將PCM數(shù)據(jù)轉(zhuǎn)換成WAV文件其實(shí)只是加個(gè)文件頭。但要做給普通用戶用,界面比較費(fèi)時(shí)間。增加了單聲道、雙聲道選擇,樣本寬度,提供更多采樣率,并允許輸入采樣率。
實(shí)現(xiàn)原理:
wav文件通常包含4段:RIFF、格式段、FACT段和數(shù)據(jù)段。 PCM數(shù)據(jù)就放在數(shù)據(jù)段。只要格式段設(shè)置的格式與數(shù)據(jù)段的數(shù)據(jù)一致,播放程序就可以正確解析。 下面這個(gè)數(shù)組的數(shù)據(jù)其實(shí)就是一個(gè)最小的wav文件。
static const unsigned char wav_template[] = { // RIFF WAVE Chunk 0x52, 0x49, 0x46, 0x46, // "RIFF" 0x30, 0x00, 0x00, 0x00, // 總長(zhǎng)度 整個(gè)wav文件大小減去ID和Size所占用的字節(jié)數(shù) 0x57, 0x41, 0x56, 0x45, // "WAVE" // Format Chunk 0x66, 0x6D, 0x74, 0x20, // "fmt " 0x10, 0x00, 0x00, 0x00, // 塊長(zhǎng)度 0x01, 0x00, // 編碼方式 0x01, 0x00, // 聲道數(shù)目 0x80, 0x3E, 0x00, 0x00, // 采樣頻率 0x00, 0x7D, 0x00, 0x00, // 每秒所需字節(jié)數(shù)=采樣頻率*塊對(duì)齊字節(jié) 0x02, 0x00, // 數(shù)據(jù)對(duì)齊字節(jié)=每個(gè)樣本字節(jié)數(shù)*聲道數(shù)目 0x10, 0x00, // 樣本寬度 // Fact Chunk 0x66, 0x61, 0x63, 0x74, // "fact" 0x04, 0x00, 0x00, 0x00, // 塊長(zhǎng)度 0x00, 0xBE, 0x00, 0x00, // Data Chunk 0x64, 0x61, 0x74, 0x61, // "data" 0x00, 0x00, 0x00, 0x00, // 塊長(zhǎng)度 };
這個(gè)wav文件的數(shù)據(jù)長(zhǎng)度為0。我們要增加PCM數(shù)據(jù)只要完成以下工作:
在數(shù)據(jù)段尾增加PCM數(shù)據(jù);
修改數(shù)據(jù)段的塊長(zhǎng)度,修改RIFF段的總長(zhǎng)度;
正確設(shè)置格式段的PCM參數(shù)。
樣本長(zhǎng)度可能不是8的整數(shù)倍,這時(shí)wav文件還是要求樣本按照字節(jié)對(duì)齊。在一個(gè)樣本中數(shù)據(jù)是左對(duì)齊的,右側(cè)空位用0填充。 pcm2wav只考慮了樣本長(zhǎng)度是16位的情況。
如果有多個(gè)聲道,wav文件要求先放樣本1的各聲道數(shù)據(jù),再放樣本2的各聲道數(shù)據(jù),依此類推。 因?yàn)槲覜](méi)有碰到過(guò)處理多聲道數(shù)據(jù)的需求,所以pcm2wav只考慮了單聲道。