这段时间需要做个语音识别的程序,由于时间和能力有限,所以不大可能自己做一个识别引擎,怎么办呢,当然是查看度娘了。
这才发现网上其实有很多的解决方案,最出名的莫过于APPLE SIRI 以及GOOGLE NOW这两个识别引擎,GOOGLE NIOW已经在自己的安卓手机上进行了无数次测试,怎么说呢,这识别率简直是爆表啊,就算不是标准普通话,就像我这种川普也是没有问题的;少年你这么猛,你家人知道么
操作之前当然要去看看大神们的研究成果啦,我这里就不说原理了,大家转到这里去看看原帖点击打开链接找不到连接就看这里http://blog.csdn.net/dlangu0393/article/details/7214728
这里由于楼主以前是搞通信的,所以文件采用amr格式,这东西好啊,压缩率高,专门用来传输人声的,效果很赞哦,关键是还能滤掉杂音,可以提高识别率(自我安慰)
废话说了这么多!上代码
int CGoogleNowDlg::PostGoogleAPI()
{
char sendata[65536]={0};
SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
return 0;
SOCKADDR_IN server;
server.sin_family = AF_INET;
server.sin_port = htons(80);
struct hostent *host_addr = gethostbyname("www.google.com");
if (host_addr == NULL)
return -1;
server.sin_addr.s_addr = *((int *) *host_addr->h_addr_list);
if (::connect(sock, (SOCKADDR *) &server, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
::closesocket(sock);
return 0;
}
char temp[64] = {0};
FILE *fp;
fp = fopen("Out.amr" , "rb");
fseek( fp , 0 , SEEK_END );
int file_size;
file_size = ftell( fp );
char * tmp;
fseek( fp , 0 , SEEK_SET);
tmp = (char *)malloc( file_size * sizeof( char ) );
memset(tmp, '\0', file_size);
int ret = fread( tmp , sizeof(char) , file_size , fp );
fclose(fp);
strcat(sendata, "POST /speech-api/v1/recognize?xjerr=1&client=chromium&lang=zh-CN&maxresults=1 HTTP/1.1\r\n");//请求行
strcat(sendata,"Accept: */*\r\n");
strcat(sendata,"Accept-Language: zh-cn\r\n");
strcat(sendata,"Accept-Encoding: gzip, deflate\r\n");
strcat(sendata,"User-Agent: Mozilla/5.0\r\n");
strcat(sendata,"Host: www.google.com\r\n");
strcat(sendata,"Pragma: no-cache\r\n");
sprintf(temp, "Content-Length: %d\r\n", file_size);
strcat(sendata,temp);
strcat(sendata, "Content-Disposition: form-data; name='file'; filename='a.amr'\r\n");
strcat(sendata, "Content-Type: audio/amr; rate=8000\r\n\r\n");//在http头后边有一空行,空行后边接着发送post数据
CString SendData;
SendData = sendata;
for (int i = 0; i<file_size; i++)
{
SendData+=tmp[i];
}
int cx = send(sock, SendData, SendData.GetLength(), 0);//发出socket请求
//接收数据
char szBuffer[1024] = {0};
CString recvData;
int flag = 1;
while (true)
{
int nRet = ::recv(sock, szBuffer, sizeof(szBuffer), 0);
recvData = szBuffer;
if (nRet == 0 || nRet == WSAECONNRESET)
{
AfxMessageBox("Connection Closed.\n");
break;
}
else if (nRet == SOCKET_ERROR)
{
AfxMessageBox("socket error\n");
break;
}
else
{
int str = recvData.Find('{');
int needNum = recvData.GetLength()-str-1;
recvData = recvData.Right(recvData.GetLength()-str-1);
FILE * fp = fopen("GoogleSpeechAPI.txt","wb");
fwrite(recvData,needNum,1,fp);
fclose(fp);
break;
}
}
::closesocket(sock);
return 0;
}
这要严格按照这个结构组装,就不会出问题,在调试阶段,一定要查看返回值,如果出现400,表示你的结构有问题,出现200说明成功。
第二个问题就是,amr文件中含有大量NUL字符,这个字符表示文件结束,使用读取的时候一定要采用二进制方式读取,特别是在组装数据的过程中一定要强制性的组装所有字符,所以我采用一个个字符组装。不然会出现字符断掉的情况,返回值虽然为200但是最后并没有返回识别数据。
暂时就这样吧!有问题可以留言哦!
本文介绍了如何在MFC项目中利用Google Speech API进行语音识别。作者分享了自己的实践过程,强调了AMR文件格式在语音识别中的优势,以及在处理AMR文件时需要注意的二进制读取和NUL字符问题。通过调试和正确组装数据,可以成功实现语音识别功能。
9590

被折叠的 条评论
为什么被折叠?



