1.获取pcm文件:
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "winmm.lib")
HWAVEIN hWaveIn; //输入设备
WAVEFORMATEX waveform; //采集音频的格式,结构体
BYTE *pBuffer1;//采集音频时的数据缓存
WAVEHDR wHdr1; //采集音频时包含数据缓存的结构体
FILE *pf;
int main()
{
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 = 10;
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;
}
2.pcm转wav
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "winmm.lib")
HWAVEIN hWaveIn; //输入设备
WAVEFORMATEX waveform; //采集音频的格式,结构体
BYTE *pBuffer1;//采集音频时的数据缓存
WAVEHDR wHdr1; //采集音频时包含数据缓存的结构体
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;//采样声道数,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 = 10;
fopen_s(&pf, "1.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);
simplest_pcm16le_to_wave("1.pcm", 1, 8000, "1.wav");
waveInClose(hWaveIn);
return 0;
}
3.录音转为pcm再转为wav:
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "winmm.lib")
HWAVEIN hWaveIn; //输入设备
WAVEFORMATEX waveform; //采集音频的格式,结构体
BYTE *pBuffer1;//采集音频时的数据缓存
WAVEHDR wHdr1; //采集音频时包含数据缓存的结构体
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;//采样声道数,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 = 10;
fopen_s(&pf, "1.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);
simplest_pcm16le_to_wave("1.pcm", 1, 8000, "1.wav");
waveInClose(hWaveIn);
return 0;
}
网友评论