Wave(.wav)文件格式

Wave文件格式主要是用來存儲音頻PCM數據的,其實也可以存儲非PCM音頻數據,這種情況我們就不考慮了。文件的擴展名爲“.wav”,採用RIFF文件結構。

一、RIFF文件格式簡介

1、RIFF文件是由一個一個的chunk組成的,並且chunk之間可以嵌套。使用小端存儲。

2、chunk的基本結構如下:

struct chunk
{
    char   chunkId[4];       // 4個字符組成的chunk標識,少於4字符右補空格
    U32    chunkSize;        // 數據塊的大小,字節
    char   data[chunkSize]
};

chunkId可以爲"RIFF"、"LIST"、"fmt"、"data"...

3、當chunkId爲"RIFF"或"LIST"(類型塊)時,chunk的結構變形爲下面這樣:

struct chunk
{
    char    chunkId[4];    // 4字符組成的chunk標識,少於4字符右補空格
    U32     chunkSize;     // chunkType + data的數據大小,字節
    char    chunkType[4];  // chunk的類型,e.g. WAVE/AVI...
    char    data[chunkSize - 4]
};

二、Wave文件格式

1、Wave文件採用RIFF文件格式,當然也就遵循RIFF文件結構。總體來看Wave文件是由多個chunk嵌套組成的。

Wave文件格式
字段 長度(B) 字段描述
chunk1 chunkId 4 第一個chunk的標識始終是"RIFF"
chunkSize 4 該chunk的數據大小,包括chunkType
chunkType 4 對於Wave文件chunk的類型爲"WAVE"
data chunk2 chunkId 4 Wave文件的第二個chunk標識爲"fmt"
chunkSize 4 該chunk的數據大小
data wFormatTag 2 音頻數據格式,0x0001表示PCM數據
nChannels 2 聲道數
nSamplesPerSec 4 採樣率,每秒採樣次數
nAvgBytesPerSec 4 每秒的音頻數據大小(B),聲道數*採樣率*每個採樣點的比特數/8
nBlockAlign 2 每個時刻的音頻數據塊大小(B),聲道數*每個採樣點的比特數/8
wBitsPerSample 2 每個採樣點(的幅值)用多少比特編碼(8 or 16)
chunk3 chunkId 4 Wave文件的第三個chunk的標識爲"data"
chunkSize 4 該chunk的數據大小
data PCM數據 chunkSize PCM數據

從上表可以看出:

(1) Wave文件最外層是一個標識爲"RIFF"的類型塊chunk1

(2) 在chunk1的data部分嵌套了2個chunk,即chunk2和chunk3

(3) chunk2的標識爲"fmt",在它的data部分存儲音頻的一些相關屬性

(4) chunk3的標識爲"data",在它的data部分存儲具體的音頻PCM數據

2、PCM數據存儲格式

3、用二進制方式打開.wav文件 驗證對Wave文件格式的理解

Windows 關機.wav

Wave測試文件我用的是C:\Windows\Media\Windows 關機.wav

二進制文本工具我用的是notepad++的Hex Editor插件,也可以用UltraEdit編輯器

爲了方便描述,我把Wave文件的各個字段進行了編號1-14,依次對應上面表格中的各個字段


1: 0x 52 49 46 46,4字節,"RIFF"的ASCII碼

對應chunk1的chunkId字段


2: 0x dc 95 02 00,4字節,由於RIFF文件格式採用小端存儲,所以轉換爲人們熟悉的字節序(大端)爲0x 00 02 95 dc,

                           再轉換爲十進制數爲169436,表示chunk1的數據大小爲169436字節。我們可以查看

                           Windows 關機.wav文件的大小爲169444字節,由於chunkId和chunkSize已經佔用8字節,

                           所以後面還有169436字節的數據。

對應chunk1的chunkSize字段


3: 0x 57 41 56 45,4字節,"WAVE"的ASCII碼

對應chunk1的chunkType字段


4: 0x 66 6d 74 20,4字節,"fmt "的ASCII碼,"fmt"不夠4個字符,所以右邊補空格。

對應chunk2的chunkId字段


5: 0x 10 00 00 00,4字節,同樣是小端存儲,轉換爲大端爲0x 00 00 00 10即十進制的16,

                                 表示chunk2的數據大小爲16字節。從上面表格可知,wFormatTag、nChannels、

                                 nSamplesPerSec、nAvgBytesPerSec、nBlockAlign、wBitsPerSample加起來剛好佔16字節。

對應chunk2的chunkSize字段


6: 0x 01 00,2字節,轉換爲大端爲0x 00 01,表示該Wave文件存儲的是音頻PCM數據。

 對應chunk2的data部分的wFormatTag字段


7: 0x 02 00,2字節,轉換爲大端爲0x 00 02即十進制的2,表示音頻聲道數爲2即雙聲道。

對應chunk2的data部分的nChannels字段


8: 0x 44 ac 00 00,4字節,轉換爲大端爲0x 00 00 ac 44即十進制的44100,表示音頻採樣率爲44100Hz。

 對應chunk2的data部分的nSamplesPerSec字段


9: 0x 10 b1 02 00,4字節,轉換爲大端爲0x 00 02 b1 10即十進制的176400,

                                 表示每秒的音頻數據大小爲176400B。用公式”聲道數*採樣率*每個採樣點的比特數/8”

                                 計算得到的剛好就是176400即2 * 44100 * 16 / 8 = 176400

 對應chunk2的data部分的nAvgBytesPerSec


10: 0x 04 00,2字節,轉換爲大端爲0x 00 04即十進制的4,表示每個時鐘(有2個採樣點)的音頻數據有4B大小。

                         它的值等於”聲道數*每個採樣點的比特數/8”即2 * 16 / 8 = 4

對應chunk2的data部分的nBlockAlign字段


11: 0x 10 00,2字節,轉換爲大端爲0x 00 10即十進制的16,表示每個採樣值用16比特編碼。

對應chunk2的data部分的wBitsPerSample字段


12: 0x 64 61 74 64,4字節,"data"的ASCII碼

對應chunk3的chunkId字段


13: 0x b8 95 02 00,4字節,轉換爲大端爲0x 00 02 95 b8即十進制的169400,

                                   表示chunk3的data部分的數據大小即PCM音頻數據的大小

對應chunk3的chunkSize字段


14: 音頻PCM數據即chunk3的data

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章