我正在做使用SAPI进行语音识别的功能,在win7下,可以使用System.Speech.Recognition.SpeechRecognitionEngine这个类来做,这个类的识别事件中会提供一个e.Result.Alternates属性。但是,由于System.Speech.Recognition.SpeechRecognitionEngine不支持在XP系统上使用,所以考虑使用COM组件的方式进行开发,我读了一些文档,好像是说使用COM组件的方式只有使用“DictationGrammar”语法时才能用“Result.Alternates()”方法。我该怎么获取识别可选项呢?
下面是使用System.Speech.Recognition.SpeechRecognitionEngine时的代码:
void engine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e) { if (this.SpeechRecognized != null) { this.SpeechRecognized(this, new RecognizedResultEventArgs { Text = e.Result.Text, Alternates = new ReadOnlyCollection<string>(e.Result.Alternates.Select(p => p.Text).ToList()) }); } }
下面是我用COM实现的部分代码,当我调用“Result.Alternates()”的时候会有一个异常:
private const int grammarId = 10; private bool speechInitialized = false; private SpeechLib.SpSharedRecoContext objRecoContext; private SpeechLib.ISpeechRecoGrammar grammar; private SpeechLib.ISpeechGrammarRule ruleListItems; // 初始化识别上下文 private void InitializeSpeech(List<string> userKeyWords = null, bool isUseSystemGrammar = false) { try { // First of all, let's create the main reco context object. // In this sample, we are using shared reco context. Inproc reco // context is also available. Please see the document to decide // which is best for your application. objRecoContext = new SpeechLib.SpSharedRecoContext(); // Then, let's set up the event handler. We only care about // Hypothesis and Recognition events in this sample. objRecoContext.Hypothesis += new _ISpeechRecoContextEvents_HypothesisEventHandler( RecoContext_Hypothesis); objRecoContext.Recognition += new _ISpeechRecoContextEvents_RecognitionEventHandler( RecoContext_Recognition); objRecoContext.AudioLevel += new _ISpeechRecoContextEvents_AudioLevelEventHandler(objRecoContext_AudioLevel); objRecoContext.EventInterests = SpeechRecoEvents.SREAllEvents; // Now let's build the grammar. grammar = objRecoContext.CreateGrammar(grammarId); ruleListItems = grammar.Rules.Add("ListItemsRule", SpeechRuleAttributes.SRATopLevel | SpeechRuleAttributes.SRADynamic, 1); RebuildGrammar(userKeyWords, isUseSystemGrammar); // Now we can activate the top level rule. In this sample, only // the top level rule needs to activated. The ListItemsRule is // referenced by the top level rule. grammar.CmdSetRuleState("ListItemsRule", SpeechRuleState.SGDSActive); speechInitialized = true; } catch (Exception e) { Loger.LogErr(e); } } // 事件响应,这里会有一个异常 public void RecoContext_Recognition(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result) { ISpeechPhraseProperty oItem; oItem = Result.PhraseInfo.Properties.Item(0); if ((System.Decimal)Result.PhraseInfo.GrammarId == grammarId) { if (this.SpeechRecognized != null) { RecognizedResultEventArgs e = new RecognizedResultEventArgs(); e.Text = oItem.Name; // The following code throws an exception ISpeechPhraseAlternates alternates = Result.Alternates(10); List<string> s = new List<string>(); foreach (ISpeechPhraseAlternate item in alternates) { s.Add(item.RecoResult.PhraseInfo.Properties.Item(0).Name); } e.Alternates = new ReadOnlyCollection<string>(s); this.SpeechRecognized(this, e); } } }