如何将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;