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;
}