语音聊天

需要代码好久前就已经用完了,但人懒没办法,现在才来总结,生怕以后要用的时候忘得一干二净,唉......

由于我是在对话框语音聊天工程使用的,所以还是以对话框语音聊天工程为例。

首先为工程连接winmm.lib库,然后在.h头文件中#include "mmsystem.h"。

然后在对话框头文件类定义之前定义一个参数:

#define BUFFER_SIZE  400     //录音buf大小,buf大小越小,实时性越好,连续性越差。

然后在类定义里面定义以下几个变量:

public:

WAVEHDR m_WAVEHDR1,m_WAVEHDR2;

char m_cbBuffer1[BUFFER_SIZE],m_cbBuffer2[BUFFER_SIZE];

HWAVEIN m_hWaveIn;

WAVEFORMATEX  m_waveformin;

BOOL m_nRecordEnd;  //录音停止状态,用这个变量来控制录音是否要结束。

然后在头文件中声明一个录音函数 void SoundIn();在cpp文件中定义录音函数:

void CChatDlg::SoundIn()  //录音函数
{   
 if(!waveInGetNumDevs())    //先侦查有米可以录音的设备
 {MessageBox("device In erroe") ;
 return;} 
 
 m_waveformin.wFormatTag=WAVE_FORMAT_PCM;  //设置录音格式,关于这个格式具体解释自己Google一下吧
 m_waveformin.nChannels=1;
 m_waveformin.nSamplesPerSec=11052;

 m_waveformin.wBitsPerSample=8;
 m_waveformin.nBlockAlign=m_waveformin.nChannels * m_waveformin.wBitsPerSample / 8; 
 m_waveformin.nAvgBytesPerSec=m_waveformin.nSamplesPerSec * m_waveformin.nBlockAlign;
 m_waveformin.cbSize=0;    
 
MMRESULT error;
error=waveInOpen(&m_hWaveIn,WAVE_MAPPER, &m_waveformin, (DWORD)m_hWnd,NULL,CALLBACK_WINDOW); //打开录音设备,成功的话函数会把录音设备的句柄赋给m_hWaveIn
 if(MMSYSERR_NOERROR !=error)  //打开设备失败的错误判断
 {
 if(MMSYSERR_ALLOCATED==error)
 MessageBox("wave In open erroe:MMSYSERR_ALLOCATED") ;
 
 if(MMSYSERR_BADDEVICEID==error)
 MessageBox("wave In open erroe:MMSYSERR_BADDEVICEID") ;
    
 if(MMSYSERR_NODRIVER==error)
 MessageBox("wave In open erroe:MMSYSERR_NODRIVER") ;
 
 if(MMSYSERR_NOMEM==error)
 MessageBox("wave In open erroe:MMSYSERR_NOMEM") ;    
 
 if(WAVERR_BADFORMAT==error)
 MessageBox("wave In open erroe:WAVERR_BADFORMAT") ; 
 return;
 }
  //开始为录音准备缓存,下面定义双缓冲,可以避免录音的不连续。
 m_WAVEHDR1.lpData = (LPTSTR)m_cbBuffer1; 

 //把char m_cbBuffer1[BUFFER_SIZE]挂载到声音缓存结构体m_WAVEHDR1里面。
 m_WAVEHDR1.dwBufferLength = BUFFER_SIZE;
 m_WAVEHDR1.dwBytesRecorded = 0;
 m_WAVEHDR1.dwUser=0;
 m_WAVEHDR1.dwFlags=0;
 m_WAVEHDR1.dwLoops=1;
 m_WAVEHDR1.lpNext=NULL;
 m_WAVEHDR1.reserved=0;
 
 m_WAVEHDR2.lpData = (LPTSTR)m_cbBuffer2;
 m_WAVEHDR2.dwBufferLength = BUFFER_SIZE;
 m_WAVEHDR2.dwBytesRecorded = 0;
 m_WAVEHDR2.dwUser=0;
 m_WAVEHDR2.dwFlags=0;
 m_WAVEHDR2.dwLoops=1;
 m_WAVEHDR2.lpNext=NULL;
 m_WAVEHDR2.reserved=0;
  
 waveInPrepareHeader(m_hWaveIn,&m_WAVEHDR1,sizeof(WAVEHDR));   //按照字面理解就是准备内存块录音 
 waveInPrepareHeader(m_hWaveIn,&m_WAVEHDR2,sizeof(WAVEHDR));
 
 waveInAddBuffer(m_hWaveIn,&m_WAVEHDR1,sizeof(WAVEHDR));  //按照字面理解就是把内存块加载上去
 waveInAddBuffer(m_hWaveIn,&m_WAVEHDR2,sizeof(WAVEHDR));
 
 m_nRecordEnd = FALSE;  //设置录音状态
 
 if(MMSYSERR_NOERROR !=waveInStart(m_hWaveIn))  //开始录音
 {MessageBox("Wave In start erroe") ;
 return;}
}

随着录音的不断进行,声音数据就不断的填充录音缓存,当一个录音缓存被填充满了之后就会促发MM_WIM_DATA消息,我们可以对这个消息做出处理,把缓存里面的声音数据按自己的要求处理。

首先在头文件定义消息处理函数,在两个AFX_MSG之间添加 afx_msg void OnMM_WIM_DATA(UINT wParam,LONG lParam);

在源文件添加消息映射,在两个AFX_MSG_MAP之间添加 ON_MESSAGE(MM_WIM_DATA,OnMM_WIM_DATA)

OnMM_WIM_DATA函数的具体定义如下:

void CChatDlg::OnMM_WIM_DATA(UINT wParam, LONG lParam) 
{ PWAVEHDR pWaveHdr = (PWAVEHDR)lParam;
  int length=sendto(soundsend, pWaveHdr->lpData,BUFFER_SIZE,0,(SOCKADDR*)&SoundaddrFrom,sizeof(SOCKADDR)); 

//由于这个例子是做语音聊天的,我们就把缓存里面的声音数据发送到指定的IP地址去。

  if(SOCKET_ERROR==length)
  {MessageBox("sound send failure!");
   return;
  }

  if(m_nRecordEnd == TRUE)  

/*判断录音状态,如果要停止录音就执行waveInClose(m_hWaveIn)关闭录音设备。我们可以建立一个停止录音按钮,按下按钮m_nRecordEnd 就变为TRUE。下面会给出停止录音按钮函数的实现。*/
  {  waveInClose(m_hWaveIn);
  return ;
  }

  waveInAddBuffer(m_hWaveIn, pWaveHdr, sizeof (WAVEHDR));

//把缓存加载到录音上去循环使用,不然的话,两个录音缓存装满了后就没有缓存用来继续录音了。
}

 

添加一个停止录音的按钮,对按钮按下做出消息响应,消息响应函数void OnSoundExit() 。
void CChatDlg::OnSoundExit() 
{
 // TODO: Add your control notification handler code here
 m_nRecordEnd = TRUE;
 waveInReset(m_hWaveIn);

}

在上面的函数中,除了把停止录音状态改为TRUE,还执行waveInReset(m_hWaveIn),这个函数会发出MM_WIM_DATA消息,从而接着执行OnMM_WIM_DATA(UINT wParam, LONG lParam) 函数,在OnMM_WIM_DATA函数里判断到m_nRecordEnd 为TRUE的话,就会执行waveInClose(m_hWaveIn),这个函数会发出MM_WIM_CLOSE消息,我们对这个消息作出响应,在响应函数中做一些收尾的工作。

首先在头文件声明消息响应函数

 afx_msg void OnMM_WIM_CLOSE(UINT wParam,LONG lParam);

然后在cpp文件进行消息映射

 ON_MESSAGE(MM_WIM_CLOSE,OnMM_WIM_CLOSE)

响应函数的定义如下:

void CChatDlg::OnMM_WIM_CLOSE(UINT wParam, LONG lParam)
{   m_nRecordEnd=FALSE;   //把录音停止状态改为FALSE
    waveInUnprepareHeader (m_hWaveIn, &m_WAVEHDR1, sizeof (WAVEHDR)) ;  //解除录音缓存
    waveInUnprepareHeader (m_hWaveIn, &m_WAVEHDR2, sizeof (WAVEHDR)) ;
}

OK 完毕了 下一篇总结如何放音吧 (*^__^*) 嘻嘻……

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
# 说明 该库是对目前市面上已有的开源中文聊天语料的搜集和系统化整理工作 该库搜集了包含 - chatterbot - 豆瓣多轮 - PTT八卦语料 - 青云语料 - 电视剧对白语料 - 贴吧论坛回帖语料 - 微博语料 - 小黄鸡语料 共8个公开闲聊常用语料和短信,白鹭时代问答等语料。 并对8个常见语料的数据进行了统一化规整和处理,达到直接可以粗略使用的目的。 **使用该项目,即可对所有的聊天语料进行一次性的处理和统一下载,不需要到处自己去搜集下载和分别处理各种不同的格式。* # 环境 python3 # 处理过程 将各个来源的语料按照其原格式进行提取,提取后进行繁体字转换,然后统一变成一轮一轮的对话。 # 使用方法 将解压后的raw_chat_corpus文件夹放到当前目录下 目录结构为 ``` raw_chat_corpus -- language -- process_pipelines -- raw_chat_corpus ---- chatterbot-1k ---- douban-multiturn-100w ---- .... -- main.py -- ... ``` 执行命令即可 ```bash python main.py ``` 或者 ```bash python3 main.py ``` # 生成结果 每个来源的语料分别生成一个独立的*.tsv文件,都放在新生成的clean_chat_corpus文件夹下。 生成结果格式为 tsv格式,每行是一个样本,先是query,再是answer ``` query \t answer ``` # 结果的使用 这个就根据每个人不同的情况自主使用即可 个人对于聊天机器人方向实践也不是很多,以下一篇之前写的知乎专栏供参考 **《从产品完整性的角度浅谈chatbot》** 文章粗略讲解了如下一些方面,介绍了聊天机器人在实际产品化过程中可能遇到的问题和解决办法。 1. chatbot自身人格的设置 1. 产品上线需要考虑的敏感词处理 1. 文本检索模型的使用 1. 文本生成模型的使用 1. 回答打分机制 1. 万能回答的使用策略 1. 多媒体消息的处理 1. 产品模型部署的问题 # 版权说明 本项目为非商业项目,为纯搜集和汇总资料,如有侵权,请在issue下留言。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值