錄音程序

1.獲取pcm文件:

#include <stdio.h>  
#include <windows.h>  
#pragma comment(lib, "winmm.lib")  

HWAVEIN hWaveIn;  //輸入設(shè)備
WAVEFORMATEX waveform; //采集音頻的格式,結(jié)構(gòu)體
BYTE *pBuffer1;//采集音頻時的數(shù)據(jù)緩存
WAVEHDR wHdr1; //采集音頻時包含數(shù)據(jù)緩存的結(jié)構(gòu)體
FILE *pf;
int main()
{
    HANDLE          wait;
    waveform.wFormatTag = WAVE_FORMAT_PCM;//聲音格式為PCM
    waveform.nSamplesPerSec = 8000;//采樣率,16000次/秒
    waveform.wBitsPerSample = 16;//采樣比特,16bits/次
    waveform.nChannels = 1;//采樣聲道數(shù),2聲道
    waveform.nAvgBytesPerSec = 16000;//每秒的數(shù)據(jù)率,就是每秒能采集多少字節(jié)的數(shù)據(jù)
    waveform.nBlockAlign = 2;//一個塊的大小,采樣bit的字節(jié)數(shù)乘以聲道數(shù)
    waveform.cbSize = 0;//一般為0

    wait = CreateEvent(NULL, 0, 0, NULL);
    //使用waveInOpen函數(shù)開啟音頻采集
    waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, (DWORD_PTR)wait, 0L, CALLBACK_EVENT);

    //建立兩個數(shù)組(這里可以建立多個數(shù)組)用來緩沖音頻數(shù)據(jù)
    DWORD bufsize = 1024 * 100;//每次開辟10k的緩存存儲錄音數(shù)據(jù)
    int i = 10;
    fopen_s(&pf, "錄音測試.pcm", "wb");
    while (i--)//錄制20左右秒聲音,結(jié)合音頻解碼和網(wǎng)絡(luò)傳輸可以修改為實(shí)時錄音播放的機(jī)制以實(shí)現(xiàn)對講功能
    {
        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));//準(zhǔn)備一個波形數(shù)據(jù)塊頭用于錄音
        waveInAddBuffer(hWaveIn, &wHdr1, sizeof(WAVEHDR));//指定波形數(shù)據(jù)塊為錄音輸入緩存
        waveInStart(hWaveIn);//開始錄音
        Sleep(1000);//等待聲音錄制1s
        waveInReset(hWaveIn);//停止錄音
        fwrite(pBuffer1, 1, wHdr1.dwBytesRecorded, pf);
        delete pBuffer1;
        printf("%ds  ", i);
    }
    fclose(pf);

    waveInClose(hWaveIn);
    return 0;
}

2.pcm轉(zhuǎn)wav

#include <stdio.h>  
#include <windows.h>  
#pragma comment(lib, "winmm.lib")  

HWAVEIN hWaveIn;  //輸入設(shè)備
WAVEFORMATEX waveform; //采集音頻的格式,結(jié)構(gòu)體
BYTE *pBuffer1;//采集音頻時的數(shù)據(jù)緩存
WAVEHDR wHdr1; //采集音頻時包含數(shù)據(jù)緩存的結(jié)構(gòu)體
FILE *pf;

int simplest_pcm16le_to_wave(const char *pcmpath, int channels, int sample_rate, const char *wavepath)
{

    typedef struct WAVE_HEADER {
        char         fccID[4];
        unsigned   long    dwSize;
        char         fccType[4];
    }WAVE_HEADER;

    typedef struct WAVE_FMT {
        char         fccID[4];
        unsigned   long       dwSize;
        unsigned   short     wFormatTag;
        unsigned   short     wChannels;
        unsigned   long       dwSamplesPerSec;
        unsigned   long       dwAvgBytesPerSec;
        unsigned   short     wBlockAlign;
        unsigned   short     uiBitsPerSample;
    }WAVE_FMT;

    typedef struct WAVE_DATA {
        char       fccID[4];
        unsigned long dwSize;
    }WAVE_DATA;


    if (channels == 0 || sample_rate == 0) {
        channels = 2;
        sample_rate = 8000;
    }
    int bits = 16;

    WAVE_HEADER   pcmHEADER;
    WAVE_FMT   pcmFMT;
    WAVE_DATA   pcmDATA;

    unsigned   short   m_pcmData;
    FILE   *fp, *fpout;

    fp = fopen(pcmpath, "rb");
    if (fp == NULL) {
        printf("open pcm file error\n");
        return -1;
    }
    fpout = fopen(wavepath, "wb+");
    if (fpout == NULL) {
        printf("create wav file error\n");
        return -1;
    }
    //WAVE_HEADER  
    memcpy(pcmHEADER.fccID, "RIFF", strlen("RIFF"));
    memcpy(pcmHEADER.fccType, "WAVE", strlen("WAVE"));
    fseek(fpout, sizeof(WAVE_HEADER), 1);
    //WAVE_FMT  
    pcmFMT.dwSamplesPerSec = sample_rate;
    pcmFMT.dwAvgBytesPerSec = pcmFMT.dwSamplesPerSec * sizeof(m_pcmData);
    pcmFMT.uiBitsPerSample = bits;
    memcpy(pcmFMT.fccID, "fmt ", strlen("fmt "));
    pcmFMT.dwSize = 16;
    pcmFMT.wBlockAlign = 2;
    pcmFMT.wChannels = channels;
    pcmFMT.wFormatTag = 1;

    fwrite(&pcmFMT, sizeof(WAVE_FMT), 1, fpout);

    //WAVE_DATA;  
    memcpy(pcmDATA.fccID, "data", strlen("data"));
    pcmDATA.dwSize = 0;
    fseek(fpout, sizeof(WAVE_DATA), SEEK_CUR);

    fread(&m_pcmData, sizeof(unsigned short), 1, fp);
    while (!feof(fp)) {
        pcmDATA.dwSize += 2;
        fwrite(&m_pcmData, sizeof(unsigned short), 1, fpout);
        fread(&m_pcmData, sizeof(unsigned short), 1, fp);
    }

    pcmHEADER.dwSize = 44 + pcmDATA.dwSize;

    rewind(fpout);
    fwrite(&pcmHEADER, sizeof(WAVE_HEADER), 1, fpout);
    fseek(fpout, sizeof(WAVE_FMT), SEEK_CUR);
    fwrite(&pcmDATA, sizeof(WAVE_DATA), 1, fpout);

    fclose(fp);
    fclose(fpout);

    return 0;
}



int main()
{
    HANDLE          wait;
    waveform.wFormatTag = WAVE_FORMAT_PCM;//聲音格式為PCM
    waveform.nSamplesPerSec = 8000;//采樣率,16000次/秒
    waveform.wBitsPerSample = 16;//采樣比特,16bits/次
    waveform.nChannels = 1;//采樣聲道數(shù),2聲道
    waveform.nAvgBytesPerSec = 16000;//每秒的數(shù)據(jù)率,就是每秒能采集多少字節(jié)的數(shù)據(jù)
    waveform.nBlockAlign = 2;//一個塊的大小,采樣bit的字節(jié)數(shù)乘以聲道數(shù)
    waveform.cbSize = 0;//一般為0

    wait = CreateEvent(NULL, 0, 0, NULL);
    //使用waveInOpen函數(shù)開啟音頻采集
    waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, (DWORD_PTR)wait, 0L, CALLBACK_EVENT);

    //建立兩個數(shù)組(這里可以建立多個數(shù)組)用來緩沖音頻數(shù)據(jù)
    DWORD bufsize = 1024 * 100;//每次開辟10k的緩存存儲錄音數(shù)據(jù)
    int i = 10;
    fopen_s(&pf, "1.pcm", "wb");
    while (i--)//錄制20左右秒聲音,結(jié)合音頻解碼和網(wǎng)絡(luò)傳輸可以修改為實(shí)時錄音播放的機(jī)制以實(shí)現(xiàn)對講功能
    {
        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));//準(zhǔn)備一個波形數(shù)據(jù)塊頭用于錄音
        waveInAddBuffer(hWaveIn, &wHdr1, sizeof(WAVEHDR));//指定波形數(shù)據(jù)塊為錄音輸入緩存
        waveInStart(hWaveIn);//開始錄音
        Sleep(1000);//等待聲音錄制1s
        waveInReset(hWaveIn);//停止錄音
        fwrite(pBuffer1, 1, wHdr1.dwBytesRecorded, pf);
        delete pBuffer1;
        printf("%ds  ", i);
    }
    fclose(pf);

    simplest_pcm16le_to_wave("1.pcm", 1, 8000, "1.wav");

    waveInClose(hWaveIn);
    return 0;
}

3.錄音轉(zhuǎn)為pcm再轉(zhuǎn)為wav:

#include <stdio.h>  
#include <windows.h>  
#pragma comment(lib, "winmm.lib")  

HWAVEIN hWaveIn;  //輸入設(shè)備
WAVEFORMATEX waveform; //采集音頻的格式,結(jié)構(gòu)體
BYTE *pBuffer1;//采集音頻時的數(shù)據(jù)緩存
WAVEHDR wHdr1; //采集音頻時包含數(shù)據(jù)緩存的結(jié)構(gòu)體
FILE *pf;

int simplest_pcm16le_to_wave(const char *pcmpath, int channels, int sample_rate, const char *wavepath)
{

    typedef struct WAVE_HEADER {
        char         fccID[4];
        unsigned   long    dwSize;
        char         fccType[4];
    }WAVE_HEADER;

    typedef struct WAVE_FMT {
        char         fccID[4];
        unsigned   long       dwSize;
        unsigned   short     wFormatTag;
        unsigned   short     wChannels;
        unsigned   long       dwSamplesPerSec;
        unsigned   long       dwAvgBytesPerSec;
        unsigned   short     wBlockAlign;
        unsigned   short     uiBitsPerSample;
    }WAVE_FMT;

    typedef struct WAVE_DATA {
        char       fccID[4];
        unsigned long dwSize;
    }WAVE_DATA;


    if (channels == 0 || sample_rate == 0) {
        channels = 2;
        sample_rate = 8000;
    }
    int bits = 16;

    WAVE_HEADER   pcmHEADER;
    WAVE_FMT   pcmFMT;
    WAVE_DATA   pcmDATA;

    unsigned   short   m_pcmData;
    FILE   *fp, *fpout;

    fp = fopen(pcmpath, "rb");
    if (fp == NULL) {
        printf("open pcm file error\n");
        return -1;
    }
    fpout = fopen(wavepath, "wb+");
    if (fpout == NULL) {
        printf("create wav file error\n");
        return -1;
    }
    //WAVE_HEADER  
    memcpy(pcmHEADER.fccID, "RIFF", strlen("RIFF"));
    memcpy(pcmHEADER.fccType, "WAVE", strlen("WAVE"));
    fseek(fpout, sizeof(WAVE_HEADER), 1);
    //WAVE_FMT  
    pcmFMT.dwSamplesPerSec = sample_rate;
    pcmFMT.dwAvgBytesPerSec = pcmFMT.dwSamplesPerSec * sizeof(m_pcmData);
    pcmFMT.uiBitsPerSample = bits;
    memcpy(pcmFMT.fccID, "fmt ", strlen("fmt "));
    pcmFMT.dwSize = 16;
    pcmFMT.wBlockAlign = 2;
    pcmFMT.wChannels = channels;
    pcmFMT.wFormatTag = 1;

    fwrite(&pcmFMT, sizeof(WAVE_FMT), 1, fpout);

    //WAVE_DATA;  
    memcpy(pcmDATA.fccID, "data", strlen("data"));
    pcmDATA.dwSize = 0;
    fseek(fpout, sizeof(WAVE_DATA), SEEK_CUR);

    fread(&m_pcmData, sizeof(unsigned short), 1, fp);
    while (!feof(fp)) {
        pcmDATA.dwSize += 2;
        fwrite(&m_pcmData, sizeof(unsigned short), 1, fpout);
        fread(&m_pcmData, sizeof(unsigned short), 1, fp);
    }

    pcmHEADER.dwSize = 44 + pcmDATA.dwSize;

    rewind(fpout);
    fwrite(&pcmHEADER, sizeof(WAVE_HEADER), 1, fpout);
    fseek(fpout, sizeof(WAVE_FMT), SEEK_CUR);
    fwrite(&pcmDATA, sizeof(WAVE_DATA), 1, fpout);

    fclose(fp);
    fclose(fpout);

    return 0;
}



int main()
{
    HANDLE          wait;
    waveform.wFormatTag = WAVE_FORMAT_PCM;//聲音格式為PCM
    waveform.nSamplesPerSec = 8000;//采樣率,16000次/秒
    waveform.wBitsPerSample = 16;//采樣比特,16bits/次
    waveform.nChannels = 1;//采樣聲道數(shù),2聲道
    waveform.nAvgBytesPerSec = 16000;//每秒的數(shù)據(jù)率,就是每秒能采集多少字節(jié)的數(shù)據(jù)
    waveform.nBlockAlign = 2;//一個塊的大小,采樣bit的字節(jié)數(shù)乘以聲道數(shù)
    waveform.cbSize = 0;//一般為0

    wait = CreateEvent(NULL, 0, 0, NULL);
    //使用waveInOpen函數(shù)開啟音頻采集
    waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, (DWORD_PTR)wait, 0L, CALLBACK_EVENT);

    //建立兩個數(shù)組(這里可以建立多個數(shù)組)用來緩沖音頻數(shù)據(jù)
    DWORD bufsize = 1024 * 100;//每次開辟10k的緩存存儲錄音數(shù)據(jù)
    int i = 10;
    fopen_s(&pf, "1.pcm", "wb");
    while (i--)//錄制20左右秒聲音,結(jié)合音頻解碼和網(wǎng)絡(luò)傳輸可以修改為實(shí)時錄音播放的機(jī)制以實(shí)現(xiàn)對講功能
    {
        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));//準(zhǔn)備一個波形數(shù)據(jù)塊頭用于錄音
        waveInAddBuffer(hWaveIn, &wHdr1, sizeof(WAVEHDR));//指定波形數(shù)據(jù)塊為錄音輸入緩存
        waveInStart(hWaveIn);//開始錄音
        Sleep(1000);//等待聲音錄制1s
        waveInReset(hWaveIn);//停止錄音
        fwrite(pBuffer1, 1, wHdr1.dwBytesRecorded, pf);
        delete pBuffer1;
        printf("%ds  ", i);
    }
    fclose(pf);

    simplest_pcm16le_to_wave("1.pcm", 1, 8000, "1.wav");

    waveInClose(hWaveIn);
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容