Speech Recognition in .Net using C#

Speech recognition is a much more difficult task than simply making the computer speak. So you would think that it would mean that there would be a good 100 to 200 lines of code required to get the task done. But with .Net it's more like 8.

                SpeechRecognitionEngine RecognitionEngine = new SpeechRecognitionEngine();
                RecognitionEngine.LoadGrammar(new DictationGrammar());
                RecognitionResult Result = RecognitionEngine.Recognize();
                StringBuilder Output = new StringBuilder();
                foreach (RecognizedWordUnit Word in Result.Words)
                {
                    Output.Append(Word.Text);
                }

The code above should be pretty obvious as to what is going on, with one exception. The LoadGrammar line might give you some pause. The system basically needs to know what to be looking for and has two modes. The first mode is dictation. This is what you would use for something like Word (and is what I show above). The second mode is command mode. In that case you have to build your own grammar (passing in text words, etc. for it to look for). The main reason to use this if you wanted to control an application with specific phrases. Other things to note is that the code above is synchronous. If you wanted to, you can do this async and have it notify you when it's done. We have other options as well, such as the ability to tie it to a wave file, etc. just like the text to speech bit of code.

Anyway, the SpeechRecognitionEngine is apart of the System.Speech.Recognition namespace. It's basically our gateway to the built in speech recognition software that Microsoft uses. Well, sort of anyway... Normally when Microsoft puts something in .Net, it means that it will work. Speech recognition doesn't seem to want to on Windows Server 2008... I spent the better part of a day trying to get it to work with nothing to show for it. Anyway, on Vista and Windows 7, this code will give you speech recognition. With XP, you have to download and install the Speech SDK from Microsoft. Windows Server 2003 seems to also work with that download, but Windows Server 2008 seems busted at this point (and I'm guessing there is no rush to fix that). There are claims out there that you can get it to work but none of them have worked for me thus far. Anyway, I hope this helps someone. Give it a try, leave feedback, and happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 9/10/2009 at 11:46 AM
Tags: , , ,
Categories: C#
Post Information: Permalink | Comments (15) | Post RSSRSS comment feed

Comments

Jim United States

Friday, February 12, 2010 11:49 PM

Jim

thanks for sharing, this is exactly what I'm looking for. Is this for windows form or web? I used the code for my website and my site will always be in "loading" mode and will never display the result.

here's the code

        SpeechRecognitionEngine RecognitionEngine;

        using (RecognitionEngine = new SpeechRecognitionEngine(new CultureInfo("en-US")))
        {
            RecognitionEngine.SetInputToWaveFile(Server.MapPath("speech.wav"));

            RecognitionEngine.LoadGrammar(new DictationGrammar());
            RecognitionResult Result = RecognitionEngine.Recognize();
            StringBuilder Output = new StringBuilder();
            foreach (RecognizedWordUnit Word in Result.Words)
            {
                Output.Append(Word.Text + " ");
            }

            lbl_result.Text = Output.ToString();
        }

James Craig United States

Sunday, February 14, 2010 8:47 PM

James Craig

Well speech recognition will not work on Windows Server 2008 and takes a lot of work to get it up and going on 2003. So depending on your server, it would be difficult to get working. Most likely it's not going to work on a website.

jamal India

Tuesday, April 27, 2010 9:52 AM

jamal

Hi craig,

am using the below code

using (RecognitionEngine = new SpeechRecognitionEngine(new CultureInfo("en-US")))
                {
                    RecognitionEngine.SetInputToWaveFile("D:/wav/music.wav");
                    SpVoice voice = new SpVoice();
                    voice.Rate = 10;
                    voice.Volume = 100;
                    RecognitionEngine.LoadGrammar(new DictationGrammar());
                    RecognitionResult Result = RecognitionEngine.Recognize();
                    RecognitionEngine.RecognizeAsync(RecognizeMode.Single);

                    StringBuilder Output = new StringBuilder();
                    foreach (RecognizedWordUnit Word in Result.Words)
                    {
                        Output.Append(Word.Text + " ");
                    }
                    RecognitionEngine.RecognizeAsyncStop();
                    lbl_result.Text = Output.ToString();
                                  
                    RecognitionEngine.Dispose();


But its not showing the output while running the page just on loading state only . what might be the problem. am using windows7 and visual Studio 2008 .

And wave file content not converted Exactly some words are wrong is there any way to set the voice clarity to recognize the wave file.

jamal India

Tuesday, April 27, 2010 9:52 AM

jamal

Hi craig,

am using the below code

using (RecognitionEngine = new SpeechRecognitionEngine(new CultureInfo("en-US")))
                {
                    RecognitionEngine.SetInputToWaveFile("D:/wav/music.wav");
                    SpVoice voice = new SpVoice();
                    voice.Rate = 10;
                    voice.Volume = 100;
                    RecognitionEngine.LoadGrammar(new DictationGrammar());
                    RecognitionResult Result = RecognitionEngine.Recognize();
                    RecognitionEngine.RecognizeAsync(RecognizeMode.Single);

                    StringBuilder Output = new StringBuilder();
                    foreach (RecognizedWordUnit Word in Result.Words)
                    {
                        Output.Append(Word.Text + " ");
                    }
                    RecognitionEngine.RecognizeAsyncStop();
                    lbl_result.Text = Output.ToString();
                                  
                    RecognitionEngine.Dispose();


But its not showing the output while running the page just on loading state only . what might be the problem. am using windows7 and visual Studio 2008 .

And wave file content not converted Exactly some words are wrong is there any way to set the voice clarity to recognize the wave file.

James Craig United States

Tuesday, April 27, 2010 1:58 PM

James Craig

You're using asynchronous recognition as well as synchronous. You should choose one or the other in this case. Also, if you're putting the recognition engine in a using statement, you shouldn't call dispose. As far as why it's only displaying during loading, to be honest, I don't know. It might be an issue where the recognition engine locks the wave file, but I'm not sure. As far as getting the recognition a bit better, depending it may need to be trained.

To train your system to recognize your voice (or whomever), go to the control panel, ease of access, and then speech recognition. There should be a button that says "Train your machine to understand you better" or something along those lines. But then it's training on your voice. But it will do a better job of recognizing anything that you say.

jamal India

Tuesday, April 27, 2010 11:29 PM

jamal


Hi Craig Thank you for your reply , but i used Async="true" in the page directive . i referred some sites it guides me to use Async="true" .

While i run the page and put break point on the Label which displays the recognized Text it shows some output but when i run the page it wont display anything it just keep loading .

do i need to close any function to make the page displays the output.

James Craig United States

Wednesday, April 28, 2010 9:57 AM

James Craig

Well if you want to do async recognition, you need to set up the code a bit different from what you have above. Below is a really basic form as an example:
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            using (SpeechRecognitionEngine RecognitionEngine = new SpeechRecognitionEngine())
            {
                RecognitionEngine.SetInputToWaveFile("C:\\YOURWAVFILE.wav");
                RecognitionEngine.RecognizeCompleted += new EventHandler<RecognizeCompletedEventArgs>(RecognitionEngine_RecognizeCompleted);
                RecognitionEngine.LoadGrammar(new DictationGrammar());
                RecognitionEngine.RecognizeAsync();
            }
        }

        void RecognitionEngine_RecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
        {
            lbl_result.Text = e.Result.Text;
        }
    }

But basically you need to set up the RecognizeCompleted event and call RecognizeAsync and remove the calls to Recognize. Also the only reason to call RecognizeAsyncStop is when you want the processing to stop in the middle. Otherwise it will continue until it's done with the file. Also note that e.Result might be null in the RecognizeCompleted event (in that case it failed to identify anything).

jamal India

Thursday, April 29, 2010 12:11 AM

jamal

still its not working, the page is keep loading only..
i dont have idea on the Sync and Async , i dont know how to stop the page and make it so the output.
pls, if you can give the code.

James Craig United States

Friday, April 30, 2010 8:22 AM

James Craig

At this point I can honestly say that I don't know what the issue is. I would try posting the issue on Stack Overflow: http://stackoverflow.com. I'm sorry that I'm not of more help.

Martin Lutini Kenya

Tuesday, May 18, 2010 5:46 AM

Martin Lutini

Hi Craig,
Am doing my final project in which i am implementing  a speech recognition system that can identify and individual by their ID number dictation. I am really new to C# sharp and .NET but i have tried to read and compile something but i get stuck when running it

// Code that Handles a recognised voice from the microphone

      public void RecoContext_Recognition(int StreamNumber, object StreamPosition,
SpeechRecognitionType RecognitionType, ISpeechRecoResult e)
      {
      // get phrase
            string phrase=e.PhraseInfo.GetText(0,-1,true);
            
            //make sure its in lower case (for safer use only)
            phrase=phrase.ToLower();
            
            //if recognised any ...
            if(phrase!="")
            {
              
              switch(e.PhraseInfo.Rule.Name)      //rule name not the phrase!
              {
                case "Activate":
                {
                  //load grammar
                  SAPIGrammarFromFile("XMLDeactivate.xml");
                  
                  //notify user
                  labell.Text="Activate";
                  
                  break;
                }
                //else pree the key (probably a menu...)
                default:
                {
          string str1=e.PhraseInfo.Rule.Name;
                  str1=str1.ToUpper();
              label1.Text=str1;
                    keybd_event((byte)(str1[0]),0,0,0);   //key down
                    keybd_event((byte)(str1[0]),0,2,0);   //key up
                    
                    //could be submenu (hook it)
                    hookSubmenu(e.PhraseInfo.Rule.Name[0].ToString());
                    break;
                }
              }
            }
            //if not recognised ...
            else
            {
              //notify the user that  nothing was recognised
            
            MessageBox.Show("Failed to process phrase"+phrase+"","Error");
            }
      }

Is their a problem with my code above coz i need it to atleast recognize a voice from the mic

James Craig United States

Tuesday, May 18, 2010 9:39 AM

James Craig

The code you have looks OK. I would step through it to see where the error occurs and what, if any, error codes you receive. That being said, I haven't used the old SAPI code since I switched to Windows 7 (System.Speech is a managed wrapper that's built into .Net starting with Vista).  I'm going to assume that you need it to run on XP though and that's why you're using SAPI instead.

Anyway one of the big issues that I use to run into with XP was that there wasn't a speech recognition engine built in by default. But if you have the Speech SDK (probably 5.1 since that's what everyone links to) or Office installed, you should have an engine. Past that double check your setup (it's really common to mess up your grammar, etc.).

Eng_rayan Tunisia

Wednesday, June 02, 2010 10:12 AM

Eng_rayan

I have an xp and ive download the sapi sdk 5.1

i use the code that you put and i builded sucsessfully but when i  start debugging an error occured


" No audio input is supplied to this recognizer"

James Craig United States

Thursday, June 03, 2010 7:52 AM

James Craig

Well, by default the code above would use the default audio input device. Assuming you have a mic, that would be it. You may want to double check that the recognizer is set up properly by setting it to a wav file. To do that you would add the following line prior to calling Recognize:

RecognitionEngine.SetInputToWaveFile("THE LOCATION OF YOUR FILE");

mahmoud Egypt

Saturday, June 19, 2010 7:32 AM

mahmoud

is it work under win xp ?

James Craig United States

Saturday, June 19, 2010 8:51 PM

James Craig

Assuming you have SP3 installed and a recognizer installed as well (basically have office 2003 installed or SAPI 5.1 SDK or one of the other recognizers out there), it will work on XP.

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading