利用微软Speech SDK 5.1开发语音识别系统主要步骤

2009-09-17 10:21:09|  分类: 知识点滴|字号 订阅

微软语音识别分两种模式:文本识别模式和命令识别模式.此两种模式的主要区别,主要在于识别过程中使用的匹配字典不同.前者使用的是通用字典,特点是内容多,覆盖的词汇量大,字典由sdk提供.适用于没有预定目标的随机听写之类的应用.同时因为词汇量大直接导致识别的精度降低,识别速度较慢.后者的字典需要 开发者自己编写,就是你们所说的xml文件.xml文件作为一种数据存储的方式,有一定的格式,定义了sdk需要确定的一些标签,和用以匹配的词汇.这种方式由开发者定义词汇的数量,大大降低匹配过程中需要检索的词汇量,提高了识别速度.同时因为侯选项极少,所以一般不会识别错误.其缺点也是明显的:词汇量小,只有预先输入字典的词汇可以被识别出来,所以一般用来作为常用命令的识别,方便用户操作,代替菜单命令等.
利用微软Speech SDK 5.1在MFC中进行语音识别开发时的主要步骤,以Speech API 5.1+VC6为例:
1、初始化COM端口
一般在CWinApp的子类中,调用CoInitializeEx函数进行COM初始化,代码如下:
::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED); // 初始化COM
注意:调用这个函数时,要在工程设置(project settings)->C/C++标签,Category中选Preprocessor,在Preprocessor definitions:下的文本框中加上“,_WIN32_DCOM”。否则编译不能通过。
2、创建识别引擎
微软Speech SDK 5.1 支持两种模式的:共享(Share)和独享(InProc)。一般情况下可以使用共享型,大的服务型程序使用InProc。如下:
hr = m_cpRecognizer.CoCreateInstance(CLSID_SpSharedRecognizer);//Share
hr = m_cpRecognizer.CoCreateInstance(CLSID_SpInprocRecognizer);//InProc
如果是Share型,可直接进到步骤3;如果是InProc型,必须使用 ISpRecognizer::SetInput 设置语音输入。如下:
CComPtr<ISpObjectToken> cpAudioToken;   //定义一个token
hr = SpGetDefaultTokenFromCategoryId(SPCAT_AUDIOIN, &cpAudioToken); //建立默认的音频输入对象
if (SUCCEEDED(hr)) { hr = m_cpRecognizer->SetInput(cpAudioToken, TRUE);}
或者:
CComPtr<ISpAudio> cpAudio;   //定义一个音频对象
hr = SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOIN, &cpAudio);//建立默认的音频输入对象
hr = m_cpRecoEngine->SetInput(cpAudio, TRUE);//设置识别引擎输入源
3、创建识别上下文接口
调用 ISpRecognizer::CreateRecoContext 创建识别上下文接口(ISpRecoContext),如下:
hr = m_cpRecoEngine->CreateRecoContext( &m_cpRecoCtxt );
4、设置识别消息
调用 SetNotifyWindowMessage 告诉Windows哪个是我们的识别消息,需要进行处理。如下:
hr = m_cpRecoCtxt->SetNotifyWindowMessage(m_hWnd, WM_RECOEVENT, 0, 0);
SetNotifyWindowMessage 定义在 ISpNotifySource 中。
5、设置我们感兴趣的事件
其中最重要的事件是”SPEI_RECOGNITION“。参照 SPEVENTENUM。代码如下:
const ULONGLONG ullInterest = SPFEI(SPEI_SOUND_START) | SPFEI(SPEI_SOUND_END) | SPFEI(SPEI_RECOGNITION) ;
hr = m_cpRecoCtxt->SetInterest(ullInterest, ullInterest);
6、创建语法规则
语法规则是识别的灵魂,必须要设置。分为两种,一种是听说式(dictation),一种是命令式(command and control---C&C)。首先 利用ISpRecoContext::CreateGrammar 创建语法对象,然后加载不同的语法规则,如下:
//dictation
hr = m_cpRecoCtxt->CreateGrammar( GIDDICTATION, &m_cpDictationGrammar );
if   (SUCCEEDED(hr))
{
hr = m_cpDictationGrammar->LoadDictation(NULL, SPLO_STATIC);//加载词典
}
//C&C
hr = m_cpRecoCtxt->CreateGrammar( GIDCMDCTRL, &m_cpCmdGrammar);
然后利用ISpRecoGrammar::LoadCmdxxx 加载语法,例如从CmdCtrl.xml中加载:
WCHAR wszXMLFile[20]=L"";
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)"CmdCtrl.xml"   , -1, wszXMLFile, 256);//ANSI转UNINCODE
hr = m_cpCmdGrammar->LoadCmdFromFile(wszXMLFile,SPLO_DYNAMIC);
注意:C&C时,语法文件使用xml格式,参见Speech SDK 5.1 中的 Designing Grammar Rules。简单例子:
<GRAMMAR LANGID="804">
    <DEFINE>
       <ID NAME="CMD" VAL="10"/>
    </DEFINE>
    <RULE NAME="COMMAND" ID="CMD" TOPLEVEL="ACTIVE">
      <L>
<p>你</P>
<p>我</p>
<p>他</p>
      </L>
    </RULE>
</GRAMMAR>
LANGI*="804"代表简体中文,在<*>...</*>中增加命令。
7、在开始识别时,激活语法进行识别
hr = m_cpDictationGrammar->SetDictationState( SPRS_ACTIVE );//dictation
hr = m_cpCmdGrammar->SetRuleState( NULL,NULL,SPRS_ACTIVE );//C&C
8、获取识别消息,进行处理
截获识别消息(WM_RECOEVENT),然后处理。识别的结果放在CSpEvent的ISpRecoResult 中。如下:
USES_CONVERSION;
CSpEvent event;
switch (event.eEventId)
{
         case SPEI_RECOGNITION:
{
//识别出了语音输入
m_bGotReco = TRUE;
static const WCHAR wszUnrecognized[] = L"<Unrecognized>";
CSpDynamicString dstrText;
//取得识别结果
if (FAILED(event.RecoResult()->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE ,&dstrText, NULL)))
{
dstrText = wszUnrecognized;
}
BSTR SRout;
dstrText.CopyToBSTR(&SRout);
CString Recstring;
Recstring.Empty();
Recstring = SRout;
//进一步处理
......
}
break;
}
9、释放创建的引

利用微软Speech SDK 5.1开发语音识别系统主要步骤的更多相关文章

  1. Microsoft Speech SDK开发包 使用

    下载开发包.我们首先从微软的官网上面下载开发包,下载地址如下: http://www.microsoft.com/en-us/download/details.aspx?id=10121我们主要下载三 ...

  2. 手把手教你利用微软的Bot Framework,LUIS,QnA Maker做一个简单的对话机器人

    最近由于要参加微软亚洲研究院的夏令营,需要利用微软的服务搭建一个对话Bot,以便对俱乐部的情况进行介绍,所以现学了几天,搭建了一个简单的对话Bot,期间参考了大量的资料,尤其是下面的这篇博客: htt ...

  3. Kinect 开发 —— 语音识别(上)

    Kinect的麦克风阵列在Kinect设备的下方.这一阵列由4个独立的水平分布在Kinect下方的麦克风组成.虽然每一个麦克风都捕获相同的音频信号,但是组成阵列可以探测到声音的来源方向.使得能够用来识 ...

  4. 利用Google Speech API实现Speech To Text

    很久很久以前, 网上流传着一个免费的,识别率暴高的,稳定的 Speech To Text API, 那就是Google Speech API. 但是最近再使用的时候,总是返回500 Error. 后来 ...

  5. 【转】Android平台下利用zxing实现二维码开发

    http://www.cnblogs.com/dolphin0520/p/3355728.html 现在走在大街小巷都能看到二维码,而且最近由于项目需要,所以研究了下二维码开发的东西,开源的二维码扫描 ...

  6. Android平台下利用zxing实现二维码开发

    Android平台下利用zxing实现二维码开发 现在走在大街小巷都能看到二维码,而且最近由于项目需要,所以研究了下二维码开发的东西,开源的二维码扫描库主要有zxing和zbar,zbar在iPos平 ...

  7. .net core 2.2 部署CentOS7(4)CentOS7下载并安装.NET SDK(软件开发工具包)

    目录: .net core 2.2 部署CentOS7(1)安装虚拟机 .net core 2.2 部署CentOS7(2)给虚拟机安装CentOS7 .net core 2.2 部署CentOS7( ...

  8. OpenCV - Android Studio 2.2 中利用CAMKE进行OpenCV的NDK开发

    我在http://www.cnblogs.com/fx-blog/p/8206737.html一文中提到了如何在Android Studio中Java层导入OpenCV(包含opencv_contri ...

  9. 《ArcGIS Runtime SDK for Android开发笔记》——(9)、空间数据的容器-地图MapView

    1.前言 在上一篇内容里介绍了 关于ArcGIS Android开发的未来(“Quartz”版Beta)相关内容,期间也提到了关于API接口的重构,开发思路的调整,根据2015UC资料也可以知道新版预 ...

随机推荐

  1. 继承在WCF中的问题和解决办法

    1. 问题 假设有代码如下: [ServiceContract] public interface IA { [OperationContract] string M1(); } [ServiceCo ...

  2. Java [Leetcode 119]Pascal's Triangle II

    题目描述: Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3,Return ...

  3. 【C#学习笔记】自我复制

    using System; using System.IO; using System.Diagnostics; namespace ConsoleApplication { class Progra ...

  4. AWK print学习

    Awk是一种处理结构数据并输出格式化结果的编程语言, Awk 是其作者 "Aho,Weinberger,Kernighan" 的简称. Awk通常被用来进行格式扫描和处理.通过扫描 ...

  5. ActionBarSherlock的学习笔记(四) ------------ ActionBarSherlock中的搜索及SearchView的使用

    在使用ActionBarSherlock定义app的头部操作时,会经常看见搜索的动作,本文主要介绍一下搜索是如何实现的. 1. SearchView 是搜索的核心组件,具体介绍请参考Android官方 ...

  6. JS调试必备的5个debug技巧

    我一直使用printf调试程序,一般来说都是比较顺利,但有时候,你会发现需要更好的方法.下面几个JavaScript技巧相信你一定会觉得十分有用   1. debugger; 我以前也说过,你可以在J ...

  7. 【转】让apache支持中文路径或者中文文件

    本帖最后由 狂人阿川 于 2013-4-12 19:13 编辑 今天在给一美国VPS客户调试他的程序的时候.发现他的网站有中文名称.貌似apache无法认识中文路径,火狐下面能下载他的文件,IE下面不 ...

  8. IT版孔乙己(转)

    [不要做学究]回忆孔先生IT版 我关于本文评价:看到这篇文章很多人会生出这样的疑问“这明明是在诋毁钻研技术的人嘛?是不是在宣扬技术无用论?”. 初看这篇文章的时候我也是这样的想法,但是逐步才明白这篇文 ...

  9. Gridview LookupEdit gridLookUpEdit z

    LookupEdit一般用法: 绑定数据源:                                 lookUpEdit.Properties.ValueMember = 实际要用的字段;  ...

  10. Long Dominoes(ZOJ 2563状压dp)

    题意:n*m方格用1*3的方格填充(不能重叠)求有多少种填充方法 分析:先想状态,但想来想去就是觉得不能覆盖所有情况,隔了一天,看看题解,原来要用三进制 0 表示横着放或竖放的最后一行,1表示竖放的中 ...