PCM文件转WAV的实现

#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的使用。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值