我的程序时基于科大讯飞的语音识别库开发的,你能开发出什么样的产品,当然依赖你得到的库。

                如果你的库只是试用版,只能添加30个词条,识别率在20%以下,等等你是开发不了好的产品的,我要介绍的程序是用的是试用版的库,添加的词条少,识别率低。还有要注意的就是,你必须有他们的很多头文件,还有线程,词条处理的两个执行cpp文件

                下面我介绍下 我的功能需求,开发过程和具体细节。。。

                主要是 1语音库初始化。  2.添加语音词条设置场景, 3.语音录入处理,  4识别结果输出,,

 

 

                1.语音库的初始化,

                对象创建需要调用API“EsrCreate”,如下ivStatus ivCall EsrCreate (ivHandle ivPtr phEsrObj,ivPCUserOS pUserOS);

                参数1,是定义一个空句柄,在ivDefine.h文件中(这是一个库内定义的参数,不许管,只要包含了头文件,就可以用了。大概需要这些头文件,ivDefine.h  ivEsrDefine.h  ivESR.h  ivEsrDefine.h   ivPlatform.h   ivErrorCode.h  线程执行文件 Thread.h  Thread.cpp记录文件 Record.h  Record.cpp)

                参数2 ,库内定义的参数,在ivEsrDefine.h文件总,主要语音库的初始化是针对此对象的初始化,属性很多。。

 

                

               初始化的具体过程  (回调函数全在下面。。) /* Aitalk对象句柄 */ivHandle      m_hEsrObj; /* 用户回调参数 */TUserData    m_tUserData;/* 识别服务线程句柄 */HANDLE     m_hESRThread;

              

          

//开始
               TUserOS tUserOS;
                memset(&tUserOS, 0, sizeof(TUserOS));                   @ 1 //对象大小    序列号(必填)
                tUserOS.nSize = sizeof(TUserOS);
                tUserOS.lpszLicence =(ivStrA)"你得到的库的序列号,否则库是没法使用的";                   @ 2    //用户平台是否支持动态内存分配
                tUserOS.lpfnRealloc = CBRealloc;                              //不支持 tUserSys.lpfnRealloc = ivNull;
                tUserOS.lpfnFree= CBFree;                                          //不支持  tUserSys.lpfnFree = ivNull;                   @ 3    //用户必须实现的回调函数
                             其中CBOpenFile、CBCloseFile和CBReadFile是需要用户实现的打开、关闭和读取文件的回调函数,以Windows平台unicode字符集为例
                tUserOS.lpfnReadFile = CBReadFile;
                tUserOS.lpfnOpenFile = CBOpenFile;
                 tUserOS.lpfnCloseFile = CBCloseFile; 
                 @ 4  //用户软件平台是否支持写文件操作?
               tUserOS.pPersisRAM = ivNull;                                     //不支持tUserSys.pRAM = USER_WORKBUFFER_ADDRESS;
                tUserOS.nPersisRAMSize = 0;                                     //不支持tUserSys.nRAMSize = USER_WORKBUFFER_BYTES;
                tUserOS.lpfnWriteFile = CBWriteFile;                         //tUserSys.lpfnWriteFile = ivNull;                                                                                 //USER_WORKBUFFER_ADDRESS 表示静态分配的Work Buffer的地址;
                                                                                 //USER_WORKBUFFER_BYTES 表示静态分配的Work Buffer的尺寸(字节数);             @ 5//用户是否希望进行资源数据校验?
                  希望:
               tUserSys.bCheckResource = ivTrue;                   //  希望:
               tUserSys.bCheckResource = ivFalse;                 //不希望:

                 tUserOS.lpfnMsgProc = CBMsgProc;                       //消息回调函数 
              m_tUserData.fpLog = _tfopen(_T("Aitalk4.0Log.esl"), _T("wb"));
               m_tUserData.pThis = this;              tUserOS.pUser = (ivPointer)&m_tUserData;
              ivStatus iStatus;
               iStatus = EsrCreate(&m_hEsrObj, &tUserOS);
              _ASSERT(ivErr_OK == iStatus);

 

     用户必须实现的回调函数

/* 内存分配回调函数 */
 ivPointer ivCall CBRealloc(ivPointer pUser, ivPointer p,ivSize nSize)
 {
  return realloc(p,nSize);
 }/* 内存释放回调函数 */
 void ivCall CBFree(ivPointer pUser, ivPointer p)
 {
  free(p);
 } 
/* 打开文件回调函数 */
 ivHandle ivCall CBOpenFile(ivPointer pUser, ivCStr lpFileName,ivInt enMod,ivInt enType)
 {
  FILE* pf;
  TCHAR szFileName[MAX_PATH];
  TCHAR* lpszMod;
  if(ivResFile == enType){
   _stprintf(szFileName, _T("%s"), _T(".\\Resource\\"));
  }
  else{
   _stprintf(szFileName, _T("%s"), _T(".\\"));
  }
  _tcscat(szFileName,(TCHAR *)lpFileName);
  if(ivModWrite == enMod){
   lpszMod = _T("wb");
  }
  else{
   lpszMod = _T("rb");
  } pf = _tfopen(szFileName,lpszMod);
 return (ivHandle)pf;
 }/* 关闭文件回调函数 */
 ivBool ivCall CBCloseFile(ivPointer pUser, ivHandle hFile)
 {
  return (0 == fclose((FILE*)hFile));
 }/* 读文件回调函数 */
 ivBool ivCall CBReadFile(ivPointer pUser, ivHandle hFile,ivPByte pBuffer,ivUInt32 iPos,ivSize nSize)
 {
  FILE* pf = (FILE*)hFile;
  ivSize nRead; /* 注意:当iPos值为FILE_POS_CURRENT时表示文件当前位置,不能调用fseek类函数 */
  if(FILE_POS_CURRENT != iPos){
   fseek(pf,iPos,SEEK_SET);
  } nRead = fread(pBuffer,1,nSize,pf);
  _ASSERT(nRead == nSize);
  return nRead == nSize;
 }/* 写文件回调函数 */
 ivBool ivCall CBWriteFile(ivPointer pUser, ivHandle hFile,ivPCByte pBuffer,ivUInt32 iPos,ivSize nSize)
 {
  FILE* pf = (FILE*)hFile;
  ivSize nWrite; /* 注意:当iPos值为FILE_POS_CURRENT时表示文件当前位置,不能调用fseek类函数 */
  if(FILE_POS_CURRENT != iPos){
   fseek(pf,iPos,SEEK_SET);
  } nWrite = fwrite(pBuffer,1,nSize,pf);
  _ASSERT(nWrite == nSize);
  return nWrite == nSize;
 }/* 消息回调函数 */
ivStatus ivCall CBMsgProc(ivPointer pUser, ivHandle hObj,ivUInt32 uMsg,ivUInt32 wParam,ivCPointer lParam)
 {
  PUserData pUser1 = (PUserData)EsrGetUserData(hObj);
  RRESULT err;
  CAitalkSample *pThis = (CAitalkSample *)pUser1->pThis; switch(uMsg)
  {
  case ivMsg_ToSleep:
   Sleep(wParam);
   break;
  case ivMsg_Create: 
   InitializeCriticalSection(&pUser1->tCriticalSection);
   break;
  case ivMsg_Destroy:
   DeleteCriticalSection(&pUser1->tCriticalSection);
   break;
  case ivMsg_ToEnterCriticalSection:
   /* 调用EnterCriticalSection时用户需保证其参数的有效性 */
   EnterCriticalSection(&pUser1->tCriticalSection);
   break;
  case ivMsg_ToLeaveCriticalSection:
   /* 调用LeaveCriticalSection时用户需保证其参数的有效性 */
   LeaveCriticalSection(&pUser1->tCriticalSection);
   break;
  case ivMsg_SpeechStart:
   pThis->OnSpeechStart();
   break;
  case ivMsg_SpeechEnd:
   break;
  case ivMsg_SpeechFlushEnd:
   break;
  case ivMsg_NoSpeechDetected:
   break;
  case ivMsg_ResponseTimeout:
   pThis->OnResponseTimeOut();
   break;
  case ivMsg_SpeechTimeout:
   pThis->OnSpeechTimeOut();
   break;
  case ivMsg_ToStartAudioRec:
   err = pThis->StartRecord();
   if(err != RECORD_ERR_OK){
    return ivErr_FALSE; 
   }
   break;
  case ivMsg_ToStopAudioRec:
   err = pThis->StopRecord();
   if(err != RECORD_ERR_OK){
    return ivErr_FALSE;
   }
   break;
  case ivMsg_Result:
   pThis->OnResult((WPARAM)wParam, (LPARAM)lParam);
   break;
  case ivMsg_LOG:
   fwrite(lParam, wParam, 1, pUser1->fpLog);
   fflush(pUser1->fpLog);
   return ivErr_FALSE;
  } return ivErr_OK;
 } 
 
/* “语音开始”消息处理函数 */
 void CAitalkSample::OnSpeechStart()
 {
  printf("%s\r\n", "Speech started!");
 }/* “反应超时”消息处理函数 */
 void CAitalkSample::OnResponseTimeOut()
 {
  printf("%s\r\n", "Response time out!");
  EsrExitService(m_hEsrObj);
 }
 /* “语音超时”消息处理函数 */
 void CAitalkSample::OnSpeechTimeOut()
 {
  printf("%s\r\n", "Speech time out!");
  EsrExitService(m_hEsrObj);
 } /* “有识别结果”消息处理函数 */
 void CAitalkSample::OnResult(WPARAM wParam, LPARAM lParam)
 {
  printf("%s\r\n", "Results arrive!");  PCEsrResult pResult = (PCEsrResult)lParam;
  ivUInt32 nBest = (ivUInt32)wParam;
  ivUInt32 i, j, k;
  FILE *fp;
     //只发一条消息
  ivCStrW pText1; setlocale(LC_ALL, "chs");
  /* 将结果输出到Result.txt文件中 */
  fp = _tfopen(_T("Result.txt"), _T("wb"));
  ivUInt32 n = 0xfeff;
  fwrite(&n, 2, 1, fp);
  for(i = 0; i < nBest; ++ i){
   fwprintf(fp, L"第%d候选 Best:\r\n", i + 1);  
   for(j = 0; j < pResult->nSlot; j ++){
    for(k = 0; k < pResult->pSlots[j].nItem; ++ k){
     ivCStrW pText = pResult->pSlots[j].pItems[k].pText;  
     fwprintf(fp, L"%s", (TCHAR*)pText);   //(TCHAR *)pText
     pText1=pText;
     
    }
   }
   fwprintf(fp, L"\r\n");
   pResult ++;
  }
  //发送出数据
     //sendMsg(pText1);
  fclose(fp);
  EsrExitService(m_hEsrObj);
 }

                      按照上述过程会实现对语音库的初始化, 为后续的添加词条添加场景,创造条件。。。