如何將Pcm格式的音頻文件轉換成Wave格式的文件


最近在做一款變聲App,其中就用到了將pcm格式轉wave格式,下面貼出源代碼,希望帶有需求的童鞋有幫助!!!這里是c++語言寫的,也可以用java實現。當然java調用native函數要用到jni技術。具體jni技術自己到網路上找找資料。

Cpp文件Pcm2Wave.cpp

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "wave.h"
#include "constant.h"

class Pcm2Wave
{
private: 
    WAVE_HEAD wave_head;
    FILE* src_pcm_file;
    FILE* dest_wave_file;
public:
    Pcm2Wave()
    { 
        memcpy(&wave_head.riff_char, "RIFF", 4);
        memcpy(&wave_head.wave, "WAVE", 4);
        memcpy(&wave_head.fmt, "fmt ", 4);
        memcpy(&wave_head.fccID, "fact", 4);
        memcpy(&wave_head.data_field, "data", 4);
        wave_head.package_len = 0;
        wave_head.format_len = 16;
        wave_head.fixed =  1;
        wave_head.channel_number = 1;
        //  采樣率 long int samplespersec
        wave_head.sample_rate = 8000 ;
    
        // 量化數 int bitpersamples=8或16
        wave_head.bits_per_sample = 16;
        //  采樣一次占字節數 int blockalig
        wave_head.byte_per_sample = wave_head.channel_number *  wave_head.bits_per_sample / 8; //NumChannels * BitsPerSample/8
           //  每秒播放字節數 long int bytepersec
        wave_head.byte_rate =     wave_head.sample_rate * wave_head.channel_number * wave_head.bits_per_sample / 8; //SampleRate * NumChannels * BitsPerSample /8
        
        
        wave_head.id = 4;
        wave_head.dwSize = 0;
        
        wave_head.data_len = 0;
    }
    
    Pcm2Wave(WAVE_HEAD* pwave_head)
    {
        if(pwave_head != NULL)
        {
            memcpy(&wave_head, pwave_head, sizeof(*pwave_head));
        }
    }
    

    ~Pcm2Wave()
    {}


    void set_channel(short pchannel_number)
    {
        wave_head.channel_number = pchannel_number;
        wave_head.byte_per_sample = wave_head.channel_number *  wave_head.bits_per_sample / 8;
        wave_head.byte_rate =     wave_head.sample_rate * wave_head.channel_number * wave_head.bits_per_sample / 8;
    }
    
    void set_sample_rate(int  psample_rate)
    {
        wave_head.sample_rate = psample_rate;
        wave_head.byte_rate =     wave_head.sample_rate * wave_head.channel_number * wave_head.bits_per_sample / 8;
    }
    
    void set_bits_per_sample(short pbits_per_sample)
    {
        wave_head.bits_per_sample =   pbits_per_sample;
        wave_head.byte_per_sample = wave_head.channel_number *  wave_head.bits_per_sample / 8;
        wave_head.byte_rate =     wave_head.sample_rate * wave_head.channel_number * wave_head.bits_per_sample / 8;
    }
    
    
    int change(const char *srcfile, const char *dsetfile)
    {
        int nFileLen = 0;
        int nSize = sizeof(wave_head);
        printf("wave的頭的大小: %d\n", nSize);
        src_pcm_file = NULL;
        dest_wave_file = NULL;
        src_pcm_file = fopen(srcfile, "rb");
        if (src_pcm_file == NULL)
            return -1;
        
        dest_wave_file = fopen(dsetfile, "wb+");
        if (dest_wave_file == NULL)
            return -2;
        
        
        int nWrite = fwrite(&wave_head, 1, nSize, dest_wave_file);
        if (nWrite != nSize)
        {
            fclose(src_pcm_file);
            fclose(dest_wave_file);
            return -3;
        }
        
        while( !feof(src_pcm_file))
        {
            char readBuf[4096];
            int nRead = fread(readBuf, 1, 4096, src_pcm_file);
            if (nRead > 0)
            {
                fwrite(readBuf, 1, nRead, dest_wave_file); 
            }
            
            nFileLen += nRead;
        }
        printf("文件指針位置: %d\n", ftell(dest_wave_file));
        //將目的文件的游標指針指向文件的開頭
        printf("nFileLen的大小: %d\n nSize的大小:%d\n", nFileLen, nSize);
        fseek(dest_wave_file, 0, SEEK_SET);
        
        wave_head.package_len = nFileLen - 8 + nSize;
        wave_head.data_len = nFileLen;
        nWrite = fwrite(&wave_head, 1, nSize, dest_wave_file);
        if (nWrite != nSize)
        {
            fclose(src_pcm_file);
            fclose(dest_wave_file);
            return -4;
        }
        fclose(src_pcm_file);
        fclose(dest_wave_file);
        
        return 0;        
    }
    
};


int main(char args [])
{
    Pcm2Wave pp;
    pp.set_sample_rate(11025);
    pp.change("jj.pcm", "jj.wav");
    return 0 ;
}

wave.h頭文件

typedef struct WAVE_HEAD
{
    char riff_char[4];   // "RIFF" char riff_id[4]="RIFF"
    int package_len ;    //文件總長-8 long int size0=文總長-8
    char wave[4];
    char fmt[4];
    int format_len;   
    short fixed;      //  fmttag=0x01
    short channel_number;  //  channel=1 或2
    int   sample_rate;   //  采樣率 long int samplespersec
    int   byte_rate;   //  每秒播放字節數 long int bytepersec
    short byte_per_sample;   //  采樣一次占字節數 int blockalign=聲道數*量化數/8
    short bits_per_sample;   // 量化數 int bitpersamples=8或16
    char fccID[4]; // must be "fact"
    int  id; // must be 0x4
    int dwSize; // 暫時沒發現有啥用
    char  data_field[4];   //  data_id="data"
    int  data_len;  //  采樣數據字節數 long int size2=文長-44
    
} WAVE_HEAD;

 


免責聲明!

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



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