Question

Winforms application written in VB.NET. I am using SpeechRecognitionEngine from System.Speech.Recognition.

I am looking for the best way to construct a Grammar. My method that generates the grammar is passed a number, indicating the count of valid objects and hence a valid range of numbers.

Possible commands:

  • Bottom
  • Top
  • Prior
  • Page [Up|Down]
  • [Open|Save|Print] # (where number is in my valid range).

What I've done is created four different Grammar objects and loaded them into my SpeechRecognitionEngine. Because of how the code that consumes the RecognitionResult currently works, two of my Grammars are named "Pages" and two of them "Numbers". I can change these, they just evolved this way. I was actually uncertain if loading two grammars with the same name into an engine would work and apparently it does.

What I have works. However I was hoping to see if there was a better way. I tried to see if I could combine Choices within Choices to make a sort of compound Choice, but I couldn't seem to make heads-nor-tails of it in my head so didn't really get anywhere with it.

So, how can I improve this? I know I can combine grammar 3 and grammar 4 together, but didn't want to change anything yet since I was trying to preserve the grammar name when parsing the RecognitionResult. I would really like to combine all my options into one single grammar with the same name and alter my other code if possible.

Private Sub LoadGrammars(count As Integer)

    '// Open, Print and Save each must be followed by a number in the range of 1 to count
    Dim gb As New GrammarBuilder()
    gb.Append(New Choices("Open", "Print", "Save"))

    Dim numChoices As New Choices '// create Choices with each number in the range
    Dim y() As String = Enumerable.Range(1, count).Select(Function(t) t.ToString()).ToArray()
    numChoices.Add(y)

    gb.Append(numChoices)
    Dim g As New Grammar(gb)
    g.Name = "Numbers"

    '// Page must be followed by Up or Down
    Dim gb2 As New GrammarBuilder()
    gb2.Append("Page")
    gb2.Append(New Choices("Up", "Down"))
    Dim g2 As New Grammar(gb2)
    g2.Name = "Pages"

    Dim gb3 As New GrammarBuilder()
    gb3.Append("Prior")
    Dim g3 As New Grammar(gb3)
    g3.Name = "Numbers"

    Dim gb4 As New GrammarBuilder()
    gb4.Append(New Choices("Bottom", "Top"))
    Dim g4 As New Grammar(gb4)
    g4.Name = "Pages"

    _engine.LoadGrammar(g)
    _engine.LoadGrammar(g2)
    _engine.LoadGrammar(g3)
    _engine.LoadGrammar(g4)

End Sub
Was it helpful?

Solution

You can nest Choices objects by going through an intermediate GrammarBuilder object.

The Choices object has a constructor that takes an array of GrammarBuilders, and the GramarBuilder object has a constructor that takes a Choices object. You'll probably want to use SemanticResultKeys and SemanticValues so that you can figure out what was actually said, though (which I won't illustrate).

I'm not a VB.net expert, so the syntax might be off here; but it would look something like this:

Dim numChoices As New Choices '// create Choices with each number in the range
Dim y() As String = Enumerable.Range(1, count).Select(Function(t) t.ToString()).ToArray()
numChoices.Add(y)

gb.Append(numChoices)
Dim g As New Grammar(gb)
g.Name = "Numbers"

'// Page must be followed by Up or Down
Dim gb2 As New GrammarBuilder()
gb2.Append("Page")
gb2.Append(New Choices("Up", "Down"))

Dim gb3 As New GrammarBuilder()
gb3.Append("Prior")

Dim gb4 As New GrammarBuilder()
gb4.Append(New Choices("Bottom", "Top"))

Dim gbArray() as GrammarBuilder(4) = {gb1, gb2, gb3, gb4};
Dim g as new Grammar(new GrammarBuilder(new Choices(gbArray)));
g.Name = "All"

_engine.LoadGrammar(g);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top