Pregunta

Scenario :

I have 2 commands.

1) Search Google for "any word here"

2) Open application "any word here"

Problem :

Since the word after "Search Google for" can be anything, how am I suppose to know what am I going to write for my IF statements?

With pre-defined sentences, I can do it easily like

void Engine_SpeechRecognized (object sender, SpeechRecognizedEventsArgs e)
{
    if (e.Result.Text == "Search Google Stackoverflow")
    {
       Search("Stackoverflow");
    }
}

But since now it's not pre-defined, what am I suppose to write for my IF statement condition? It's not like I can do this,

if (e.Result.Text == "Search Google" + e.Result.Text)
{
    Search(e.Result.Text);
}

So, how am I going to do it? This is easy if I only have 1 command and need only to execute 1 action, then I could just set the default action as Search(), but now the case's different.

Here is my code ( For only 1 command & action , I NEED 2 and above) * Using System.Speech

public MainWindow() 
{ 
    InitializeComponent(); 
    builder.Append("search google for"); builder.AppendDictation();

    Grammar grammar = new Grammar(builder);
    grammar.Name = ("Google Searching");

    engine.LoadGrammarAsync(grammar);
    engine.SetInputToDefaultAudioDevice();
    engine.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(Engine_SpeechRecognized);
    engine.RecognizeAsync(RecognizeMode.Multiple);
}

string result;
void Engine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    txtSpeech.Text = e.Result.Text;
    ExtractKeywords(e.Result.Text);

    OpenApp("https://www.google.com/#q=" + result);
}
¿Fue útil?

Solución

For this sort of thing, you can pull the target phrase from the RecognizedPhrase.Words property. Since the first 3 words of the result.text are going to be "Search Google for", result.words[3]..results.words[result.words.count-1]will have the phrase to search for.

Concatenate them together and off you go.

To support multiple actions, use the Grammar.Name property to tell which command you want to run.

void Engine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    txtSpeech.Text = e.Result.Text;
    ExtractKeywords(e.Result.Text);

    if (e.Result.Grammar.Name.Equals("Google Search"))
    {
         OpenApp("www.google.com", result);
    }
    else if (e.Result.Grammar.Name.Equals("StackOverflow Search"))
    {
         OpenApp("www.stackoverflow.com", result);
    }
    // etc...
}

Otros consejos

You could use a dictionary with a key that indicates your command and an anonymous method that holds the to be executed command. For performance you better refactor the Dictionary to be static and only instantiated once but this gives you the general idea.

void Engine_SpeechRecognized (object sender, SpeechRecognizedEventsArgs e)
{
    var commands = new Dictionary<string, Action<string>>();
    commands.Add(
         "search google", 
         (arg) => { Search(arg);  }) ;
    commands.Add(
         "open application", 
         (arg) => { OpenApp( "https://www.google.com/#q=" + arg);  }) ;

    foreach(var command in commands.Keys)
    {
       if (e.Result.Text.StartsWith(command))
       {
          Action(command, e.Result.Text, commands[command]);
       }
    }
}

/* helper for getting one point for an arguments extractor */
static void Action(string cmd,string all, Action<string> act)
{
    string args = all.Replace(cmd,"");
    act(args);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top