Get user input from Speech?

2019-02-17 01:56发布

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.

3条回答
做个烂人
2楼-- · 2019-02-17 02:28

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 
    ...
查看更多
兄弟一词,经得起流年.
3楼-- · 2019-02-17 02:28

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.

查看更多
你好瞎i
4楼-- · 2019-02-17 02:35

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();
查看更多
登录 后发表回答