• Windows WaveIn 录音


    1. 设置采集音频格式
      [cpp] view plain copy
       在CODE上查看代码片派生到我的代码片
      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] view plain copy
       在CODE上查看代码片派生到我的代码片
      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] view plain copy
       在CODE上查看代码片派生到我的代码片
      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] view plain copy
       在CODE上查看代码片派生到我的代码片
      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] view plain copy
       在CODE上查看代码片派生到我的代码片
      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] view plain copy
       在CODE上查看代码片派生到我的代码片
      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] view plain copy
       在CODE上查看代码片派生到我的代码片
      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] view plain copy
       在CODE上查看代码片派生到我的代码片
      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. }  
  • 相关阅读:
    Photoshop色阶、曲线命令图解和编程实现(附源码)
    苹果Mac OS X快捷键大全
    lucene Field部分参数设置含义
    图片管理下载逻辑
    Lucene.Net无障碍学习和使用:索引篇 (转)
    Firebug 调试器开发中的12个技巧
    Lucene.Net 多线程操作建议(转)
    如何在ASP.NET中下载文件
    Lucene.Net 2.3.1开发介绍 —— 简介 (转)
    JS打开图片另存为对话框 (转)
  • 原文地址:https://www.cnblogs.com/qiengo/p/6437308.html
Copyright © 2020-2023  润新知