关于windowsAPI录音(转载)

一、须添加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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
录音程序,可在DEC++或vc++6.0编译环境下成功运行 部分代码: int main() { creat_file(); //新建文件,原文件数据被删除 RecordWave(); //录音函数 simplest_pcm16le_to_wave("NocturneNo2inEflat_44.1k_s16le.pcm", 1, 44100, "output_nocture.wav"); //将二进制录音信息从内存中提取,并生成 wav 文件 测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 3 return 0; } void RecordWave() { int count = waveInGetNumDevs(); //检测录音设备 printf("\n 音频输入数量:%d\n", count); WAVEINCAPS waveIncaps; MMRESULT mmResult = waveInGetDevCaps(0, &waveIncaps;, sizeof(WAVEINCAPS)); printf("\n 音频输入设备:%s\n", waveIncaps.szPname); if (MMSYSERR_NOERROR == mmResult) { //HWAVEIN phwi; WAVEFORMATEX pwfx; //录音格式指针 WaveInitFormat (&pwfx;, //波形声音的格式,单声道双声道使用 WAVE_FORMAT_PCM.当包含在 WAVEFORMATEXTENSIBLE 结构中时,使用 WAVE_FORMAT_EXTENSIBLE 1, //声道数量 44100, //采样率 16 // 采样位数 ); printf("\n 正在打开音频输入设备"); printf("\n 采样参数:声道 44.1kHz 16bit\n"); mmResult = waveInOpen( &phwi;, WAVE_MAPPER, &pwfx;, (DWORD)(MicCallback), NULL, CALLBACK_FUNCTION );//3 if (MMSYSERR_NOERROR == mmResult) { //WAVEHDR pwh1; char buffer1[10240]; pwh1.lpData = buffer1; pwh1.dwBufferLength = 10240; pwh1.dwUser = 1; pwh1.dwFlags = 0; 测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 4 mmResult = waveInPrepareHeader(phwi, &pwh1;, sizeof(WAVEHDR));//为波形输 入设备准备缓冲区 printf("\n 准备缓冲区 1"); //WAVEHDR pwh2; char buffer2[10240]; pwh2.lpData = buffer2; pwh2.dwBufferLength = 10240; pwh2.dwUser = 2; pwh2.dwFlags = 0; mmResult = waveInPrepareHeader(phwi, &pwh2;, sizeof(WAVEHDR));//为波形输 入设备准备缓冲区 printf("\n 准备缓冲区 2\n"); // WAVEHDR pwh3; char buffer3[10240]; pwh3.lpData = buffer3; pwh3.dwBufferLength = 10240; pwh3.dwUser = 3; pwh3.dwFlags = 0; mmResult = waveInPrepareHeader(phwi, &pwh3;, sizeof(WAVEHDR));//为波形输 入设备准备缓冲区 printf("准备缓冲区 3\n"); if (MMSYSERR_NOERROR == mmResult) { mmResult = waveInAddBuffer(phwi, &pwh1;, sizeof(WAVEHDR));//给输入设 备增加一个缓存 printf("\n 将缓冲区 1 加入音频输入设备"); mmResult = waveInAddBuffer(phwi, &pwh2;, sizeof(WAVEHDR));//给输入设 备增加一个缓存 printf("\n 将缓冲区 2 加入音频输入设备\n"); mmResult = waveInAddBuffer(phwi, &pwh3;, sizeof(WAVEHDR));//给输入设 备增加一个缓存 printf("将缓冲区 3 加入音频输入设备\n");

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值