4

Given the following code,

Choices choices = new Choices();
choices.Add(new GrammarBuilder(new SemanticResultValue("product", "<product/>")));

GrammarBuilder builder = new GrammarBuilder();
builder.Append(new SemanticResultKey("options", choices.ToGrammarBuilder()));

Grammar grammar = new Grammar(builder) { Name = Constants.GrammarNameLanguage};
grammar.Priority = priority;

_recognition.LoadGrammar(grammar);

How can I add additional words to the loaded grammar? I know this can be achieved both in native code and using the SpeechLib interop, but I prefer to use the managed library.

Update: What I want to achieve, is not having to load an entire grammar repeatedly because of individual changes. For small grammars I got good results by calling

_recognition.RequestRecognizerUpdate()

and then doing the unload of the old grammar and loading of a rebuilt grammar in the event:

void Recognition_RecognizerUpdateReached(object sender, RecognizerUpdateReachedEventArgs e)

For large grammars this becomes too expensive.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Kim Major
  • 3,681
  • 1
  • 22
  • 20

3 Answers3

1

In native SAPI, I'd use ISpGrammarBuilder2::AddTextSubset().

Eric Brown
  • 13,774
  • 7
  • 30
  • 71
1

It sounds like you need to use some indirection, via the a grammar rule reference. This can be done with the GrammarBuilder.AppendRuleReference method. It might be easier to test out your grammars first with some SRGS grammar files.

The principle is that you load a main large grammar which has some references in it, to smaller user specific word lists grammars, which you would dynamically load.

See http://www.w3.org/TR/speech-grammar/#S2.2 for the srgs format, and http://msdn.microsoft.com/en-us/library/system.speech.recognition.grammarbuilder.appendrulereference.aspx for the programmatic version.

Conor OG
  • 533
  • 2
  • 8
  • I'm not sure I follow. Let's say I add a reference to an external grammar as described in AppendRuleReference. After this referenced grammar has been loaded, the content of it changes. How do I now update the speech engine to use the amended grammar? (without reloading it of course) – Kim Major Mar 16 '09 at 17:31
  • You _do_ need to reload the _referenced_ grammar, but not the main grammar. This should be a much smaller load/unload operation. If the differences per user are large, then the other option would be to have them all loaded, and then enable/disable them on the fly. – Conor OG Mar 16 '09 at 18:28
  • I'll try to give an example. Open word and start to type. Each phrase you add/delete/change should be added/deleted/changed(=delete then add) to the grammar. I need to support large files. (where I define large as making the the reload noticeable) – Kim Major Mar 16 '09 at 21:09
  • Conor, maybe I can try something like this. Create a main grammar with references to n empty grammars. (where n is some sufficiently large number) Let's say that 5000 phrases makes the reload of a referenced grammar noticeable. I could then move to the next reference for each 5000th phrase. – Kim Major Mar 16 '09 at 21:13
  • If that's an option maybe you don't even need the reference. You could just use the first grammar till it gets too big, then just load a second grammar, and use it till it reaches the limit, etc – Conor OG Mar 17 '09 at 09:53
1

An alternative, if you have very large grammars, would be to use the dictation grammar option. There is a standard dictation grammar, but you could also specify your own. See http://msdn.microsoft.com/en-us/library/system.speech.recognition.dictationgrammar.aspx, and it's constructor.

You wouldn't update this. It contains all possible words.

Conor OG
  • 533
  • 2
  • 8
  • The dictation grammar won't work since I need more context. The sample I gave in a previous comment about typing phrases in word is oversimplified. The grammar is pretty complex. Anyhow, thanks for you input. – Kim Major Mar 17 '09 at 07:18