微软语音开发包的丁点使用

  首先说明,微软语音包(speech sdk 5.1)是很强大的,我对里面的功能就用过丁点。在最近使用的时候发现已经有5.3了,而昨晚意外的发现lingoes以及金山等词典工具都用到了它里面的TTS部分。

 

  首先是必须得安装SPEECH SDK 5.1 以及其附加的语音包的(日语和中文,英文在SDK包里有了)。安装完后最好能初始化下,设置下配置文件。就是简单的录制你的声音。

 

  然后在自己的工程里增加对库和头文件的引用。

  /** 包含语音头文件 */
#include "sapi.h"
#include "sphelper.h"
#pragma comment(lib,"sapi.lib");

 

这是我在自己工程的stdafx.h头文件里写入的引用。仅供参考。

 

然后就只要用到两个函数了。

    /**语音开发相关方法与成员*/
    void RecoEvent();
    void InitSR(HWND);

 

 

InistSR是用来初始化语音设备的。不过记得要在项目目录下有个CmdCtrl.xml文件存储命令。

具体代码如下:

void Test::InitSR(HWND m_hWnd) { //m_bGotReco=FALSE; //m_bInSound=FALSE; HRESULT hr = S_OK; //创建识别引擎COM实例 hr = cpRecoEngine.CoCreateInstance(CLSID_SpInprocRecognizer); if( SUCCEEDED( hr ) ) { //创建识别上下文对象 hr = cpRecoEngine->CreateRecoContext( &m_cpRecoCtxt ); } else PostQuitMessage(0); if (SUCCEEDED(hr)) { //设置消息机制 hr = m_cpRecoCtxt->SetNotifyWindowMessage( m_hWnd, WM_RECOEVENT, 0, 0 ); } else PostQuitMessage(0); if (SUCCEEDED(hr)) { //我们关心的事件 const ULONGLONG ullInterest = SPFEI(SPEI_RECOGNITION); hr = m_cpRecoCtxt->SetInterest(ullInterest, ullInterest); } else PostQuitMessage(0); CComPtr<ISpAudio> cpAudio; //建立默认的音频输入对象 hr = SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOIN, &cpAudio); //设置识别引擎输入源 hr = cpRecoEngine->SetInput(cpAudio, TRUE); // b_initSR = TRUE; //创建听写模式的语法对象 hr = m_cpRecoCtxt->CreateGrammar( GID_DICTATION, &m_cpDictationGrammar ); if (SUCCEEDED(hr)) { //加载词典 hr = m_cpDictationGrammar->LoadDictation(NULL, SPLO_STATIC); } else PostQuitMessage(0); if (FAILED(hr)) { m_cpDictationGrammar.Release(); PostQuitMessage(0); } //创建命令模式的语法对象 hr = m_cpRecoCtxt->CreateGrammar( GID_CMD_GR, &m_cpCmdGrammar); if( FAILED(hr) ) { PostQuitMessage(0); } WCHAR wszXMLFile[20]=L""; //ANSI转UNINCODE MultiByteToWideChar(CP_ACP, 0, (LPCSTR)"CmdCtrl.xml" , -1, wszXMLFile, 256); //从文件中读取语法词典 hr = m_cpCmdGrammar->LoadCmdFromFile(wszXMLFile,SPLO_DYNAMIC); if (FAILED(hr)) { PostQuitMessage(0); } }

 

 

然后就是RecoEvent函数了,用来监听语音消息的。里面有对应的接受到某个命令就该执行动作的地方。

我在里面放了个“前进”的命令。。。可以参考。

void Test::RecoEvent() { USES_CONVERSION; CSpEvent event; while (event.GetFrom(m_cpRecoCtxt) == S_OK) { 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; //MessageBox(NULL,"123","waiting",MB_OK); if(Recstring=="前进") { m_MD2.GetModel().currentAnim=(m_MD2.GetModel().currentAnim+1)%(m_MD2.GetModel().numOfAnimations); m_MD2.GetModel().currentFrame=(m_MD2.GetModel()).pAnimations[m_MD2.GetModel().currentAnim].startFrame; } } break; } } }

 

 

2个函数如果都嵌入好了,那就只剩激活语音了。激活了就OK了。

    ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
    this->InitSR(this->m_Window.m_hWnd);

很简单的2句话,本来上面的初始化COM组件的我没写,这个地方让我捣鼓了2小时才意识到。基础功不扎实,罪过罪过。

 

另外在这里面会用到的数据成员是:

 

    CComPtr<ISpRecoContext>     m_cpRecoCtxt;
    CComPtr<ISpRecoGrammar>     m_cpDictationGrammar;
    CComPtr<ISpRecoGrammar>        m_cpCmdGrammar;
    CComPtr<ISpRecognizer>        cpRecoEngine;
    BOOL b_Cmd_Grammar;

 

宏变量是:

#define GID_DICTATION   0           // Dictation grammar has grammar ID 0
#define GID_CMD_GR      33333
#define WM_RECOEVENT    WM_USER+1

 

总共重新弄出语音来耗费了我一个周日。很笨吧我,呵呵。不过语音控制还是很好玩的。现在我的demo里有鼠标、键盘、摇杆以及语音控制了。可谓一个不错的IO交互了。呵呵~

 

希望对你有帮助。有问题欢迎探讨了。

 

 

 

你可能感兴趣的:(cmd,null,金山,微软,tts,引擎)