close
簡單的理解AAC之後, 我們來了解一下WAV; 其實我本來打算把這個放到稍微後面一些, 但我自己也想驗證一下弄出來的PCM是不是正確的, 所以才有了這一篇的誕生;
什麼是WAV? 或以WAVE為副檔名的檔案是什麼? 它是一種標準聲音格式檔,主要用於Windows作業系統,通常都是未經壓縮的聲音檔,但它也支援音訊壓縮. 而這個格式屬於資源交換檔案格式(RIFF)的應用之一, 通常會採用脈波編碼變調(PCM)的音訊儲存在裡面, 也是市面上很常出現的規格之一.
接下來讓我們看看格式, 格式的話前44bytes 會放檔案的header, 這樣就可以使播放器能夠簡單知道檔案的基本資訊, 以下為格式, ( 出自WIKI )
註:上圖描述有誤,「位元組率」實際應為「=取樣頻率*位元深度*聲道數量/8」(圖片中漏乘了聲道數量),它代表每秒鐘資料的位元組數。
接下來我們來寫寫程式吧,
#define PCMFileName "PCMFile.pcm"
#define WAVFileName "WAVFile.wav"
PCMToWav(PCMFileName, 2, 44100, 16, WAVFileName);
int CFFmpegAudioDlg::PCMToWav
(
const char* pcmpath ,
int channles ,
int sample_rate ,
int fmtsize ,
const char* wavpath
)
{
FILE* fp, *fpout;
WAV_HEADER pcmHeader;
WAV_FMT pcmFmt;
WAV_DATA pcmData;
int bits = 16;
fp = fopen(pcmpath, "rb");
if (fp == NULL)
{
AppendText(L"fopen failed\r\n");
return -1;
}
memcpy(pcmHeader.chunkid, "RIFF", strlen("RIFF"));
long fileSize = 44 + getFileSize((char*)pcmpath) - 8;
pcmHeader.chunksize = fileSize;
memcpy(pcmHeader.format, "WAVE", strlen("WAVE"));
//
memcpy(pcmFmt.subformat, "fmt ", strlen("fmt "));
pcmFmt.sbusize = fmtsize;
pcmFmt.audioFormat = 1;
pcmFmt.numchannels = channles;
pcmFmt.sampleRate = sample_rate;
pcmFmt.byteRate = sample_rate * channles * bits / 8;
pcmFmt.blockAlign = channles * bits / 8;
pcmFmt.bitPerSample = bits;
memcpy(pcmData.wavdata, "data", strlen("data"));
pcmData.dataSize = getFileSize((char*)pcmpath);
fpout = fopen(wavpath, "wb");
if (fpout == NULL)
{
AppendText(L"fopen failed\r\n");
return -1;
}
fwrite(&pcmHeader, sizeof(pcmHeader), 1, fpout);
fwrite(&pcmFmt, sizeof(pcmFmt), 1, fpout);
fwrite(&pcmData, sizeof(pcmData), 1, fpout);
char* buff = (char*)malloc(512);
int len;
while ((len = fread(buff, sizeof(char), 512, fp)) != 0) {
fwrite(buff, sizeof(char), len, fpout);
}
free(buff);
fclose(fp);
fclose(fpout);
AppendText(L"PCM to WAV Success!\r\n");
return 0;
}
全站熱搜