一、须添加mmsystem.h头文件
二、须添加winmm.lib库文件
三、waveInOpen函数提供把录音的消息回传到窗口函数和专用回调函数两种方式
如果要把录音层和UI层分离则最好使用专用回调函数方式,具体做法如下:
MMRESULT mmr = waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,
(DWORD)(MicCallback), DWORD(this), CALLBACK_FUNCTION);
其中MicCallback为自定义的专用函数名,格式如下:
static DWORD CALLBACK MicCallback( //消息回掉函数
HWAVEIN hWaveIn,
UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2);
DWORD CALLBACK MicCallback(HWAVEIN hwavein, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
switch(uMsg)
{
case WIM_OPEN:
//do something
break;
case WIM_DATA:
//do something
break;
case WIM_CLOSE:
//do something
break;
default:
break;
}
return 0;
}
如果使用窗口回调函数,则WIM_OPEN、WIM_DATA、WIM_CLOSE消息会自动被相应的窗口回调函数接收
具体使用方式 waveInOpen (&hWaveIn, WAVE_MAPPER, &waveform,
(DWORD) hwnd, 0, CALLBACK_WINDOW)
其中hwnd为相应的窗口回调函数所在的窗口句柄
回调函数是窗口函数和专用回调函数有点不一样:
如果回调函数是窗口回调函数,则WIM_OPEN事件是在waveInOpen执行完以后跳出调用waveInOpen的模块才产生
如果回调函数是专用回调函数,则WIM_OPEN事件是在waveInOpen刚刚执行(还没执行完)的时候就产生了,所以这个时候在WIM_OPEN事件处理中,不能有和waveInOpen存在时间相关性(逻辑先后顺序)的代码。
我在调试代码的时候就是被这个问题搞了两天,后来一步一步跟踪才发现这个问题。
windowapi录音的顺序:
一、建两个录音缓冲区,每个缓冲区大小2000byte
二、准备音频格式头waveform
三、使用waveInOpen函数创建一个音频输入设备句柄赋给hWaveIn
四、对应于两前的两个音频缓冲区,创建两个音频格式头pWaveHdr,并把缓冲区做为音频格式头的一个成员
五、使用waveInPrepareHeader函数把两个音频格式头初始化
六、使用waveInAddBuffer函数把两个音频格式头加入录音队列并调用waveInStart函数开始录音
七、录音开始自动把录到的音频存入音频格式头中对应的缓冲区中
八、当一个音频格式头对应的缓冲区满后,引发MM_WIM_DATA事件,并且声卡自动把这个音频格式头从录音队列中删队
回调函数响应MM_WIM_DATA处理录音数据时,一般就是把缓冲区里的数据倒出来,并且把这个缓冲区及对应的音频格式头重新初始化后加入录音队列中
九、停止录音的方法
可以waveInStop和waveInReset一起调用,考虑采用以下调用顺序。
waveInStop(hWaveIn);
waveInReset(hWaveIn);
waveInUnprepareHeader(hWaveIn, ...);
waveInClose(hWaveIn);
阅读(7956) | 评论(1) | 转发(0) |