views:

1701

answers:

6

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.

+1  A: 

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
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
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
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
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
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
+1  A: 

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
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
A: 

Hi Kim can you send me your above complete code for loading grammar at [email protected]

Actually I am grabbing grammar file from external xml but getting an exception for HRESULT error : 0x80045048

Although my xml rules are according to SAPI documentation.

A: 

Hi Kim can you send me above code source because I am unable to add my words and run the code after some modification dynamically.

I want to add words dynamically at runtime to SAPI voice database and also want to add some own training files. Any assistance will be highly appreciated

+1  A: 

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

Eric Brown
Thank you. I'll have a look and see if I have access to AddTextSubset(). Maybe through reflection.
Kim Major
A: 

I know this is an old post.. but has anyone ever reached some conclusion.. or knows of something more? I am dealing with a similar problem.. want to load a generic grammar from a file. This file references external ones ( grammar files ). While the app is running, i wanna be able to add and delete rules depending on situations, thus improving accuracy ( i think)

Any help will be appreciated.

Ricardo Silva