Hasan A Yousef
Hasan A Yousef

Reputation: 24988

async wait in Speech recognizer

I'm trying duplicating this example with the following changes:

  1. Using Console app instead of Windows: This looks to be fine as the computer is speaking to me

  2. Using Sync functionality: and here looks I've a mistake.

UPDATE Once the program is executed, it speaks to me, and waited for key to be pressed, after that it waited a little to 'listening' but the sre_SpeechRecognized is not executed.

Below is my code, thanks:

using System;
using System.Threading.Tasks;
using System.Speech.Synthesis;
using System.Speech.Recognition;

class Startup {
        // Create a simple handler for the SpeechRecognized event
    static void sre_SpeechRecognized (object sender, SpeechRecognizedEventArgs e)
    {
        string speech = e.Result.Text;

                //handle custom commands
        switch (speech)
        {
            case "red":
                Console.WriteLine("Hello");
                break;
            case "green":
                System.Diagnostics.Process.Start("Notepad");
                break;
            case "blue":
                Console.WriteLine("You said blue");
                break;
            case "Close":
               Console.WriteLine("Speech recognized: {0}", e.Result.Text);
                break;
        }
        Console.WriteLine("Speech recognized: {0}", e.Result.Text);
    }

public async Task<object> Invoke(dynamic i) {
// Initialize a new instance of the SpeechSynthesizer.
        SpeechSynthesizer synth = new SpeechSynthesizer();

        // Configure the audio output. 
        synth.SetOutputToDefaultAudioDevice();

        // Speak a string.
        synth.Speak("This example demonstrates a basic use of Speech Synthesizer");

        Console.WriteLine();
        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();

        // Create a new SpeechRecognitionEngine instance.
        SpeechRecognizer recognizer = new SpeechRecognizer();

        // Create a simple grammar that recognizes "red", "green", or "blue".
        Choices colors = new Choices();
        colors.Add(new string[] { "red", "green", "blue" });

        // Create a GrammarBuilder object and append the Choices object.
        GrammarBuilder gb = new GrammarBuilder();
        gb.Append(colors);

        // Create the Grammar instance and load it into the speech recognition engine.
        Grammar g = new Grammar(gb);
        recognizer.LoadGrammar(g);

        // Register a handler for the SpeechRecognized event.
        recognizer.SpeechRecognized += 
          new EventHandler<SpeechRecognizedEventArgs> (Startup.sre_SpeechRecognized);
       Console.WriteLine("Exiting now..");
   return null;
}
}

Upvotes: 0

Views: 2016

Answers (2)

Mrinal Kamboj
Mrinal Kamboj

Reputation: 11478

Modify the Invoke method as follows (this is typical case of Async caller (Node Js here) waiting for a Synchronous event to complete)

Important Details (please note basis of this modification is that otherwise Speech engine is working as expected)

  1. Made Invoke method Sync, instead of Async, as there was no Async call in the original code
  2. Replaced the return value as Task to fetch the event return value
  3. Made the event Inline for ease of using objects
  4. Added Recognize sync method in the end
  5. Will return when the Task completes post event firing and will contain result inside Task<string>, which can fetch result using TaskObject.Result property

      public async Task<object> Invoke(dynamic i) {    // async here is required to be used by Edge.JS that is a node.js module enable communicating with C# files
      var tcs = new TaskCompletionSource<object>();
      // Initialize a new instance of the SpeechSynthesizer.
        SpeechSynthesizer synth = new SpeechSynthesizer();
    
        // Configure the audio output. 
        synth.SetOutputToDefaultAudioDevice();
    
        // Speak a string.
        synth.Speak("This example demonstrates a basic use of Speech Synthesizer");
    
        Console.WriteLine();
        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    
        // Create a new SpeechRecognitionEngine instance.
    
        SpeechRecognitionEngine recognizer = new SpeechRecognitionEngine();
    
        recognizer.SetInputToDefaultAudioDevice();
    
        // Create a simple grammar that recognizes "red", "green", or "blue".
        Choices colors = new Choices();
        colors.Add(new string[] { "red", "green", "blue" });
    
        // Create a GrammarBuilder object and append the Choices object.
        GrammarBuilder gb = new GrammarBuilder();
        gb.Append(colors);
    
        // Create the Grammar instance and load it into the speech recognition engine.
        Grammar g = new Grammar(gb);
        recognizer.LoadGrammar(g);
    
        // Register a handler for the SpeechRecognized event.
        recognizer.SpeechRecognized += (sender,e) => {
    
           string speech = e.Result.Text;
    
            //handle custom commands
            switch (speech)
            {
                case "red":
                 tcs.SetResult("Hello Red");
                break;
                case "green":
                 tcs.SetResult("Hello Green");
                break;
                case "blue":
                 tcs.SetResult("Hello Blue");
                 break;
                case "Close":
                 tcs.SetResult("Hello Close");
                break;
               default:
                 tcs.SetResult("Hello Not Sure");
              break;
    }
    
     };
    
       // For Edge JS we cannot await an Async Call (else it leads to error)
       recognizer.Recognize();              
       return tcs.Task.Result;
    
       //// For pure C#
       // await recognizer.RecognizeAsync();              
       // return tcs.Task;
    }
    

Async specific changes

  1. public async Task<object> Invoke(dynamic i) (Make method async and return type Task, requirements of an async method)
  2. Call await recognizer.RecognizeAsync(); (Call await on Async call)
  3. return tcs.Task (return type needs to be Task)

Upvotes: 1

Chris Tophski
Chris Tophski

Reputation: 960

You don't start the recognition. Please see the link you posted. There is a line sre.Recognize(); (which is missing in your code) after registering the event in the example. There is also a method RecognizeAsync() mentioned, which might be what you want.

Upvotes: 1

Related Questions