FFMpeg音頻混合,背景音(四):用原始c++讀寫方式將pcm轉換成wav


一、思路

    將未經過編碼壓縮的pcm格式文件,加上44字節的文件頭即可。其他數據直接寫到新文件。

#include <iostream>
using namespace std;
//wav的頭部第一部分
typedef struct WAV_HEADER {
    char chunkid[4];
    unsigned long chunksize;
    char format[4];
}pcmHeader;
//wav的頭部第二部分,保存着文件的采樣率、通道數、碼率等等一些基礎參數
typedef struct WAV_FMT {
    char subformat[4];
    unsigned long sbusize;
    unsigned short audioFormat;
    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;
}
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;
    //打開輸入的文件流
    fp = fopen(pcmpath, "rb");
    if (fp == NULL)
    {
        cout << "fopen failed" << endl;
        return -1;
    }
    //第一部分
    memcpy(pcmHeader.chunkid, "RIFF", strlen("RIFF"));//字符REFF
    long fileSize = 44 + getFileSize((char*)pcmpath) - 8;
    pcmHeader.chunksize = fileSize;//wav文件小
    memcpy(pcmHeader.format, "WAVE", strlen("WAVE"));//字符WAVE
    //第二部分
    memcpy(pcmFmt.subformat, "fmt ", strlen("fmt "));//字符串fmt 
    pcmFmt.sbusize = fmtsize;//存儲位寬
    pcmFmt.audioFormat = 1;//pcm數據標識
    pcmFmt.numchannels = channles; //通道數
    pcmFmt.sampleRate = sample_rate;//采樣率
    pcmFmt.byteRate = sample_rate * channles * bits / 8;//每秒傳遞的比特數
    pcmFmt.blockAlign = channles * bits / 8;
    pcmFmt.bitPerSample = bits;//樣本格式,16位。
    //第三部分
    memcpy(pcmData.wavdata, "data", strlen("data"));//字符串data
    pcmData.dataSize = getFileSize((char*)pcmpath);//pcm數據長度
    //打開輸出的文件流
    fpout = fopen(wavpath, "wb");
    if (fpout == NULL)
    {
        cout << "fopen failed" << endl;
        return -1;
    }
    //寫入wav頭部信息44個字節
    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;
    //讀取pcm數據寫入wav文件
    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");
    //cout << sizeof(long) << endl;
    //cout << sizeof(short) << endl;
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM