`

VC++如何编写一个语音识别的类for Micosoft speech Api5.1

 
阅读更多
1)在构造语音类之前,必须先设置好工程环境:
  a、从微软官方网站下载windows speech sdk并安装,然后在Visual Studio 6.0中进行相关设置,在Project Setings选项的C++选项卡的“分类:预处理器”添加“,__WIN32_DCOM”(为预先初始化COM组件成功);
  b、将预处理头文件选项选中“自动使用预补偿页眉”;
  c、在常规选项卡中选择“实用MFC静态连接库”;

  
  2)封装语音类
  由于采用面向对象的编程理念,借助UML(Unified Modeling Language统一建模语言)构造CSPEECH语音类如下
  
  CSPEECH类
  
  + void InitSR(); //初始化语音
  +void RecoEvent();//识别命令函数
  
  +BOOL b_initSR;
  +BOOL b_Cmd_Grammar;
  
  //3个语音接口
  +CComPtr<isprecocontext> m_cpRecocontxt; <br>  +CComPtr<isprecogrammar> m_cpRecoGrammar; <br>  +CComPtr<isprecognizer> m_cpRecoEngine; <br>   <br>  然后开始添加语音类,需要注意的是在定义语音类的头文件中,包含〈sphelper.h〉并且自定义语音识别消息和类型 <br>  #define GID_CMD_GR 333333 <br>  #define WM_RECOEVENT WM_USER+102 <br>  剩下来就是对cpp文件的函数initSR()和RecoEvent()补充函数体 <br>   <br>  3)具体见下面代码: <br>  (1)void CSpeech::initSR() <br>  { <br>  HRESULT hr=S_OK; <br>  hr=m_cpRecoEngine.CoCreateInstance(CLSID_SpInprocRecognizer);//创建识别引擎COM实例 <br>  if(SUCCEEDED(hr)) <br>  { <br>  hr =m_cpRecoEngine-&gt;CreateRecoContext(&amp;m_cpRecoCtxt );//创建识别上下文 <br>  } <br>  else <br>  MessageBox(hWnd,"error1","error",S_OK); <br>  if(SUCCEEDED(hr)) <br>  { <br>  hr = m_cpRecoCtxt-&gt;SetNotifyWindowMessage(hWnd, WM_RECOEVENT, 0, 0 ); <br>  }//消息机制设置,使计算机时刻监听语音消息 <br>  else <br>  MessageBox(hWnd,"error2","error",S_OK); <br>  if (SUCCEEDED(hr)) <br>  { <br>  ULONGLONG ullMyEvents = SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_HYPOTHESIS); <br>  hr = m_cpRecoCtxt-&gt;SetInterest(ullMyEvents, ullMyEvents); <br>  } <br>  else <br>  MessageBox(hWnd,"error3","error",S_OK); <br>  //设置默认的音频 <br>  CComPtr<ispaudio> m_cpAudio; <br>  hr=SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOIN,&amp;m_cpAudio);//建立默认的音频输入对象 <br>  hr=m_cpRecoEngine-&gt;SetInput(m_cpAudio,TRUE);//设置识别引擎输入源 <br>  hr=m_cpRecoCtxt-&gt;CreateGrammar(GID_CMD_GR,&amp;m_cpCmdGrammar);//创建命令语法 <br>  b_Cmd_Grammar=TRUE; <br>  if(FAILED(hr)) <br>  { <br>  MessageBox(hWnd,"error 4","error",S_OK); <br>  } <br>  hr=m_cpCmdGrammar-&gt;LoadCmdFromResource(NULL,MAKEINTRESOURCEW(IDR_CMDCTRL),L"SRGRAMMAR",MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL), SPLO_DYNAMIC);//加载命令语法文件 <br>  if(FAILED(hr)) <br>  { <br>  MessageBox(hWnd,"error5","error",S_OK); <br>  } <br>  b_initSR=TRUE; <br>  } <br>   <br>  (2)BOOL CSpeech::RecoEvent() <br>  { <br>  USES_CONVERSION; <br>  CSpEvent event; <br>  while(event.GetFrom(m_cpRecoCtxt)==S_OK) <br>  { <br>  switch(event.eEventId) <br>  { <br>  case SPEI_RECOGNITION: <br>  { <br>  static const WCHAR wszUnrecognized[]=L"<unrecognized>"; <br>  CSpDynamicString dstrText; <br>  if(FAILED(event.RecoResult()-&gt;GetText(SP_GETWHOLEPHRASE,SP_GETWHOLEPHRASE,TRUE,&amp;dstrText,NULL))) <br>  { <br>  dstrText=wszUnrecognized; <br>  } <br>  dstrText.CopyToBSTR(&amp;SRout); <br>  Recstring.Empty(); <br>  Recstring=SRout; <br>  if(b_Cmd_Grammar) <br>  { <br>  if(Recstring=="左") <br>  { <br>  ISpVoice *pVoice=NULL; <br>  if(FAILED(CoInitialize(NULL))) <br>  { <br>  MessageBox(hWnd,"Error to initialize COM","error",S_OK); <br>  return FALSE; <br>  } <br>  HRESULT hr=CoCreateInstance(CLSID_SpVoice,NULL,CLSCTX_ALL,IID_ISpVoice,(void**)&amp;pVoice); <br>  if(SUCCEEDED(hr)) <br>  { <br>  hr=pVoice-&gt;Speak(L"左转",0,NULL); <br>  pVoice-&gt;Release(); <br>  pVoice=NULL; <br>  } <br>  CoUninitialize(); <br>  m_OpenGL-&gt;m_baiscobj-&gt;LEFT=1; <br>  return TRUE ; <br>  } <br>   <br>  if(Recstring=="向下走") <br>  { <br>  ISpVoice *pVoice=NULL; <br>  if(FAILED(CoInitialize(NULL))) <br>  { <br>  MessageBox(hWnd,"Error to initialize COM","error",S_OK); <br>  return FALSE; <br>  } <br>  HRESULT hr=CoCreateInstance(CLSID_SpVoice,NULL,CLSCTX_ALL,IID_ISpVoice,(void**)&amp;pVoice); <br>  if(SUCCEEDED(hr)) <br>  { <br>  hr=pVoice-&gt;Speak(L"开始后退",0,NULL); <br>  pVoice-&gt;Release(); <br>  pVoice=NULL; <br>  } <br>  CoUninitialize(); <br>  m_OpenGL-&gt;m_baiscobj-&gt;BACK=1; <br>  return TRUE ; <br>  } <br>  if(Recstring=="最小化") <br>  { <br>  ISpVoice *pVoice=NULL; <br>  if(FAILED(CoInitialize(NULL))) <br>  { <br>  MessageBox(hWnd,"Error to initialize COM","error",S_OK); <br>  return FALSE; <br>  } <br>  HRESULT hr=CoCreateInstance(CLSID_SpVoice,NULL,CLSCTX_ALL,IID_ISpVoice,(void**)&amp;pVoice); <br>  if(SUCCEEDED(hr)) <br>  { <br>  hr=pVoice-&gt;Speak(L"最小化",0,NULL); <br>  pVoice-&gt;Release(); <br>  pVoice=NULL; <br>  } <br>  CoUninitialize(); <br>  SendMessage(hWnd,WM_SYSCOMMAND, SC_MINIMIZE, MAKELPARAM(0, 0)); <br>   <br>  return TRUE; <br>  } <br>  if(Recstring=="右") <br>  { <br>  ISpVoice *pVoice=NULL; <br>  if(FAILED(CoInitialize(NULL))) <br>  { <br>  MessageBox(hWnd,"Error to initialize COM","error",S_OK); <br>  return FALSE; <br>  } <br>  HRESULT hr=CoCreateInstance(CLSID_SpVoice,NULL,CLSCTX_ALL,IID_ISpVoice,(void**)&amp;pVoice); <br>  if(SUCCEEDED(hr)) <br>  { <br>  hr=pVoice-&gt;Speak(L"开始右转",0,NULL); <br>  pVoice-&gt;Release(); <br>  pVoice=NULL; <br>  } <br>  CoUninitialize(); <br>  m_OpenGL-&gt;m_baiscobj-&gt;RIGHT=1; <br>  return TRUE ; <br>  } <br>  if(Recstring=="停下来") <br>  { <br>  ISpVoice *pVoice=NULL; <br>  if(FAILED(CoInitialize(NULL))) <br>  { <br>  MessageBox(hWnd,"Error to initialize COM","error",S_OK); <br>  return FALSE; <br>  } <br>  HRESULT hr=CoCreateInstance(CLSID_SpVoice,NULL,CLSCTX_ALL,IID_ISpVoice,(void**)&amp;pVoice); <br>  if(SUCCEEDED(hr)) <br>  { <br>  hr=pVoice-&gt;Speak(L"动作开始了",0,NULL); <br>  pVoice-&gt;Release(); <br>  pVoice=NULL; <br>  } <br>  CoUninitialize(); <br>  m_OpenGL-&gt;m_baiscobj-&gt;Move=0; <br>  m_OpenGL-&gt;m_baiscobj-&gt;BACK=0; <br>  m_OpenGL-&gt;m_baiscobj-&gt;LEFT=0; <br>  m_OpenGL-&gt;m_baiscobj-&gt;RIGHT=0; <br>  return TRUE ; <br>  } <br>   <br>  if(Recstring=="跑步") <br>  { <br>  ISpVoice *pVoice=NULL; <br>  if(FAILED(CoInitialize(NULL))) <br>  { <br>  MessageBox(hWnd,"Error to initialize COM","error",S_OK); <br>  return FALSE; <br>  } <br>  HRESULT hr=CoCreateInstance(CLSID_SpVoice,NULL,CLSCTX_ALL,IID_ISpVoice,(void**)&amp;pVoice); <br>  if(SUCCEEDED(hr)) <br>  { <br>  hr=pVoice-&gt;Speak(L"动作开始了",0,NULL); <br>  pVoice-&gt;Release(); <br>  pVoice=NULL; <br>  } <br>  CoUninitialize(); <br>  m_OpenGL-&gt;m_baiscobj-&gt;Move=1; <br>  return TRUE ; <br>  } <br>  if(Recstring=="退出") <br>  { <br>  m_OpenGL-&gt;CleanUp(); // 结束处理 <br>  PostQuitMessage(0); <br>  return TRUE; <br>  } <br>  } <br>  } <br>  } <br>  }return TRUE; <br>  } <br>  要注意的是RecoEvent()必须能处理人物、摄像头的漫游,所以在人物、摄像机类的行为函数中添加了控制变量Move、BACK、LEFT、RIGHT;并附了初值1,当在行为函数中为1时行为函数体执行,所以也必须 <br>  #include "OpenGL.h" <br>  #include "baiscobj.h" <br>  其间我们借助于指针变量,巧妙的使语音能控制行为,却不影响动画的刷新,但不足的是由于opengl动画md2模型的不能导入成功,使踢球,跳木箱等功能函数没有完成,所以只要行为函数出来,可通过上述同样方法实现语音控制。 <br>   <br>  4)如何在winmain()函数中执行语音程序? <br>  首先包含语音头文件〈sapi.h〉 <br>  接着(#define CSpeech speech)定义语音类对象 <br>   <br>  INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,INT )// WinMain程序入口 <br>  { <br>  ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);//初始化COM <br>  …… <br>  char cc[]="tml"; <br>  WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, <br>  GetModuleHandle(NULL), NULL, NULL, NULL, (LPCTSTR)IDR_MENU1, <br>  cc, NULL }; <br>  RegisterClassEx( &amp;wc ); <br>  m_OpenGL=new OpenGL();// <br>  hWnd = CreateWindowEx(NULL,cc,"智能精灵键盘(↑进↓退→右←左UP仰DOWM俯)", <br>  dwStyle|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,nX,nY,Width, Height,NULL,NULL,hInst,NULL); // 创建窗口 <br>  ShowWindow( hWnd, SW_SHOWDEFAULT ); // 显示窗口 <br>  UpdateWindow( hWnd ); // 刷新窗口 <br>  speech.b_Cmd_Grammar=FALSE; <br>  speech.initSR(); <br>  GameLoop(); // 进入消息循环 <br>  return 0; <br>  } <br>  通过speech.initSR(),执行语音的初始化,为了设置一个简单的语音识别开关,简单的添加一个任务栏,只有语音这一个菜单资源,然后利用消息机制,在消息处理函数里Switch(message)里添加: <br>  case WM_COMMAND: <br>  switch(LOWORD(wParam)) <br>  { <br>  case IDM_SPEECH:speech.startcmd(); <br>  } <br>  return 0;break; <br>  即当单击语音菜单时,则使语音功能完全激活,下面是这个函数的实体: <br>   <br>  void CSpeech::startcmd() <br>  { <br>  if(b_initSR) <br>  { <br>  HRESULT hr=m_cpCmdGrammar-&gt;SetRuleState(NULL,NULL,SPRS_ACTIVE); <br>  ISpVoice *pVoice=NULL; <br>  if(FAILED(CoInitialize(NULL))) <br>  { <br>  MessageBox(hWnd,"Error to initialize COM","error",S_OK); <br>  return ; <br>  } <br>  hr=CoCreateInstance(CLSID_SpVoice,NULL,CLSCTX_ALL,IID_ISpVoice,(void**)&amp;pVoice); <br>  if(SUCCEEDED(hr)) <br>  { <br>  hr=pVoice-&gt;Speak(L"语法已经激活",0,NULL); <br>  pVoice-&gt;Release(); <br>  pVoice=NULL; <br>  } <br>  CoUninitialize(); <br>  } <br>  } <br>  5)在所有的工作完成之前,还必须先在项目工程下添加XML语法文件,通过initSR()中的LoadCmdFromResource()函数加载;XML文件可通过以记事本形式打开编辑。具体如下: <br>  -<grammar langid="804">-<rule toplevel="ACTIVE" name="COMMAND">-<l><p>下</p> <p>左</p> <p>右</p> <p>向上走</p> <p>向下走</p> <p>跳</p> <p>停下来</p> <p>跑步</p> <p>识别</p> <p>语音</p> <p>还原</p> <p>文件</p> <p>踢球 <br></p> <p></p> <br><p><u><font color="#0000ff">需要的留下Email,我给大家发</font></u></p> </l></rule></grammar></unrecognized></ispaudio></isprecognizer></isprecogrammar></isprecocontext>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics