#include <iostream>
using namespace std;
typedef struct WAV_HEADER
{
char chunkid[4];
unsigned long chunksize;
char format[4];
} pcmHeader;
typedef struct WAV_FMT
{
char subformat[4];
unsigned long sbusize;
unsigned short audioFormat;
unsigned short numchannels;
unsigned long sampleRate;
unsigned long byteRate;
unsigned long blockAlign;
unsigned long 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;
}
int pcvToWav(const char *pcmpath, int channels, int sample_tate, int fmtSize, const char* wavpath)
{
// 打开文件
FILE * fp, *fout;
fp = fopen(pcmpath, "rb");
if(fp== NULL) {
cout<<"fopen input failed"<<endl;
return -1;
}
pcmHeader header;
pcmFmt fmt;
pcmData data;
memcpy(header.chunkid, "RIFF", strlen("RIFF"));
header.chunksize = getFileSize((char *)pcmpath) + 44 -8;
memcpy(header.format, "WAVE", strlen("WAVE"));
memcpy(fmt.subformat, "fmt ", strlen("fmt "));
fmt.sbusize = fmtSize; //16位存储位宽
fmt.audioFormat = 1; //pcm数据为1
fmt.numchannels = channels;
fmt.bitPerSample = sample_tate;
fmt.byteRate = sample_tate * channels * 16 / 8;
fmt.blockAlign = channels * 16 /8;
fmt.bitPerSample = 16;
memcpy(data.wavdata, "data", strlen("data"));
data.dataSize = getFileSize((char*)pcmpath);
// 写入数据 1、写入头部信息 2、写入PCM数据
// 1、打开文件
fout = fopen(wavpath, "wb");
if (fout ==NULL){
cout<<"fopen out failed"<<endl;
return -1;
}
fwrite(&header,sizeof(header), 1,fout);
fwrite(&fmt,sizeof(fmt), 1,fout);
fwrite(&data,sizeof(data), 1,fout);
// 写入PCM文件
char* buff = (char*)malloc(512);
int len;
// 读取pcm的文件到buff中
while((len = fread(buff, sizeof(char), 512, fp)) != 0) {
fwrite(buff, sizeof(char), len, fout);
}
free(buff);
fclose(fp);
fclose(fout);
cout<<"finish"<<endl;
}
int main() {
pcvToWav("../audio.pcm",2,44100, 16,"../outfile.wav");
return 0;
}
需要学习的知识点
1、获取文件的字节长度使用的方法是 fseek(fp, 0, SEEK_END), ftell(fp);
2、字符串的拷贝常用的是memcy和strcy.
3、fwrite写入结构体的方式;
4、按照字符数组读取文件中fread与fwrite的使用。