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. }  
posted @ 2017-02-24 10:09  Qiengo  阅读(3075)  评论(0编辑  收藏  举报