Search code examples
c#.netspeech-recognitionsapimicrosoft-speech-api

Crash trying to create some simple System.Speech.Recognition Grammar


Hi I'm trying to parse times said by speech:

        var ret = new GrammarBuilder();

        var hours = new Choices();
        for (int c = 1; c < 24; c++)
            hours.Add(new SemanticResultValue(c.ToString(), c));

        var minutes = new Choices();
        for (int c = 1; c < 60; c = c + 1)
            minutes.Add(new SemanticResultValue(c.ToString(), c));

        var topLevelChoices = new Choices();

        //eight fourty five = 8:45
        //four twenty = 4:20
        var methodOne = new GrammarBuilder();
        methodOne.Append(new SemanticResultKey("hour", hours));
        methodOne.Append(new SemanticResultKey("minute", minutes));
        topLevelChoices.Add(methodOne);

        //quarter to five = 4:45
        //half past ten = 10:30
        var methodTwo = new GrammarBuilder();
        methodTwo.Append(new SemanticResultKey("minute", new Choices(
            new SemanticResultValue("twenty past", 20),
            new SemanticResultValue("twenty to", -20),
            new SemanticResultValue("quarter past", 15),
            new SemanticResultValue("quarter to", -15),
            new SemanticResultValue("half past", 30)
            )));
        methodTwo.Append(new SemanticResultKey("hour", hours));
        topLevelChoices.Add(methodTwo);

        //ten o'clock
        //one o'clock
        var methodThree = new GrammarBuilder();
        methodThree.Append(new SemanticResultKey("hour", hours));
        methodThree.Append("o'clock");
        topLevelChoices.Add(methodThree);

        ret.Append(topLevelChoices);

        var g = new Grammar(ret); //crash occurs here

But I'm getting an exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll (Additional information: Index was out of range. Must be non-negative and less than the size of the collection.). See the upper-stack:

mscorlib.dll!System.ThrowHelper.ThrowArgumentOutOfRangeException() + 0x4e bytes 
mscorlib.dll!System.Collections.Generic.List<System.__Canon>.this[int].set(int index, System.__Canon value) + 0x3b bytes    
System.Speech.dll!System.Speech.Internal.GrammarBuilding.BuilderElements.Optimize(System.Collections.ObjectModel.Collection<System.Speech.Internal.GrammarBuilding.RuleElement> newRules) + 0x38e bytes 
System.Speech.dll!System.Speech.Recognition.GrammarBuilder.InternalGrammarBuilder.CreateElement(System.Speech.Internal.SrgsParser.IElementFactory elementFactory, System.Speech.Internal.SrgsParser.IElement parent, System.Speech.Internal.SrgsParser.IRule rule, System.Speech.Internal.GrammarBuilding.IdentifierCollection ruleIds) + 0x83 bytes    
System.Speech.dll!System.Speech.Recognition.GrammarBuilder.CreateGrammar(System.Speech.Internal.SrgsParser.IElementFactory elementFactory) + 0x6e bytes 
System.Speech.dll!System.Speech.Recognition.GrammarBuilder.Compile(System.IO.Stream stream) + 0x7e bytes    
System.Speech.dll!System.Speech.Recognition.Grammar.LoadCfg(bool isImportedGrammar, bool stgInit) + 0x174 bytes 
System.Speech.dll!System.Speech.Recognition.Grammar.LoadAndCompileCfgData(bool isImportedGrammar, bool stgInit) + 0x32 bytes    
> SapiGrammarCrash.exe!SapiGrammarCrash.Form1.Form1_Load(object sender, System.EventArgs e) Line 71 + 0x29 bytes    C#

I have tried .NET 3.0 and 4.5 - same result. Also tried 2 machines - both x64.

Any ideas?


Solution

  • I'm pretty sure you're rebinding the SemanticResultValues. The docs specifically say

    After a SemanticResultValue has been used to set the Value, whether it is tagged with the default root key or by any particular SemanticResultKey, that value must not be modified or an exception will occur during recognition operations.

    The workaround is to create a separate set of SemanticResultValues for your methodThree.