关于SAPI的简介

API 概述

SAPI API在一个应用程序和语音引擎之间提供一个高级别的接口。SAPI 实现了所有必需的对各种语音引擎的实时的控制和管理等低级别的细节。

SAPI引擎的两个基本类型是文本语音转换系统(TTS)和语音识别系统。TTS系统使用合成语音合成文本字符串和文件到声音音频流。语音识别技术转换人类的声音语音流到可读的文本字符串或者文件。

文本语音转换API

应用程序能通过IspVoice的对象组建模型(COM)接口控制文本语音转换。一旦一个应用程序有一个已建立的IspVoice对象(见Text-to-Speech指南),这个应用程序就只需要调用ISpVoice::Speak 就可以从文本数据得到发音。另外,ISpVoice接口也提供一些方法来改变声音和合成属性,如语速ISpVoice::SetRate,输出音量ISpVoice::SetVolume,改变当前讲话的声音ISpVoice::SetVoice等。

特定的SAPI控制器也可以嵌入输入文本使用来实时的改变语音合成器的属性,如声音,音调,强调字,语速和音量。这些合成标记在sapi.xsd中,使用标准的XML格式,这是一个简单但很强大定制TTS语音的方法,不依赖于特定的引擎和当前使用的声音。

ISpVoice::Speak方法能够用于同步的(当完全的完成朗读后才返回)或异步的(立即返回,朗读在后台处理)操作。当同步朗读(SPF_ASYNC)时,实时的状态信息如朗读状态和当前文本位置可以通过ISpVoice::GetStatus得到。当异步朗读时,可以打断当前的朗读输出以朗读一个新文本或者把新文本自动附加在当前朗读输出的文本的末尾。

除了ISpVoice接口之外SAPI也为高级TTS应用程序提供许多有用的COM接口。

事件

SAPI用标准的回调机制(Window消息, 回调函数 or Win32 事件)来发送事件来和应用程序通信。对于TTS,事件大多用于同步地输出语音。应用程序能够与它们发生的实时行为例如单词边界,音素,口型或者应用程序定制的书签等同步。应用程序能够用ISpNotifySource, ISpNotifySink, ISpNotifyTranslator, ISpEventSink, ISpEventSource, 和 ISpNotifyCallback初始化和处理这些实时事件。

字典

应用程序通过使用ISpContainerLexicon, ISpLexicon 和IspPhoneConverter提供的方法能为语音合成引擎提供定制的单词发音。

资源

查找和选择SAPI语音数据如声音文件及发音字典可以被下列COM接口控制:ISpDataKey, ISpRegDataKey, ISpObjectTokenInit, ISpObjectTokenCategory, ISpObjectToken, IEnumSpObjectTokens, ISpObjectWithToken, ISpResourceManager 和 IspTask。

音频

最后,有一个接口能把声音输出到一些指定目标如电话和自定硬件 (ISpAudio, ISpMMSysAudio, ISpStream, ISpStreamFormat, ISpStreamFormatConverter)。

语音识别 API

就像ISpVoice是语音合成的主接口,IspRecoContext是语音识别的主接口。像ISpVoice一样,它是一个IspEventSource接口,这意味着它是语音程序接收被请求的语音识别事件通知的媒介。

一个应用程序必须从两个不同类型的语音识别引擎(ISpRecognizer)中选择一种。一种是可以与其它语音识别程序共享识别器的语音识别引擎,这在大多数识别程序中被推荐使用。为了为IspRecognizer建立一个共享的ISpRecoContext接口,一个应用程序只需要用CLSID_SpSharedRecoContext调用COM的 CoCreateInstance方法。这种方案中,SAPI将建立一个音频输入流,把它设置为SAPI默认的音频输入流。对于大型服务器程序,它可能在单独在一个系统上运行,性能是关键,一个InProc语音识别引擎更适合。

为了为InProc ISpRecognizer建立一个IspRecoContext,程序必须首先用CLSID_SpInprocRecoInstance调用CoCreateInstance来建立属于它自己的InProc IspRecognizer。然后程序必须调用ISpRecognizer::SetInput(见 also ISpObjectToken)来建立一个音频输入流。最后程序可以调用ISpRecognizer::CreateRecoContext来得到一个IspRecoContext。

下一步是建立程序感兴趣的事件通知,因为IspRecognizer也是一个IspEventSource,IspEventSource实际上是IspNotifySource,程序从它的ISpRecoContext可以调用IspNotifySource的一个方法来指出IspRecoContext的哪里的事件应该被报告。然后它应该调用ISpEventSource::SetInterest来指出哪些事件应该通报。最重要的事件是SPEI_RECOGNITION,指出和IspRecoContext相关的IspRecognizer已经识别了一些语音。其他可用到的语音识别事件的详细资料参见SPEVENTENUM。

最后,一个语音程序必须建立,加载,并且激活一个IspRecoGrammar,本质上就是指出哪些类型的发言被识别,例如口述或一个命令和控制文法。首先,程序用ISpRecoContext::CreateGrammar建立一个IspRecoGrammar,然后程序加载适合的文法,下面两个方法中调用其中一个:口述模式的调用方法ISpRecoGrammar::LoadDictation,命令和控制模式的则调用方法ISpRecoGrammar::LoadCmdxxx。最后为了激活这些文法以开始进行识别,程序为口述模式调用ISpRecoGrammar::SetDictationState或者为命令和控制模式调用调用ISpRecoGrammar::SetRuleState或者ISpRecoGrammar::SetRuleIdState。

当识别依靠通知机制返回到程序,SPEVENT结构的成员lParam将是一个IspRecoResult,程序可以确定什么被识别和使用了IspRecoContext的哪个IspRecoGrammar。

一个IspRecognizer,无论是否是共享的还是InProc的,都可以有多个IspRecoContexts和它关联,并且每个都可以通过它自己的事件通知方法通知IspRecognizer。从一个IspRecoContext可以建立多个IspRecoGrammars,以便于识别不同类型的发言。

利用微软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、释放创建的引擎、识别上下文对象、语法等。调用相应的Release函数即可。

需要源码请在本人CSDN留下email!

本文作者专著《Visual C++2010开发权威指南》即将推出,敬请关注,Visual C++2010最近技术,Windows7开发最新技术!

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

VC++基于微软语音引擎开发语音识别总结相关推荐

  1. 一款非常好玩的小程序游戏推荐给大家,基于cocos creator引擎开发的

    一款非常好玩的小程序游戏推荐给大家,基于cocos creator引擎开发的,排名包含微信好友排行榜,全球榜,快邀请好友,一起来玩吧.

  2. 流程引擎课堂(二)| 基于开源流程引擎开发的BPM有那些难点?

    编者按:开源流程引擎哪个好?如何基于开源流程引擎开发BPM,存在哪些难点?本文从国内流程引擎市场的难点出发,分析了其中的利弊. 企业的流转离不开流程,一个好的流程管理系统可以为企业增效降本,增强企业综 ...

  3. 基于开源流程引擎开发BPM或OA有哪些难点

    前言     如何基于开源流程引擎开发OA系统?开源流程引擎哪个好?把它整合到自己的产品里难不难,有没有啥风险?这是大家经常遇到的问题.笔者从2006年开始参与流程引擎开发,经历了三代流程引擎研发,支 ...

  4. 卡牌类手游源码 刀塔传奇 免费分享 基于cocos2d-x3.0引擎开发

    卡牌类手游源码 刀塔传奇 免费分享 基于cocos2d-x3.0引擎开发 https://bbs.wxrym.com/thread-90118-1-1.html (出处: 外星人源码论坛) 今天给大家 ...

  5. 室内导航应用程序,基于自研引擎开发3D地图+导航应用-采用蓝牙定位方案

    1.基于蓝牙技术的定位方案 目前室外的全球卫星导航系统(GNSS)应用已经大规模普及,通过应用程序可以为用户提供全天候的3维坐标和速度以及时间信息服务,同时中国自行研制的北斗卫星导航系统也成为了继GP ...

  6. 基于JBox2D物理引擎开发的“雷电”小游戏(五)——碰撞

    不好意思,隔了这么久才发这一篇文章,虽然部分原因是最近因为实习的事情很忙,还有一部分原因是比较懒,废话不多说,现在开始正文. 碰撞 既然学到了这里,想必大家都明白,物理引擎会帮我们做很多事情,省去从零 ...

  7. 微软TTS语音引擎编程入门

    我们都使用过一些某某词霸的英语学习工具软件,它们大多都有朗读的功能,其实这就是利用的Windows的TTS(Text To Speech)语音引擎.它包含在Windows Speech SDK开发包中 ...

  8. 【VC++技术杂谈004】使用微软TTS语音引擎实现文本朗读

    本文主要介绍如何使用微软TTS语音引擎实现文本朗读,以及生成wav格式的声音文件. 1.语音引擎及语音库的安装 TTS(Text-To-Speech)是指文本语音的简称,即通过TTS引擎把文本转化为语 ...

  9. Android App开发语音处理之系统自带的语音引擎、文字转语音、语音识别的讲解及实战(超详细 附源码)

    需要源码请点赞关注收藏后评论区留下QQ~~~ 一.系统自带的语音引擎 语音播报的本质是将书面文字转换成自然语言的音频流,这个转换操作被称作语音合成,又称TTS(从文本到语音)在转换过程中,为了避免机械 ...

最新文章

  1. nginx 只写了listen80 没有 listen443 用https访问
  2. cat、tac、more、less、head、tail、cut
  3. GCC的内存边界对齐
  4. python教程:列表(list)、元组(tuple)、字典(dict)
  5. Eclipse Memory Analysis分析Java运行内存情况
  6. DES和AES加密:指定键的大小对于此算法无效
  7. MySQL8.0.19下载安装及配置详细步骤
  8. docker+selenium grid解决node执行经常卡死
  9. 【项目管理】风险分析
  10. 服装设计与工程_百度百科
  11. 2015年全国大学生电子设计竞赛A题(双向DC-DC变换器)训练总结(硬件部分)
  12. 三菱q系列c语言模块,【重磅干货】三菱Q系列串口模块QJ71C24的Modbus通信
  13. 果园机器人作文开头_果园机器人作文
  14. php集成开发环境哪个最好,推荐几个好用的PHP集成开发环境
  15. 我所知道坦克大战(单机版)之 让子弹飞、让坦克控制子弹开炮
  16. python大写字母怎么读_python中字母大小写的转换,和一些字典的常规操作
  17. 【游戏】Win 10 运行红色警戒2
  18. cad2006激活未找到html文件,[转载]AutoCAD2006启动时提示“许可证系统出现问题”解决方法...
  19. MAYA打造地震后的古城场景-3D建模场景模型教程
  20. 基于知识图谱+机器学习,搭建风控模型的项目落地

热门文章

  1. 全面详细的github中文教程
  2. 数据库IP网络切换问题
  3. tnc_pib_tc
  4. Java开发手册(黄山版)
  5. SoundPool的使用
  6. 计算星期几(蔡勒公式)
  7. 基于element-ui的table实现树级表格操作及单元格合并
  8. 调用百度人脸识别API
  9. 运营大数据具体做什么的?有哪些价值提现?
  10. 微软流媒体框架DirectShow