2014-02-07 78 views
2

我似乎無法從SpeechRecognizedEventArgs中提取我想要的信息。我的語法有短語「一」和「左箭頭」。如果我同時說出兩者之間的關係,那麼我的識別者會發現他們的語法是因爲我的最大重複次數是五次,但是我無法區分結果中的相位。 SpeechRecognizedEventArgstext是「一個向左箭頭」,當我想要「一個,左箭頭」或列表中的第一個項目是「一個」,第二個是「左箭頭」。在SpeechRecognizedEventArgs中爲Microsoft語音識別找到單個匹配的短語

我發現了一個「Words」屬性,它幾乎是我想要的,但並不完全。如果風格使得它們逗號分開,或者某個事件發生在語法中的任何單個階段被找到,那麼我將它們逐一地取代它們,而不是在一個不可分割的組中。我的一些代碼:

var cultureInfo = new System.Globalization.CultureInfo("en-US"); 
    recognizer_ = new SpeechRecognitionEngine(cultureInfo); 
    var choices = LoadWordChoices(); 
    var gb = new GrammarBuilder(); 
    gb.Append(choices, 1, 5); 
    var grammar = new Grammar(gb); 
    recognizer_.LoadGrammar(grammar); 
    recognizer_.SpeechRecognized += 
     new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized); 

且事件:

void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e) 
    { 
     // e.g. "one left arrow" 
     // when I'd like either "one,left arrow" or a list 
     Console.WriteLine(e.Result.Text); 
     // ... 
    } 

編輯 - 使用語義的作品,當我說出例如一個短語嘗試「左箭頭」,但是當我說「一個左箭頭」時,它會崩潰,並出現以下錯誤:「mscorlib.dll中發生未處理的異常類型'System.Reflection.TargetInvocationException'。附加信息:異常已被調用的目標「。這裏是我的嘗試:

 var gb = new GrammarBuilder(); 
     var choices = new Choices(); 
     var words = LoadWords(); // string[] of "one", "left arrow" etc. 
     foreach (var word in words) 
     { 
      choices.Add(new SemanticResultValue(word, word)); 
     } 
     gb.Append(choices, 1, 5); 
     return gb; 

編輯2:包括最小工作程序重現錯誤:

class MySpeech 
{ 
    private SpeechRecognitionEngine recognizer_; 

    public MySpeech() 
    { 
     var cultureInfo = new System.Globalization.CultureInfo("en-US"); 
     recognizer_ = new SpeechRecognitionEngine(cultureInfo); 
     var gb = CreateGrammarBuilder(); 
     var grammar = new Grammar(gb); 
     recognizer_.LoadGrammar(grammar); 

     recognizer_.SpeechRecognized += 
      new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized); 
     recognizer_.SetInputToDefaultAudioDevice(); 
     recognizer_.RecognizeAsync(RecognizeMode.Multiple); 
    } 

    private GrammarBuilder CreateGrammarBuilder() 
    { 
     var gb = new GrammarBuilder(); 
     var choices = new Choices(); 
     var words = new string[] { "one", "left arrow" }; 
     foreach (var word in words) 
     { 
      choices.Add(new SemanticResultValue(word, word)); 
     } 
     var gbChoices = new GrammarBuilder(choices); 
     var key = new SemanticResultKey("press", gbChoices); 
     gb.Append(key, 1, 5); 
     return gb; 
    } 

    void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e) 
    { 
     Console.WriteLine("Recognized: " + e.Result.Text); 
    } 
} 

回答

4

你想在你的語法使用SemanticResultKeySemanticResultValue對象是,然後你可以使用e.Result.Semantics來提取各種結果。

SemanticValue是一個字典,值也可以是SemanticValues,產生一個值的樹。

請注意,SemanticResultValues必須與SemanticResultKeys關聯。

var gb = new GrammarBuilder(); 
    var choices = new Choices(); 
    var words = LoadWords(); // string[] of "one", "left arrow" etc. 
    foreach (var word in words) 
    { 
     choices.Add(new SemanticResultValue(word, word)); 
    } 
    var gbchoices = new GrammarBuilder(choices); 
    var key = new SemanticResultKey("words", gbchoices); 

    gb.Append(key, 1, 5); // use implicit conversion from SemanticResultKey to GrammarBuilder 
+0

我已經嘗試了一些變體,但是當我使用多個短語時它會一直崩潰。我更新了代碼。有任何想法嗎? –

+0

@PhloxMidas你能用示例和堆棧回溯來更新/開始一個新問題嗎? –

+0

@PhloxMidas沒有看到你的編輯;更新的答案 –

1

我擺脫了TargetInvokationException,只需添加一個口述語法。

_speech.LoadGrammar(new Grammar(new Choices(commands)) { Name = "commands" }); 
_speech.LoadGrammar(new DictationGrammar() { Name = "_background" }); 

在SpeechRecognized事件中,您可以檢查結果是否來自您的命令字典。

SpeechRecognized += (object sender, SpeechRecognizedEventArgs e) => 
    { 
    if (e.Result.Grammar.Name == "commands") 
    { 
     // command recognized 
    } 
    else 
    { 
     // "background noise" 
    } 
    }; 

結果是:沒有更多的崩潰和非常準確和穩定的命令(或在您的情況下,也許單個詞?)識別。