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. }  
相關文章
相關標籤/搜索