none
Speech Recognition in WorkerThread RRS feed

  • Question

  • Hello guys, i am using Microsoft Speech Object Library for speech to text conversion in a .wav file.
    In my program, if this recogniton takes place in main thread it successes, but if i call the recogniton methods and eventhandlers in a different thread (worker thread) it fails. Here more details:

    this works :
    void Button_Click(object o, eventargs e)
    {
     .. here speech recognition from file code, registerin handlers ...
    }
    
    void myRecoContext_Recogniton(int a, object b,SpeechRecognitionType t,ISpeechRecoResult r)
    {
    ... action when something recognized here ...
    }

    this does nothing :
    void Button_Click(object o, eventargs e)
    {
    Thread t = ...(recognize);
    t.start();
    }

    void recognize()
    {
    .. here speech recognition from file code, registering handlers...
    }

    void myRecoContext_Recogniton(int a, object b,SpeechRecognitionType t,ISpeechRecoResult r)
    {
    ... action when something recognized here ...
    }


    it thought, after end of recognize method above, thread ends and no recognition events fired, and i put Thread.Sleep(10000) not to dispose the thread but again it useless.

    How can i transfer eventhandlers that are created in a worker thread to main thread, or what else may be a solution?
    I hope somebody could help me.
    Thursday, November 19, 2009 12:02 AM

Answers

  • Hi,

    You are using old COM interface.  Since .NET 3.0 there is a wrapper that might solve your problem.  Add System.Speech to your project.

    Here is a sample.

    SpeechRecognitionEngine sre = new SpeechRecognitionEngine();
    
    private void Form1_Load(object sender, EventArgs e)
    {
                CreateCommands();
                sre.SpeechDetected += new EventHandler<SpeechDetectedEventArgs>(sre_SpeechDetected);
                sre.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(sre_SpeechRecognized);
                sre.RecognizeCompleted += new EventHandler<RecognizeCompletedEventArgs>(sre_RecognizeCompleted);
                sre.SpeechRecognitionRejected += new EventHandler<SpeechRecognitionRejectedEventArgs>(sre_SpeechRecognitionRejected);
                Thread t = new Thread(delegate() { sre.SetInputToDefaultAudioDevice(); sre.RecognizeAsync(RecognizeMode.Single); });
                t.Start();
    }
     private void CreateCommands()
    {
                string[] commands= new string[] { "Run Notepad", "Run Paint" };
                Choices insChoices = new Choices(commands);
                GrammarBuilder insGrammarBuilder = new GrammarBuilder(insChoices);
                Grammar insGrammar = new Grammar(insGrammarBuilder);
                sre.LoadGrammar(insGrammar);
    }
    void sre_SpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
    {
               
    }
    
    void sre_RecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
    {
                sre.RecognizeAsync();
               
    }
    
    void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
    {
                if (e.Result.Text == "Run Notepad")
                {
                    Process.Start("notepad.exe");
                }
                else if (e.Result.Text == "Run Paint")
                {
                    Process.Start("mspaint.exe");            
                }
             
    }
    
    void sre_SpeechDetected(object sender, SpeechDetectedEventArgs e)
    {
    
    }
    
    
    • Marked as answer by TarumaR Sunday, November 22, 2009 4:22 AM
    Thursday, November 19, 2009 1:41 AM
  • Yes you can use

    sre.SetInputToWaveFile()

    • Marked as answer by TarumaR Sunday, November 22, 2009 4:22 AM
    Thursday, November 19, 2009 6:56 PM

All replies

  • Hi,

    You are using old COM interface.  Since .NET 3.0 there is a wrapper that might solve your problem.  Add System.Speech to your project.

    Here is a sample.

    SpeechRecognitionEngine sre = new SpeechRecognitionEngine();
    
    private void Form1_Load(object sender, EventArgs e)
    {
                CreateCommands();
                sre.SpeechDetected += new EventHandler<SpeechDetectedEventArgs>(sre_SpeechDetected);
                sre.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(sre_SpeechRecognized);
                sre.RecognizeCompleted += new EventHandler<RecognizeCompletedEventArgs>(sre_RecognizeCompleted);
                sre.SpeechRecognitionRejected += new EventHandler<SpeechRecognitionRejectedEventArgs>(sre_SpeechRecognitionRejected);
                Thread t = new Thread(delegate() { sre.SetInputToDefaultAudioDevice(); sre.RecognizeAsync(RecognizeMode.Single); });
                t.Start();
    }
     private void CreateCommands()
    {
                string[] commands= new string[] { "Run Notepad", "Run Paint" };
                Choices insChoices = new Choices(commands);
                GrammarBuilder insGrammarBuilder = new GrammarBuilder(insChoices);
                Grammar insGrammar = new Grammar(insGrammarBuilder);
                sre.LoadGrammar(insGrammar);
    }
    void sre_SpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
    {
               
    }
    
    void sre_RecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
    {
                sre.RecognizeAsync();
               
    }
    
    void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
    {
                if (e.Result.Text == "Run Notepad")
                {
                    Process.Start("notepad.exe");
                }
                else if (e.Result.Text == "Run Paint")
                {
                    Process.Start("mspaint.exe");            
                }
             
    }
    
    void sre_SpeechDetected(object sender, SpeechDetectedEventArgs e)
    {
    
    }
    
    
    • Marked as answer by TarumaR Sunday, November 22, 2009 4:22 AM
    Thursday, November 19, 2009 1:41 AM
  • I was wandering which one is better , using recoginiton engine or recocontext, but you said i was using old one so
    i understand recognition engine is better.
    but one thing to address here, i am reading from file (.wav) to recognition.
    is it enough to change sre.setinputfromfile , to run the example code you just gave?

    Thank you very much indeed.
    Thursday, November 19, 2009 3:43 PM
  • Yes you can use

    sre.SetInputToWaveFile()

    • Marked as answer by TarumaR Sunday, November 22, 2009 4:22 AM
    Thursday, November 19, 2009 6:56 PM
  • That was very useful indeed, but something little problematic here, i run the code for sre.SetInputToWaveFile(path)
    and got an exception (TargetInvocationException ) at the Application.Run(new Form1()); line after a success recognition operation.
    Soon realized that
    sre.RecognizeAsync();
    
    line in sre_RecognizeCompleted method unnecessary for file input version, now this works perfect after deleting this line, but I have not figure the real reason out for the exception that i got before deletion RecognizeAsync() method.
    Am I right about the redundancy of this non-parameterized Async method?
    Sunday, November 22, 2009 4:19 AM
  • Hi,

    Yes it is not necessary in your example since its for performing a single recognition operation
    Sunday, November 22, 2009 5:42 AM
  • I am unable to run Tamer Oz code.

    I am in need of converting wav file to text using audio.wav file not from Microphone. I am using Microsoft SAPI but couldn't came across to a good solution. Although I have achieved Speech to text through microphone successfully. Now I want to convert wav file as send wave file as input.
     I tried above code and also a code at

     
    But couldnot  come to a good solution. So need assistance on it.
    • Proposed as answer by jobormo Tuesday, March 1, 2011 5:29 PM
    • Unproposed as answer by jobormo Tuesday, March 1, 2011 5:29 PM
    Friday, November 27, 2009 4:51 PM
  • how can I do, to count the number of times one word appear on my input file? I mean I have compiled the code given and only send one event the first time it recognize the word and not continue recognizing the word in the rest of the file.
    Many thanks for all your job!!
    Tuesday, March 1, 2011 4:53 PM
  • I got the answer! we have to change
    sre.RecognizeAsync(RecognizeMode.Single) ->sre.RecognizeAsync(RecognizeMode.Multiple)
    thx to all!
    Tuesday, March 1, 2011 5:31 PM