博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Windows WaveIn 录音
阅读量:5042 次
发布时间:2019-06-12

本文共 2772 字,大约阅读时间需要 9 分钟。

  1. 设置采集音频格式
    [cpp]
      
     
    1. WAVEFORMATEX waveform; //采集音频的格式,结构体  
    2. waveform.wFormatTag = WAVE_FORMAT_PCM;//声音格式为PCM  
    3. waveform.nSamplesPerSec = 8000;//采样率,16000次/秒  
    4. waveform.wBitsPerSample = 16;//采样比特,16bits/次  
    5. waveform.nChannels = 1;//采样声道数,2声道  
    6. waveform.nAvgBytesPerSec = 16000;//每秒的数据率,就是每秒能采集多少字节的数据  
    7. waveform.nBlockAlign = 2;//一个块的大小,采样bit的字节数乘以声道数  
    8. waveform.cbSize = 0;//一般为0  
  2. 提前准备好的录音数据缓存
    [cpp]
      
     
    1. m_pRecoderBuf = new unsigned char[20 * 1024];  
    2. m_recoderNum = 20;  
    3. m_recoderBufLen = 20 * 1024;  
    4. m_pWaveHdr  = new WAVEHDR[20];  
    5. memset(m_pRecoderBuf, 0, 20 * 1024);  
    6. memset(m_pWaveHdr, 0, sizeof(WAVEHDR) * 20);  
  3. 打开录音设备
    [cpp]
      
     
    1. MMRESULT mmres = waveInOpen(&m_hWaveIn, WAVE_MAPPER, &waveform, (DWORD_PTR)WaveInProc, (DWORD_PTR)this, CALLBACK_FUNCTION );  
    2.       
    3. if(mmres != MMSYSERR_NOERROR)  
    4. {  
    5.     // failed, try again.  
    6.     return;  
    7. }  
    WAVE_MAPPER表示系统会自己寻找合适的录音设备。
  4. 准备数据空间
    [cpp]
      
     
    1. for (int i = 0; i < m_recoderNum; ++i)  
    2. {  
    3.     m_pWaveHdr[i].lpData = (char*)m_pRecoderBuf + i * 1024;  
    4.     m_pWaveHdr[i].dwBufferLength = 1024;  
    5.     mmres = waveInPrepareHeader(m_hWaveIn, &m_pWaveHdr[i], sizeof(WAVEHDR));  
    6.     mmres = waveInAddBuffer(m_hWaveIn, &m_pWaveHdr[i], sizeof(WAVEHDR));  
    7. }  
  5. 开始录音并打开写文件
    [cpp]
      
     
    1. mmres = waveInStart(m_hWaveIn);  
    2.   
    3. SYSTEMTIME systemtime;  
    4. GetLocalTime(&systemtime);  
    5. char filename[256];  
    6. sprintf_s(filename, 256, "%d-%d-%d_%d_%d_%d.wav", systemtime.wYear, systemtime.wMonth, systemtime.wDay, systemtime.wHour, systemtime.wMinute, systemtime.wSecond);  
    7. m_pWavFile = wav_write_open(filename, 8000, 16, 1);  
  6. 要提前定义好数据接收回调函数,因为我们用的是CALLBACK_FUNCTION
    [cpp]
      
     
    1. static BOOL CALLBACK WaveInProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);  
    2. BOOL   WaveInProcImpl(HWAVEOUT hwo, UINT uMsg, DWORD dwParam1, DWORD dwParam2);  
    函数里的处理是:
    [cpp]
      
     
    1. BOOL CAudioFileConvertDlg::WaveInProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)  
    2. {  
    3.     CAudioFileConvertDlg* pPlayer = (CAudioFileConvertDlg*)dwInstance;  
    4.   
    5.     return pPlayer->WaveInProcImpl(hwo, uMsg, dwParam1, dwParam2);  
    6. }  
    7.   
    8. BOOL CAudioFileConvertDlg::WaveInProcImpl(HWAVEOUT hwo, UINT uMsg, DWORD dwParam1, DWORD dwParam2)  
    9. {  
    10.     // 忽略打开和关闭设备时的处理  
    11.     if(uMsg == WIM_DATA)  
    12.     {  
    13.         LPWAVEHDR pHdr = (LPWAVEHDR) dwParam1;  
    14.   
    15.         MMRESULT mmres = waveInUnprepareHeader (m_hWaveIn, pHdr, sizeof(WAVEHDR));  
    16.         //处理数据   
    17.         if (NULL != m_pWavFile)  
    18.         {  
    19.             wav_write_data(m_pWavFile, (unsigned char *)(pHdr->lpData), pHdr->dwBytesRecorded);  
    20.         }  
    21.         //重新准备数据  
    22.         mmres = waveInPrepareHeader(m_hWaveIn, pHdr, sizeof(WAVEHDR));  
    23.         mmres = waveInAddBuffer(m_hWaveIn, pHdr, sizeof(WAVEHDR));  
    24.     }  
    25.   
    26.     return TRUE;  
    27. }  
  7. 关闭录音并关闭wav写文件
    [cpp]
      
     
    1. MMRESULT mmres = waveInStop(m_hWaveIn);  
    2. mmres = waveInClose(m_hWaveIn);  
    3. wav_write_close(m_pWavFile);  
    4. if (NULL != m_pRecoderBuf)  
    5. {  
    6.     delete []m_pRecoderBuf;  
    7.     m_pRecoderBuf = NULL;  
    8. }  
    9.   
    10. if (NULL != m_pWaveHdr)  
    11. {  
    12.     delete []m_pWaveHdr;  
    13.     m_pWaveHdr = NULL;  
    14. }  

转载于:https://www.cnblogs.com/qiengo/p/6437308.html

你可能感兴趣的文章
php修改SESSION的有效生存时间
查看>>
spring security 11种过滤器介绍
查看>>
Hibernate一对多、多对一关联
查看>>
一、记录Git使用中遇到的问题及解决方法
查看>>
学习网址
查看>>
前端表格插件datatables
查看>>
内部类
查看>>
树链剖分入门
查看>>
图解算法时间复杂度
查看>>
UI_搭建MVC
查看>>
一个样例看清楚JQuery子元素选择器children()和find()的差别
查看>>
代码实现导航栏分割线
查看>>
Windows Phone开发(7):当好总舵主 转:http://blog.csdn.net/tcjiaan/article/details/7281421...
查看>>
VS 2010打开设计器出现错误
查看>>
SQLServer 镜像功能完全实现
查看>>
Vue-详解设置路由导航的两种方法
查看>>
一个mysql主从复制的配置案例
查看>>
大数据学习系列(8)-- WordCount+Block+Split+Shuffle+Map+Reduce技术详解
查看>>
dvwa网络渗透测试环境的搭建
查看>>
Win8 安装VS2012 和 Sql Server失败问题
查看>>