C#中调用SAPI实现语音识别的2种方法

通过微软的SAPI,不仅仅可以实现语音合成TTS,同样可以实现语音识别SR。下面我们就介绍并贴出相关代码。主要有两种方式:

1、使用COM组件技术,不管是C++,C#,Delphi都能玩的转,开发出来的东西在XP和WIN7都能跑。(注意要引入系统组件SpeechLib,XP要安装识别引擎)
2、使用WIN7的windows api,其实最终还是调用了SAPI,所以开发出来的东西就只能在WIN7上面跑。

其实不管是哪一种,都是调用SAPI,可能后一种代码比较简单。

使用第一种方式,需要注意在COM选项卡里面的Microsoft Speech  object  library引用

public class SpRecognition
  {
    private static SpRecognition _Instance = null;
    private SpeechLib.ISpeechRecoGrammar isrg;
    private SpeechLib.SpSharedRecoContextClass ssrContex = null;

    public delegate void StringEvent(string str);
    public StringEvent SetMessage;

    private SpRecognition()
    {
      ssrContex = new SpSharedRecoContextClass();
      isrg = ssrContex.CreateGrammar(1);
      SpeechLib._ISpeechRecoContextEvents_RecognitionEventHandler recHandle =
         new _ISpeechRecoContextEvents_RecognitionEventHandler(ContexRecognition);
      ssrContex.Recognition += recHandle;
    }
    public void BeginRec()
    {
      isrg.DictationSetState(SpeechRuleState.SGDSActive);
    }
    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)
    {
      if (SetMessage != null)
      {
        SetMessage(result.PhraseInfo.GetText(0, -1, true));
      }
    }
  }

第二种同样需要引入,不过引入的是Win7中的.NET3.5类库

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Speech;
using System.Speech.Recognition;
using System.Globalization;
using System.Windows.Forms;

namespace StudyBeta
{
  public class SRecognition
  {
    public SpeechRecognitionEngine recognizer = null;//语音识别引擎
    public DictationGrammar dictationGrammar = null; //自然语法
    public System.Windows.Forms.Control cDisplay; //显示控件

    public SRecognition(string[] fg) //创建关键词语列表
    {
      CultureInfo myCIintl = new CultureInfo("en-US");
      foreach (RecognizerInfo config in SpeechRecognitionEngine. InstalledRecognizers())//获取所有语音引擎
      {
    if (config.Culture.Equals(myCIintl) && config.Id == "MS-1033-80-DESK" )
        {
          recognizer = new SpeechRecognitionEngine(config);
          break;
        }//选择美国英语的识别引擎
      }
      if (recognizer != null)
      {
        InitializeSpeechRecognitionEngine(fg);//初始化语音识别引擎
        dictationGrammar = new DictationGrammar();
      }
      else
      {
        MessageBox.Show("创建语音识别失败");
      }
    }
    private void InitializeSpeechRecognitionEngine(string[] fg)
    {
        recognizer.SetInputToDefaultAudioDevice();//选择默认的音频输入设备
        Grammar customGrammar = CreateCustomGrammar(fg);
      //根据关键字数组建立语法
        recognizer.UnloadAllGrammars();
        recognizer.LoadGrammar(customGrammar);
      //加载语法
     recognizer.SpeechRecognized += new EventHandler <SpeechRecognizedEventArgs>(recognizer_SpeechRecognized);
     recognizer.SpeechHypothesized += new EventHandler <SpeechHypothesizedEventArgs>(recognizer_SpeechHypothesized);
    }
    public void BeginRec(Control tbResult)//关联窗口控件
    {
      TurnSpeechRecognitionOn();
      TurnDictationOn();
      cDisplay = tbResult;
    }
    public void over()//停止语音识别引擎
    {
      TurnSpeechRecognitionOff();
    }
    public virtual Grammar CreateCustomGrammar(string[] fg) //创造自定义语法
    {
      GrammarBuilder grammarBuilder = new GrammarBuilder();
      grammarBuilder.Append(new Choices(fg));
      return new Grammar(grammarBuilder);
    }
    private void TurnSpeechRecognitionOn()//启动语音识别函数
    {
      if (recognizer != null)
      {
        recognizer.RecognizeAsync(RecognizeMode.Multiple); //识别模式为连续识别
      }
      else
      {
        MessageBox.Show("创建语音识别失败");
      }
    }
    private void TurnSpeechRecognitionOff()//关闭语音识别函数
    {
      if (recognizer != null)
      {
        recognizer.RecognizeAsyncStop();
        TurnDictationOff();
      }
      else
      {
        MessageBox.Show("创建语音识别失败");
      }
    }
private void recognizer_SpeechRecognized(object sender, SpeechRecognized EventArgs e)
    {
  //识别出结果完成的动作,通常把识别结果传给某一个控件
      string text = e.Result.Text;
      cDisplay.Text = text;
    }
    private void TurnDictationOn()
    {
      if (recognizer != null)
      {
        recognizer.LoadGrammar(dictationGrammar);
  //加载自然语法
      }
      else
      {
        MessageBox.Show("创建语音识别失败");
      }
    }
    private void TurnDictationOff()
    {
      if (dictationGrammar != null)
      {
        recognizer.UnloadGrammar(dictationGrammar);
  //卸载自然语法
      }
      else
      {
        MessageBox.Show("创建语音识别失败");
      }
    }
  }
}

*********转载:https://m.jb51.net/article/67278.htm

原文地址:https://www.cnblogs.com/linybo/p/10126742.html

时间: 2024-08-29 04:14:38

C#中调用SAPI实现语音识别的2种方法的相关文章

boost在lambda表达式中调用占位符参数的成员函数的方法

boost中提供了lambda表达式的用法,但是lambda表达式的功能还不是很强大,在其中只能对lambda的占位符参数_1等使用最基本的操作符,如+-*/,可是很多时候如果传入的占位符参数是一个对象指针的话,我们可能想要调用这个类的成员函数. 我在开发中遇到了这个问题,需要在stl的算法中传入一个函数来调用对象的比较函数,因为感觉这样太麻烦,还需要重新定义一个函数,所以想起了lambda表达式,c++11的lambda表达式我倒是没试过,可是受项目开发环境所限,只能选择boost.但是我用的

Oracle数据库中调用Java类开发存储过程、函数的方法

Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日  浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL,除此之外,还可以用时下最流行的编程语言Java来做开发.随着对oracle的了解越来越多,越来越禁不住oracle的诱惑,oracle技术真的是一门很有趣的学问.之前,我在博客中总结了挺多有关SQL.PL/SQL的,但是对于oracle数据库中Java类的调用却没有总结,也是因为之前不太会,这会儿总

关于网页中不刷新页面改变验证码的两种方法

今天做一个注册的页面,需要输入验证码.验证码的生成是动态的,不过要刷新页面,才能改变验证码,因为刷新后浏览器会向服务器提交新的请求,服务器就动态生成新的验证码响应给浏览器.为了能够在不刷新页面的情况下改变验证码,需要JavaScript的支持. 第一种方法是在请求地址后面带参数,这是一个小窍门.因为浏览器访问服务器的时候地址后面可以带上参数一起传给服务器,而加载内容是只看地址不看后面的参数:另外在<img src="地址"/>中,只要浏览器发现地址改变了就会自动重新加载该地

文字转语音文件的两种方法

文件转语音文件的两种方法.小伙伴们在日常的工作.学习或是生活当中,是否遇到过以下这种情况.在工作中每天要阅读大量文件资料,在学习中每天要阅读各种课文,在生活中也会观看各种小说.但是长时间的用眼阅读,就会使大家的眼睛感到疲劳,十分的酸痛,可是又需要将剩下的内容阅读完.在这种时候就变得十分无奈,大家就会像如何能将文字转换为语音就好了.那么今天小编就将教给大家如何将文字转换为语音文件. 1.在开始转换前,需要小伙伴们先打开电脑里的浏览器,并输入搜索文字转语音在线转换,然后点击进入搜索到得页面当中. 2

Struts2中Action取得表单数据的几种方法

Struts2中Action取得表单数据的几种方法 Struts2中Action获得表单数据的几种方法struts2 Action获取表单传值 1.通过属性驱动式JSP: <form action="sys/login.action" method="post"> <input type="text" name="username"> <input type="submit"

【转】oracle 中随机取一条记录的两种方法

oracle 中随机取一条记录的两种方法 V_COUNT INT:=0; V_NUM INT :=0; 1:TBL_MYTABLE 表中要有一个值连续且唯一的列FID BEGIN SELECT COUNT(*) INTO V_COUNT FROM  TBL_MYTABLE; SELECT TRUNC(DBMS_RADOM.VALUE(1,V_COUNT+1)) INTO V_NUM FROM DUAL; SELECT * FROM TBL_MYTABLE T WHERE T.FID=V_NUM;

[转]在Arcmap中加载互联网地图资源的4种方法

转自http://blog.3snews.net/space.php?uid=6955280&do=blog&id=67981 前一段时间想在Arcmap中打开互联网地图中的地图数据,如影像数据.基础地图数据等,经过简单研究目前总结了四种方法,整理下与大家分享,有些内容可能理解有误,希望大家多多指教.4种方法如下: a)        如果地图支持OGC(开放地理空间信息联盟)协议的话,可以通过WMS,WMTS服务资源在Arcmap中打开,如天地图等. b)        通过相关插件打开

Java中线程等待(同步)的五种方法

在面试时,经常会有面试官问道,一个主线程有多个子线程,如何能使子线程的业务执行完成之后,再执行主线程业务逻辑.对于这个问题,本人能够想到的有五种方法,详细请移步源码 1.使用线程类自带的join方法,将子线程加入到主线程,在子线程执行完之后,在执行主线程逻辑. 例如 public static void joinDemo() throws InterruptedException { System.out.println("=========Test with join=====");

在Arcmap中加载互联网地图资源的4种方法

前一段时间想在Arcmap中打开互联网地图中的地图数据,如影像数据.基础地图数据等,经过简单研究目前总结了四种方法,整理下与大家分享,有些内容可能理解有误,希望大家多多指教.4种方法如下: a)        如果地图支持OGC(开放地理空间信息联盟)协议的话,可以通过WMS,WMTS服务资源在Arcmap中打开,如天地图等. b)        通过相关插件打开.如使用ArcBruTile插件等可以在arcmap中打开如Google map,openstreet,必应地图,百度地图等. c)