VC 语音识别程序做法 (1)

 

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

                如果你的库只是试用版,只能添加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);
}


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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值