iOS將PCM數(shù)據(jù)文件轉(zhuǎn)換為WAV文件

最近學(xué)習(xí)寫wav文件,搞了很久,踩了不少坑。將PCM數(shù)據(jù)文件轉(zhuǎn)換為WAV文件其實就是在PCM數(shù)據(jù)前加上WAV的頭。只需要設(shè)置好碼率,聲道數(shù),采樣位數(shù)就可以了。從別人移植過來一段C代碼,發(fā)現(xiàn)在iOS各種設(shè)備平臺上還有兼容性的問題,簡單的修改了一下,經(jīng)過幾次測試,發(fā)現(xiàn)沒什么問題了,分享給大家。

//wav頭的結(jié)構(gòu)如下所示:

typedef  struct  {

char        fccID[4];

int32_t      dwSize;

char        fccType[4];

} HEADER;

typedef  struct  {

char        fccID[4];

int32_t      dwSize;

int16_t      wFormatTag;

int16_t      wChannels;

int32_t      dwSamplesPerSec;

int32_t      dwAvgBytesPerSec;

int16_t      wBlockAlign;

int16_t      uiBitsPerSample;

}FMT;

typedef  struct  {

char        fccID[4];

int32_t      dwSize;

}DATA;

int convertPcm2Wav(char *src_file, char *dst_file, int channels, int sample_rate)

{

int bits = 16;

//以下是為了建立.wav頭而準備的變量

HEADER  pcmHEADER;

FMT  pcmFMT;

DATA  pcmDATA;

unsigned  short  m_pcmData;

FILE  *fp,*fpCpy;

if((fp=fopen(src_file,  "rb"))  ==  NULL) //讀取文件

{

printf("open pcm file %s error\n", src_file);

return -1;

}

if((fpCpy=fopen(dst_file,  "wb+"))  ==  NULL) //為轉(zhuǎn)換建立一個新文件

{

printf("create wav file error\n");

return -1;

}

//以下是創(chuàng)建wav頭的HEADER;但.dwsize未定,因為不知道Data的長度。

strncpy(pcmHEADER.fccID,"RIFF",4);

strncpy(pcmHEADER.fccType,"WAVE",4);

fseek(fpCpy,sizeof(HEADER),1); //跳過HEADER的長度,以便下面繼續(xù)寫入wav文件的數(shù)據(jù);

//以上是創(chuàng)建wav頭的HEADER;

if(ferror(fpCpy))

{

printf("error\n");

}

//以下是創(chuàng)建wav頭的FMT;

pcmFMT.dwSamplesPerSec=sample_rate;

pcmFMT.dwAvgBytesPerSec=pcmFMT.dwSamplesPerSec*sizeof(m_pcmData);

pcmFMT.uiBitsPerSample=bits;

strncpy(pcmFMT.fccID,"fmt  ", 4);

pcmFMT.dwSize=16;

pcmFMT.wBlockAlign=2;

pcmFMT.wChannels=channels;

pcmFMT.wFormatTag=1;

//以上是創(chuàng)建wav頭的FMT;

fwrite(&pcmFMT,sizeof(FMT),1,fpCpy); //將FMT寫入.wav文件;

//以下是創(chuàng)建wav頭的DATA;  但由于DATA.dwsize未知所以不能寫入.wav文件

strncpy(pcmDATA.fccID,"data", 4);

pcmDATA.dwSize=0; //給pcmDATA.dwsize  0以便于下面給它賦值

fseek(fpCpy,sizeof(DATA),1); //跳過DATA的長度,以便以后再寫入wav頭的DATA;

fread(&m_pcmData,sizeof(int16_t),1,fp); //從.pcm中讀入數(shù)據(jù)

while(!feof(fp)) //在.pcm文件結(jié)束前將他的數(shù)據(jù)轉(zhuǎn)化并賦給.wav;

{

pcmDATA.dwSize+=2; //計算數(shù)據(jù)的長度;每讀入一個數(shù)據(jù),長度就加一;

fwrite(&m_pcmData,sizeof(int16_t),1,fpCpy); //將數(shù)據(jù)寫入.wav文件;

fread(&m_pcmData,sizeof(int16_t),1,fp); //從.pcm中讀入數(shù)據(jù)

}

fclose(fp); //關(guān)閉文件

pcmHEADER.dwSize = 0;  //根據(jù)pcmDATA.dwsize得出pcmHEADER.dwsize的值

rewind(fpCpy); //將fpCpy變?yōu)?wav的頭,以便于寫入HEADER和DATA;

fwrite(&pcmHEADER,sizeof(HEADER),1,fpCpy); //寫入HEADER

fseek(fpCpy,sizeof(FMT),1); //跳過FMT,因為FMT已經(jīng)寫入

fwrite(&pcmDATA,sizeof(DATA),1,fpCpy);  //寫入DATA;

fclose(fpCpy);  //關(guān)閉文件

return 0;

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容