最近在做一款變聲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;