Click here to Skip to main content
15,886,199 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
Hey!
So i'm having problem with my speech recognition program. It gives me this error: "At least one grammar must be loaded before doing a recognition." Anyways here the code.

Thanks!

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Speech.Synthesis;
using System.Speech.Recognition;
using System.Diagnostics;

namespace Speech_Recognition_test_3
{
    public partial class Form1 : Form
    {
        private static SpeechSynthesizer synth = new SpeechSynthesizer();
        private static SpeechRecognitionEngine recEngine = new SpeechRecognitionEngine();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //ko klikneš začne poslušati
            Here it shows me the error
            recEngine.RecognizeAsync(RecognizeMode.Multiple);
            //enable-a drugi button
            button2.Enabled = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Choices toDo = new Choices();
            toDo.Add(new string[] { "open itunes", "open chrome", "open file explorer" });

            //naredi grammar ki ga program uporablja za preverjanje izgoverjene besede
            GrammarBuilder grammarBuilder = new GrammarBuilder();
            grammarBuilder.Append(toDo);
            Grammar grammar = new Grammar(grammarBuilder);

            //Začne uporabljati grammar
            Here it loads the grammar supposedly
            recEngine.LoadGrammarAsync(grammar);
            //Tu se določi default naprava za snemanje
            recEngine.SetInputToDefaultAudioDevice();
            recEngine.SpeechRecognized += recEngine_SpeechRecognised;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            recEngine.RecognizeAsyncStop();
        }

        public static void recEngine_SpeechRecognised(object sender, SpeechRecognizedEventArgs e)
        {
            switch (e.Result.Text)
            {
                
                case "open itunes":
                    MessageBox.Show("Opening iTunes");
                    break;
                case "open chrome":
                    MessageBox.Show("Opening Google Chrome");
                    break;
                case "open file explorer":
                    MessageBox.Show("I cant do that");
                    break;
            }
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
                MessageBox.Show("Hello World!");
        }
    }
}


What I have tried:

I don't know what to try. ///////////////////////////
Posted
Updated 22-Feb-16 18:53pm
Comments
Wombaticus 22-Feb-16 13:41pm    
This may help
http://stackoverflow.com/questions/27065410/c-sharp-voice-recognition-issue
Sergey Alexandrovich Kryukov 23-Feb-16 0:55am    
That's not exactly it. This is a known problem and, besides, I can see a bug.
Please see Solution 1.
—SA
Patrice T 22-Feb-16 15:11pm    
Contact the author of the speech recognition package.
Sergey Alexandrovich Kryukov 23-Feb-16 0:54am    
Not the author, but the provider of the code is... Microsoft. This is a known problem and, besides, I can see a bug.
Please see Solution 1.
—SA
Matt T Heffron 22-Feb-16 16:18pm    
Try capturing the LoadGrammarCompleted event to see if it is being loaded successfully before you click button1.
Perhaps just try the speech recognition sample on MSDN and then modify it a bit at a time to your application. Learn as you go.

1 solution

Something is wrong here. The code, as you show it, could not even compile. You cannot append string[] to a grammar builder, you have to append an instance of Choice. This is a correct code fragment:
C#
string[] phrases = new string[] {
   // ...
}
Choices choiceSet = new Choices(phrases);
GrammarBuilder grammarBuilder = new GrammarBuilder();
grammarBuilder.Append(choiceSet);
or, even simpler
C#
string[] phrases = new string[] {
   // ...
}
Choices choiceSet = new Choices(phrases);
GrammarBuilder grammarBuilder = new GrammarBuilder(choiceSet);


In addition to that (sigh)… there is a very, very subliminal problem related, surprisingly, to apartment model you are using with the recognizer. There are two different engines. Depending on the platform and probably .NET version, the engine System.Speech.Recognition.SpeechRecognitionEngine requires [MTAThread], another one System.Speech.Recognition.SpeechRecognizer, requries [STAThread].

Wrong choice of the apartment state, by some reason, cause the message you reported. A while ago, I quickly figured it out, because rudimentary Microsoft samples worked and could be used for comparison. However, this problem has gone when I switched from XP to Windows 7, where both engines works with either of the two apartment states. Not all application types allow to chose any apartment state for a main thread, but you can always do all your work in some other thread you can create with required apartment state.

So, first, follow my code fragment above and, if it does not yet work, try to change apartment state. Before you ask some follow up questions, please try it out and then tell us you OS version, .NET version and type of the engine.

By the way, this answer is based on testing I've just done. All works. If you want, I'll give you a complete sample, but after your try to fix your code, please.

[EDIT]

As I promised, this is a fully functional sample:
C#
namespace SpeechConsole {
    using System;
    using System.Speech.Recognition;

    class Program {

        const string QuiteCommand = "Quit"; //, "Go out of here";
        const string RepeatInstructionCommand = "Repeat instructions";
        const string ShutUpCommand = "Shut up";

        void Run() {
            try {
                string[] phrases = new string[] {
                    "10", "Previous", "Remember", "Forget", "Save",
                    RepeatInstructionCommand, ShutUpCommand, QuiteCommand, };
                Choices choiceSet = new Choices(phrases);
                GrammarBuilder grammarBuilder = new GrammarBuilder(choiceSet);
                grammarBuilder.Append(choiceSet);
                SpeechRecognitionEngine engine = new SpeechRecognitionEngine();
                // another option which works:
                //SpeechRecognizer engine = new SpeechRecognizer();
                engine.LoadGrammar(new Grammar(grammarBuilder));
                engine.RecognizeCompleted += (source, eventInfo) => {
                    // ...
                }; //engine.RecognizeCompleted
                engine.SpeechRecognitionRejected += (source, eventInfo) => {
                    Console.WriteLine("What the hell you're trying to say?!");
                }; //engine.SpeechDetected
                engine.SpeechRecognized += (source, eventInfo) => {
                    Console.WriteLine(@"Detected: ""{0}""", eventInfo.Result.Text);
                    if (eventInfo.Result.Text == QuiteCommand)
                        System.Diagnostics.Process.GetCurrentProcess().Kill();
                    if (eventInfo.Result.Text == RepeatInstructionCommand)
                        Instructions(phrases);
                }; //engine.SpeechRecognized
                engine.SetInputToDefaultAudioDevice();
                Instructions(phrases);
                engine.RecognizeAsync(RecognizeMode.Multiple);
                System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
            } catch (Exception e) {
                Console.WriteLine("{0}: {1}", e.GetType().Name, e.Message);
            } //exception
        } //Run

        void Instructions(string[] phrases) {
            Console.WriteLine("Say one of the following:");
            foreach (string prompt in phrases)
                Console.WriteLine("           " + prompt);
            Console.WriteLine();
        } //Instructions

        // [System.MTAThread]
        // IMPORTANT! speech recognition will not work on STAThread on some systems
        // In this case, use default (no attribute at all)
        // or [System.MTAThread] but not [System.STAThread]
        static void Main() {
            Console.Title = "Ctrl+C or say \"Quit\" to exit";            
            new Program().Run();
        } //Main

    } //class Program

} //namespace SpeechConsole


—SA
 
Share this answer
 
v9
Comments
Matt T Heffron 23-Feb-16 12:24pm    
+5
Sergey Alexandrovich Kryukov 23-Feb-16 21:46pm    
Thank you, Matt.
—SA
Ziggs6 24-Feb-16 8:55am    
So i tried it and it still something doesn't work i don't know why. So if you could give me that full sample, i'd be very thankful.
Ziggs6 24-Feb-16 9:33am    
Okay no problem, thanks.
Sergey Alexandrovich Kryukov 24-Feb-16 9:42am    
Done.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900