Sapi 新增語法的文章(轉載)

於為源發表於2013-11-22

最近在做SAPI方面的工作,比較詳細的中文資料不多,遇到各種問題,本來想著做完了專案總結一下,今天看到這篇文章,對於SAPI載入識別語法方面的描述十分詳細,先轉過來做個備份,謝謝原文博主:djyangmaowei,原文地址:http://blog.csdn.net/djyangmaowei/article/details/5384942

 

應用程式可以利用SpSharedRecoContext介面建立不同的與語音識別引擎的連線。每一個連線都可以使用各自的事件並且使用不同的語音識別語法(grammars)。每一個基於SAPI語音識別的應用程式必須具有至少一個SpSharedRecoContext介面。

 

第一種方法: 自己定義Grammar

 

using System;

using System.Collections;

using System.ComponentModel;

using System.Drawing;

using System.Data;

using System.Windows.Forms;

using System.Diagnostics;

using SpeechLib;

 

namespace WindowsFormsApplication3

{

    public partial class Form1 : Form

    {

        private SpeechLib.ISpeechGrammarRule menuRule = null;

        private SpeechLib.SpSharedRecoContext objRecoContext;

        private ISpeechRecoGrammar grammar;

        public Form1()

        {

            InitializeComponent();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            // 得到一個RecoContext例項. 

            objRecoContext = new SpeechLib.SpSharedRecoContext();

            // 指派一個事件給Hypothesis Event(中間層暫定的識別,即,初級的,臨時的識別).

            objRecoContext.Hypothesis += new _ISpeechRecoContextEvents_HypothesisEventHandler(Hypo_Event);

            // 指派一個事件給語音識別.

            objRecoContext.Recognition += new _ISpeechRecoContextEvents_RecognitionEventHandler(Reco_Event);

            //建立grammer例項.

            grammar = objRecoContext.CreateGrammar(0);

 

            label1.Text = "Speak Out one of the following./r/n1. 人民 2. 馬克思 3. 孫中山 4. 恩格斯/r/n5. 楊茂巍 6. 王芳 7. 世界 8. 成都";

            //啟用選單命令.   

            menuRule = grammar.Rules.Add("MenuCommands", SpeechRuleAttributes.SRATopLevel | SpeechRuleAttributes.SRADynamic, 1);

            object PropValue = "";

            menuRule.InitialState.AddWordTransition(null, "人民", " ", SpeechGrammarWordType.SGLexical, "人民", 1, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "馬克思", " ", SpeechGrammarWordType.SGLexical, "馬克思", 2, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "孫中山", " ", SpeechGrammarWordType.SGLexical, "孫中山", 3, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "恩格斯", " ", SpeechGrammarWordType.SGLexical, "恩格斯", 4, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "楊茂巍", " ", SpeechGrammarWordType.SGLexical, "楊茂巍", 5, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "王芳 ", " ", SpeechGrammarWordType.SGLexical, "王芳 ", 6, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "世界", " ", SpeechGrammarWordType.SGLexical, "世界", 7, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "成都", " ", SpeechGrammarWordType.SGLexical, "成都", 8, ref PropValue, 1.0F);

            grammar.Rules.Commit();

            grammar.CmdSetRuleState("MenuCommands", SpeechRuleState.SGDSActive);

        }

        private void Reco_Event(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result)

        {

            textBox1.Text = Result.PhraseInfo.GetText(0, -1, true);

        }

        private void Hypo_Event(int StreamNumber, object StreamPosition, ISpeechRecoResult Result)

        {

            textBox2.Text = Result.PhraseInfo.GetText(0, -1, true);

        }

    }

}

第二種方法:
不定義Grammar 利用SAPI自動識別輸入語音 準確率不高
public class SpRecognition
     {
          private static SpRecognition _Instance = null ;
          private SpeechLib.ISpeechRecoGrammar isrg ;
          private SpeechLib.SpSharedRecoContextClass ssrContex =null;
          private System.Windows.Forms.Control cDisplay  ;
          private SpRecognition()
         {
              ssrContex = new SpSharedRecoContextClass() ;
              isrg = ssrContex.CreateGrammar(1) ;          
              SpeechLib._ISpeechRecoContextEvents_RecognitionEventHandler recHandle =
                   new _ISpeechRecoContextEvents_RecognitionEventHandler(ContexRecognition) ;
              ssrContex.Recognition += recHandle ;
         }
         public void BeginRec(Control tbResult)
         {            
              isrg.DictationSetState(SpeechRuleState.SGDSActive) ;
              cDisplay = tbResult ;
         }
         public static SpRecognition instance()
         {
              if (_Instance == null)
                   _Instance = new SpRecognition() ;
              return _Instance ;
         }
         public void CloseRec()
         {
              isrg.DictationSetState(SpeechRuleState.SGDSInactive) ;
         }
          private void ContexRecognition(int iIndex,object obj,SpeechLib.SpeechRecognitionType type,SpeechLib.ISpeechRecoResult result)
         {
              cDisplay.Text += result.PhraseInfo.GetText(0,-1,true) ;
         }
 
     }
第三種方法:
外界讀入xml grammar (c://1.xml)
 private SpeechLib.SpSharedRecoContext ssrc;
        private ISpeechRecoGrammar srg;
        private void button1_Click(object sender, EventArgs e)
        {
            ssrc = new SpSharedRecoContext();
            srg = ssrc.CreateGrammar(1);
            srg.CmdLoadFromFile("c://1.xml", SpeechLoadOption.SLODynamic);//讀入規則
           // ssrc.EventInterests = SpeechRecoEvents.SREAllEvents;//在"語音事件"中有說明
            ssrc.Recognition += new _ISpeechRecoContextEvents_RecognitionEventHandler(ssrc_Recognition);//新增識別事件     
            ssrc.Hypothesis += new _ISpeechRecoContextEvents_HypothesisEventHandler(Hypo_Event);
            srg.CmdSetRuleState(srg.Rules.Item(0).Name, SpeechRuleState.SGDSActive);//啟用規則       
        }
        private void button2_Click(object sender, EventArgs e)
        {
          
        }
        private void button3_Click(object sender, EventArgs e)
        {
           
        }
        void ssrc_Recognition(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result)
        {
            textBox1.Text = Result.PhraseInfo.GetText(0, -1, true);
        }
        private void Hypo_Event(int StreamNumber, object StreamPosition, ISpeechRecoResult Result)
        {
            textBox2.Text = Result.PhraseInfo.GetText(0, -1, true);
        }
 
1.xml
<?xml version="1.0" encoding="gb2312" ?> 
<GRAMMAR LANGID="804"> 
<RULE NAME="命令" TOPLEVEL="ACTIVE"> 
<L> 
<P>口令結束</P> 
<P>放大</P> 
<P>Home</P> 
<p>End</p> 
<P>上一頁</P> 
<P>下一頁</P> 
<P>向上</P> 
<P>向下</P> 
<P>左視窗</P> 
<P>右視窗</P> 
<P>關閉</P> 
<P>撤消</P> 
<P>重新整理</P> 
</L> 
</RULE> 
</GRAMMAR>
如要原始碼 請留下郵箱 

相關文章