Question

I have just started trying out the Windows Speech to Text capabilities in C# .Net. I currently have the basics working (IE - Say something, and it will provide output based on what you say). However, I am struggling to figure out how to actually recieve user input as a variable.

What I mean by this, is that for example. If the user says:

"Call me John"

Then I want to be able to take the word John as a variable and then store that as say, the persons username.

My current SpeechRecognized event is as follows:

void zeusSpeechRecognised(object sender, SpeechRecognizedEventArgs e)
    {
        writeConsolas(e.Result.Text, username);
        switch (e.Result.Grammar.RuleName)
        {
            case "settingsRules":
                switch (e.Result.Text)
                {
                    case "test":
                        writeConsolas("What do you want me to test?", me);
                        break;
                    case "change username":
                        writeConsolas("What do you want to be called?", me);
                        break;
                    case "exit":
                        writeConsolas("Do you wish me to exit?", me);
                        break;
                }
                break;
        }
    }

NB:writeConsolas is just a glorified append line to a RichTextBox.

I would like to add another case which does the following:

case "call me"
    username = e.Result.GetWordFollowingCallMe() //Obv not a method, but thats the general idea.
    break;

Obviously, there is no such method, but that is the general idea that I wish to implement. Is there a way to search for specific phrases (IE: Call me) and take the following word?

EDIT: I should note, that the e.Result.Text only returns words that it can match to Text in the dictionary.

Was it helpful?

Solution

It does not look like in your situation e.Result.Text represents something that you can enumerate: you are checking the words that start the text, not the text in its entirety. In cases like this, you should not use a switch, and go for a chain of if-then-elses instead:

var text = e.Result.Text;
if (text.StartsWith("test")) {
    writeConsolas("What do you want me to test?", me);
} else if (text.StartsWith("change username")) {
    writeConsolas("What do you want to be called?", me);
} else if (text.StartsWith("exit")) {
    writeConsolas("Do you wish me to exit?", me);
} else if (text.StartsWith("call me")) {
    // Here you have the whole text. Chop off the "call me" part,
    // using Substring(), and do whatever you need to do with the rest of it
} else 
    ...

OTHER TIPS

Well it can't be used in a switch on e.Result.Text, as it will test on the entire value : Call Me John.

You should have a condition in a default case, or outside of your switch

But I would really refactor all that, trying to avoid switch or massive if..else if...else

const string Callme = "call me";
var text = e.Result.Text;

switch (text)
   {
   case "test":
       writeConsolas("What do you want me to test?", me);
   break;
   case "change username":
       writeConsolas("What do you want to be called?", me);
   break;
   case "exit":
       writeConsolas("Do you wish me to exit?", me);
   break;

   }
   if (text.StartsWith(CallMe)
       userName = text.Replace(CallMe, string.Empty).Trim();

I would look at updating your grammar to use SemanticValues so that you can extract the results directly rather than having to parse through recognition results. There's a quick example here that demonstrates SemanticValues, SemanticResultKeys, and SemanticResultValues.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top