WAV文件的编码
编码包括了两方面内容,一是按一定格式存储数据,二是采用一定的算法压缩数据。WAV格式对音频流的编码没有硬性规定,支持非压缩的PCM(Puls Code Modulation)脉冲编码调制格式,还支持压缩型的微软自适应分脉冲编码调制Microsoft ADPCM(Adaptive Differential Puls Code Modulation)、国际电报联盟(International Telegraph Union)制定的语音压缩标准ITUG.711 a-law、ITU G.711-law、IMA ADPCM、ITU G.723 ADPCM (Yamaha)、GSM 6.10、ITU G.721 ADPCM编码和其它压缩算法。MP3编码同样也可以运用在WAV中,只要安装相应的Decode,就可以播放WAV中的MP3音乐。
代码
#include <iostream>
using namespace std;
typedef struct WAV_HEADER {
char chunkid[4];
unsigned long chunksize;//long 4字节
char format[4];
}pcmHeader;
typedef struct WAV_FMT {
char subformat[4];
unsigned long sbusize;
unsigned short audioFormat;//short 两字节
unsigned short numchannels;
unsigned long sampleRate;
unsigned long byteRate;
unsigned short blockAlign;
unsigned short bitPerSample;
}pcmFmt;
typedef struct WAV_DATA {
char wavdata[4];
unsigned long dataSize;
}pcmData;
long getFileSize(char* filename)
{
FILE* fp = fopen(filename, "r");//只读
if (!fp) {
return -1;
}
fseek(fp, 0, SEEK_END);//指向最后字节
long size = ftell(fp);//返回文件字节长度
fclose(fp);
return size;
}
//pcm 中没有指定信息 通道数 采样率 需要传入
int pcvToWav(const char* pcmpath, int channles, int sample_rate, int fmtsize, const char* wavpath)
{
FILE* fp, *fpout;
WAV_HEADER pcmHeader;
WAV_FMT pcmFmt;
WAV_DATA pcmData;
int bits = 16;
//打开pcm 文件 二进制方式读
fp = fopen(pcmpath, "rb");
if (fp == NULL)
{
cout << "fopen failed" << endl;
return -1;
}
//
memcpy(pcmHeader.chunkid, "RIFF", strlen("RIFF"));//
long fileSize = 44 + getFileSize((char*)pcmpath) - 8;
pcmHeader.chunksize = fileSize;//wavÎļþС
memcpy(pcmHeader.format, "WAVE", strlen("WAVE"));//
//
memcpy(pcmFmt.subformat, "fmt ", strlen("fmt "));//
pcmFmt.sbusize = fmtsize;//存储位宽
pcmFmt.audioFormat = 1;//
pcmFmt.numchannels = channles; //
pcmFmt.sampleRate = sample_rate;//采样率
pcmFmt.byteRate = sample_rate * channles * bits / 8;//码率 1s中传输的数据字节
pcmFmt.blockAlign = channles * bits / 8;//
pcmFmt.bitPerSample = bits;//
//
memcpy(pcmData.wavdata, "data", strlen("data"));//
pcmData.dataSize = getFileSize((char*)pcmpath);
//
fpout = fopen(wavpath, "wb");
if (fpout == NULL)
{
cout << "fopen failed" << endl;
return -1;
}
//
fwrite(&pcmHeader, sizeof(pcmHeader), 1, fpout);
fwrite(&pcmFmt, sizeof(pcmFmt), 1, fpout);
fwrite(&pcmData, sizeof(pcmData), 1, fpout);
//
char* buff = (char*)malloc(512);
int len;
//
while ((len = fread(buff, sizeof(char), 512, fp)) != 0) {
fwrite(buff, sizeof(char), len, fpout);
}
free(buff);
fclose(fp);
fclose(fpout);
}
int main()
{
pcvToWav("audio.pcm", 2, 44100, 16, "outdio.wav");
return 0;
}