输入音PCM 属性: 16k采样率 16位深 单声道
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
/* wav音频头部格式 */
typedef struct _wave_pcm_hdr
{
char riff[4]; // = "RIFF"
int size_8; // = FileSize - 8
char wave[4]; // = "WAVE"
char fmt[4]; // = "fmt "
int fmt_size; // = 下一个结构体的大小 : 16
short int format_tag; // = PCM : 1
short int channels; // = 通道数 : 1
int samples_per_sec; // = 采样率 : 8000 | 6000 | 11025 | 16000
int avg_bytes_per_sec; // = 每秒字节数 : samples_per_sec * bits_per_sample / 8
short int block_align; // = 每采样点字节数 : wBitsPerSample / 8
short int bits_per_sample; // = 量化比特数: 8 | 16
char data[4]; // = "data";
int data_size; // = 纯数据长度 : FileSize - 44
} wave_pcm_hdr;
/* 默认wav音频头部数据 */
wave_pcm_hdr default_wav_hdr =
{
{ 'R', 'I', 'F', 'F' },
0,
{'W', 'A', 'V', 'E'},
{'f', 'm', 't', ' '},
16,
1,
1,
16000,
32000,
2,
16,
{'d', 'a', 't', 'a'},
0
};
int main()
{
// 读取文件
filebuf* pbuf;
ifstream filestr;
int size;
// 要采用二进制方式打开
filestr.open("in.pcm", ios::binary);
if (!filestr.is_open())
{
cout << "in file open failed !"<<endl;
return -1;
}
// 获取filestr对应buffer对象的指针
pbuf = filestr.rdbuf();
// 调用buffer对象方法获取文件大小
size = pbuf->pubseekoff(0, ios::end, ios::in);
pbuf->pubseekpos(ios::beg, ios::in);
// 加载文件中数据到内存进行wav重组
// 打开输出文件
ofstream fileOutWav;
fileOutWav.open("out.wav", ios::binary | ios::out);
if (!fileOutWav.is_open())
{
cout << "out file open failed !"<<endl;
return -1;
}
//定义wav头,写入文件
wave_pcm_hdr wav_hdr = default_wav_hdr;
wav_hdr.data_size = size; //pcm 大小
wav_hdr.size_8 = wav_hdr.data_size + (sizeof(wav_hdr) - 8);
fileOutWav.write((char *)&wav_hdr, sizeof(wav_hdr)) ;
char mem_data[1] = {0};
for (int i = 0; i <= size; i++)
{
//读取pcm 到内存
pbuf->sgetn(mem_data, 1);
//写入wav文件
fileOutWav.write(mem_data,1);
}
filestr.close();
fileOutWav.close();
}