此文来自:http://blog.sina.com.cn/s/blog_488a8b4c0100032j.html
使用wave族函数,需要添加winmm.lib
是否需要加入mmsystem.h看情况
是否需要加入mmsystem.h看情况
//这是在头文件中需要添加的变量和函数
//具体用途会在下面介绍cpp文件时候都用到
//具体用途会在下面介绍cpp文件时候都用到
HWAVEIN hWaveIn; //输入设备
WAVEFORMATEX waveform; //采集音频的格式,结构体
BYTE *pBuffer1,*pBuffer2;//采集音频时的数据缓存
WAVEHDR wHdr1,wHdr2; //采集音频时包含数据缓存的结构体
static DWORD CALLBACK MicCallback( //消息回掉函数
HWAVEIN hWaveIn,
UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2);
/以下是cpp文件中的操作
WAVEFORMATEX waveform; //采集音频的格式,结构体
BYTE *pBuffer1,*pBuffer2;//采集音频时的数据缓存
WAVEHDR wHdr1,wHdr2; //采集音频时包含数据缓存的结构体
static DWORD CALLBACK MicCallback( //消息回掉函数
HWAVEIN hWaveIn,
UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2);
/以下是cpp文件中的操作
waveform.wFormatTag = WAVE_FORMAT_PCM;//声音格式为PCM
waveform.nSamplesPerSec = 16000;//采样率,16000次/秒
waveform.wBitsPerSample = 16;//采样比特,16bits/次
waveform.nChannels = 2;//采样声道数,2声道
waveform.nAvgBytesPerSec = 16000 * 4;//每秒的数据率,就是每秒能采集多少字节的数据
waveform.nBlockAlign = 4;//一个块的大小,采样bit的字节数乘以声道数
waveform.cbSize = 0;//一般为0
//使用waveInOpen函数开启音频采集
MMRESULT mmr = waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,
(DWORD)(MicCallback), DWORD(this), CALLBACK_FUNCTION);
if(mmr != MMSYSERR_NOERROR)
return false;
waveform.nSamplesPerSec = 16000;//采样率,16000次/秒
waveform.wBitsPerSample = 16;//采样比特,16bits/次
waveform.nChannels = 2;//采样声道数,2声道
waveform.nAvgBytesPerSec = 16000 * 4;//每秒的数据率,就是每秒能采集多少字节的数据
waveform.nBlockAlign = 4;//一个块的大小,采样bit的字节数乘以声道数
waveform.cbSize = 0;//一般为0
//使用waveInOpen函数开启音频采集
MMRESULT mmr = waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,
(DWORD)(MicCallback), DWORD(this), CALLBACK_FUNCTION);
if(mmr != MMSYSERR_NOERROR)
return false;
//建立两个数组(这里可以建立多个数组)用来缓冲音频数据
DWORD bufsize = 8 * 1024;
pBuffer1 = new BYTE[bufsize];
pBuffer2 = new BYTE[bufsize];
DWORD bufsize = 8 * 1024;
pBuffer1 = new BYTE[bufsize];
pBuffer2 = new BYTE[bufsize];
wHdr1.lpData = (LPSTR)pBuffer1;
wHdr1.dwBufferLength = bufsize;
wHdr1.dwBytesRecorded = 0;
wHdr1.dwUser = 0;
wHdr1.dwFlags = 0;
wHdr1.dwLoops = 1;
wHdr1.lpNext = NULL;
wHdr1.reserved = 0;
wHdr1.dwBufferLength = bufsize;
wHdr1.dwBytesRecorded = 0;
wHdr1.dwUser = 0;
wHdr1.dwFlags = 0;
wHdr1.dwLoops = 1;
wHdr1.lpNext = NULL;
wHdr1.reserved = 0;
//将建立好的wHdr1做为备用
waveInPrepareHeader(hWaveIn,&wHdr1,sizeof(WAVEHDR));
waveInPrepareHeader(hWaveIn,&wHdr1,sizeof(WAVEHDR));
wHdr2.lpData = (LPSTR)pBuffer2;
wHdr2.dwBufferLength = bufsize;
wHdr2.dwBytesRecorded = 0;
wHdr2.dwUser = 0;
wHdr2.dwFlags = 0;
wHdr2.dwLoops = 1;
wHdr2.lpNext = NULL;
wHdr2.reserved = 0;
wHdr2.dwBufferLength = bufsize;
wHdr2.dwBytesRecorded = 0;
wHdr2.dwUser = 0;
wHdr2.dwFlags = 0;
wHdr2.dwLoops = 1;
wHdr2.lpNext = NULL;
wHdr2.reserved = 0;
//将建立好的wHdr2做为备用
waveInPrepareHeader(hWaveIn,&wHdr2,sizeof(WAVEHDR));
waveInPrepareHeader(hWaveIn,&wHdr2,sizeof(WAVEHDR));
//将两个wHdr添加到waveIn中去
waveInAddBuffer (hWaveIn, &wHdr1, sizeof (WAVEHDR)) ;
waveInAddBuffer (hWaveIn, &wHdr2, sizeof (WAVEHDR)) ;
waveInAddBuffer (hWaveIn, &wHdr1, sizeof (WAVEHDR)) ;
waveInAddBuffer (hWaveIn, &wHdr2, sizeof (WAVEHDR)) ;
//开始音频采集
waveInStart(hWaveIn);
//下面这个是callback函数,对于采集到的音频数据都在这个函数中处理
DWORD CALLBACK
CIMAADPCMDlg::MicCallback(HWAVEIN hwavein, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
//这个CIMAADPCMDlg就是你的音频采集类
CIMAADPCMDlg*pWnd = (CIMAADPCMDlg*)dwInstance;
int re(0);
switch(uMsg)
{
case WIM_OPEN:
TRACE("WIM_OPEN/n");
break;
case WIM_DATA:
TRACE("WIM_DATA/n");
//这里就是对采集到的数据做处理的地方,我是做了发送处理
//((PWAVEHDR)dwParam1)->lpData这就是采集到的数据指针
//((PWAVEHDR)dwParam1)->dwBytesRecorded这就是采集到的数据长度
re = send(pWnd->sends,((PWAVEHDR)dwParam1)->lpData,((PWAVEHDR)dwParam1)->dwBytesRecorded,0);
//处理完了之后还要再把这个缓冲数组加回去
//pWnd->win代表是否继续采集,因为当停止采集的时候,只有当所有的
//缓冲数组都腾出来之后才能close,所以需要停止采集时就不要再waveInAddBuffer了
if(pWnd->win)
waveInAddBuffer (hwavein, (PWAVEHDR) dwParam1, sizeof (WAVEHDR)) ;
TRACE("%d/n",re);
break;
case WIM_CLOSE:
TRACE("WIM_CLOSE/n");
break;
waveInStart(hWaveIn);
//下面这个是callback函数,对于采集到的音频数据都在这个函数中处理
DWORD CALLBACK
CIMAADPCMDlg::MicCallback(HWAVEIN hwavein, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
//这个CIMAADPCMDlg就是你的音频采集类
CIMAADPCMDlg*pWnd = (CIMAADPCMDlg*)dwInstance;
int re(0);
switch(uMsg)
{
case WIM_OPEN:
TRACE("WIM_OPEN/n");
break;
case WIM_DATA:
TRACE("WIM_DATA/n");
//这里就是对采集到的数据做处理的地方,我是做了发送处理
//((PWAVEHDR)dwParam1)->lpData这就是采集到的数据指针
//((PWAVEHDR)dwParam1)->dwBytesRecorded这就是采集到的数据长度
re = send(pWnd->sends,((PWAVEHDR)dwParam1)->lpData,((PWAVEHDR)dwParam1)->dwBytesRecorded,0);
//处理完了之后还要再把这个缓冲数组加回去
//pWnd->win代表是否继续采集,因为当停止采集的时候,只有当所有的
//缓冲数组都腾出来之后才能close,所以需要停止采集时就不要再waveInAddBuffer了
if(pWnd->win)
waveInAddBuffer (hwavein, (PWAVEHDR) dwParam1, sizeof (WAVEHDR)) ;
TRACE("%d/n",re);
break;
case WIM_CLOSE:
TRACE("WIM_CLOSE/n");
break;
default:
break;
}
return 0;
}
break;
}
return 0;
}
//最后是结束采集
win = false;
//在这里可以等待一定的时间,确保所有缓冲数组全都退出来了
//也可以在WIM_DATA消息处理中加个计数器,计算全部buffer都
//退出来了,就可以调用下面的close了
waveInClose(hWaveIn);
win = false;
//在这里可以等待一定的时间,确保所有缓冲数组全都退出来了
//也可以在WIM_DATA消息处理中加个计数器,计算全部buffer都
//退出来了,就可以调用下面的close了
waveInClose(hWaveIn);