<pre class="cpp" name="code">pcm文件轉wav文件時,主要是在pcm文件加入wav的頭。wav的文件頭包含wav標示及解碼標示。<p>下面的一段代碼爲將8k,16bit,PCM(Intel(LSB,MSB)未加壓縮的轉wav文件。</p>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
//讀文件,返回內存指針,記得free
void* ReadFile(const char *path, unsigned int *len)
{
FILE *f = fopen(path, "rb");
if (f == NULL)
return NULL;
fseek(f, 0, SEEK_END);
*len = ftell(f);
fseek(f, 0, SEEK_SET);
void *buffer = malloc(*len);
*len = fread(buffer, 1, *len, f);
fclose(f);
return buffer;
}
//pcm轉wav,返回wav內存指針和wav長度
void* pcmToWav(const void *pcm, unsigned int pcmlen, unsigned int *wavlen)
{
//44字節wav頭
void *wav = malloc(pcmlen + 44);
//wav文件多了44個字節
*wavlen = pcmlen + 44;
//添加wav文件頭
memcpy(wav, "RIFF", 4);
*(int *)((char*)wav + 4) = pcmlen + 36;
memcpy(((char*)wav + 8), "WAVEfmt ", 8);
*(int *)((char*)wav + 16) = 16;
*(short *)((char*)wav + 20) = 1;
*(short *)((char*)wav + 22) = 1;
*(int *)((char*)wav + 24) = 8000;
*(int *)((char*)wav + 28) = 16000;
*(short *)((char*)wav + 32) = 16 / 8;
*(short *)((char*)wav + 34) = 16;
strcpy((char*)((char*)wav + 36), "data");
*(int *)((char*)wav + 40) = pcmlen;
//拷貝pcm數據到wav中
memcpy((char*)wav + 44, pcm, pcmlen);
return wav;
}
//pcm文件轉wav文件,pcmfilePath:pcm文件路勁,wavfilePath:生成的wav路勁
int pcmfileToWavfile(const char *pcmfilePath, const char *wavfilePath)
{
unsigned int pcmlen;
//讀取文件獲得pcm流,也可以從其他方式獲得
void *pcm = ReadFile(pcmfilePath, &pcmlen);
if (pcm == NULL)
{
printf("not found file\n");
return 1;
}
//pcm轉wav
unsigned int wavLen;
void *wav = pcmToWav(pcm, pcmlen, &wavLen);
FILE *fwav = fopen(wavfilePath, "wb");
fwrite(wav, 1, wavLen, fwav);
fclose(fwav);
free(pcm);
free(wav);
return 0;
}
int main(int argc,char *argv[])
{
if(argc<3) return 1;
if(strstr(argv[1],".pcm")==NULL) return 1;
if(strstr(argv[2],".wav")==NULL) return 1;
int ret = pcmfileToWavfile(argv[1],argv[2]);
if (ret != 0)
{
printf("error pcm to wav\n");
}
else
{
printf("succ");
}
}
比如將這段代碼複製到一個文件中,該文件名字爲pcm2wav.cpp。將其編譯。
g++ pcm2wav.cpp -o pcm2wav
./pcm2wav /home/20160630102824.pcm /20160630102824.wav