1. 程式人生 > >C++ 採集音訊流(PCM裸流)實現錄音功能

C++ 採集音訊流(PCM裸流)實現錄音功能

#include "stdafx.h"
#include <stdio.h>  
#include <windows.h>  
#pragma comment(lib, "winmm.lib")  
 
HWAVEIN hWaveIn;  //輸入裝置
WAVEFORMATEX waveform; //採集音訊的格式,結構體
BYTE *pBuffer1;//採集音訊時的資料快取
WAVEHDR wHdr1; //採集音訊時包含資料快取的結構體
FILE *pf;
int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE          wait;
    waveform.wFormatTag = WAVE_FORMAT_PCM;//聲音格式為PCM
    waveform.nSamplesPerSec = 8000;//取樣率,16000次/秒
    waveform.wBitsPerSample = 16;//取樣位元,16bits/次
    waveform.nChannels = 1;//取樣聲道數,2聲道
    waveform.nAvgBytesPerSec = 16000;//每秒的資料率,就是每秒能採集多少位元組的資料
    waveform.nBlockAlign = 2;//一個塊的大小,取樣bit的位元組數乘以聲道數
    waveform.cbSize = 0;//一般為0
 
    wait = CreateEvent(NULL, 0, 0, NULL);
    //使用waveInOpen函式開啟音訊採集
    waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform,(DWORD_PTR)wait, 0L, CALLBACK_EVENT);
 
    //建立兩個陣列(這裡可以建立多個數組)用來緩衝音訊資料
    DWORD bufsize = 1024*100;//每次開闢10k的快取儲存錄音資料
    int i = 20;
    fopen_s(&pf, "錄音測試.pcm", "wb");
    while (i--)//錄製20左右秒聲音,結合音訊解碼和網路傳輸可以修改為實時錄音播放的機制以實現對講功能
    {
        pBuffer1 = new BYTE[bufsize];
        wHdr1.lpData = (LPSTR)pBuffer1;
        wHdr1.dwBufferLength = bufsize;
        wHdr1.dwBytesRecorded = 0;
        wHdr1.dwUser = 0;
        wHdr1.dwFlags = 0;
        wHdr1.dwLoops = 1;
        waveInPrepareHeader(hWaveIn, &wHdr1, sizeof(WAVEHDR));//準備一個波形資料塊頭用於錄音
        waveInAddBuffer(hWaveIn, &wHdr1, sizeof (WAVEHDR));//指定波形資料塊為錄音輸入快取
        waveInStart(hWaveIn);//開始錄音
        Sleep(1000);//等待聲音錄製1s
        waveInReset(hWaveIn);//停止錄音
        fwrite(pBuffer1, 1, wHdr1.dwBytesRecorded, pf);
        delete pBuffer1;    
        printf("%ds  ", i);
    }
    fclose(pf);
 
    waveInClose(hWaveIn);
    return 0;
}