Reputation: 12739
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:
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 Grammar
s 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
Upvotes: 0
Views: 849
Reputation: 13932
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);
Upvotes: 1