【數據壓縮】WAV PCM FORMAT

       WAV文件是微軟公司開發的一種聲音文件格式,大部分的WAV文件中的音頻數據是直接通過PCMPulse Code Modulation)脈衝編碼調製得到的樣本數據,由於未被壓縮或壓縮比很小所以其質量較高,但同時數據量也很大。在數字領域,存儲音頻文件的最直接方式就是在滿足奈奎斯特抽樣定理的條件下,將模擬的音頻文件進行抽樣量化,將得到的一系列樣本值以二進制形式存儲在文件中,這就是PCM脈衝編碼調製的大致步驟。儘管大部分的WAV文件存儲的都是未經壓縮的,但它也支持一些音頻壓縮方法。

      那麼如何將模擬的音頻變成存儲在電腦中的二進制數據呢?首先是選定抽樣頻率,對模擬音頻進行抽樣使得其在時間域是離散的,再將抽樣值進行量化。WAV文件對每個抽樣值的量化比特數沒有具體規定,但固定在存儲時每個樣本值由整數個字節來表示,因此每個樣本值的比特數均應該爲8bit的整數倍如8bit16bit24bit32bit等。當某個樣本值的比特數不是8bit的整數倍時,則需要將其左移並再低位填充0使其變成8bit的整數倍。例如某個抽樣量化後的樣本值爲1011000101,則存儲時需要將其補010110001 01000000,再採用小端序(先存低字節,再存高字節,默認存儲方式)的方式進行存儲,最終該樣值被存爲B1 40。一個需要注意的小細節是在 WAV文件中,8bit的是unsigned 類型的無符號數據,但16bit或更高的量化級的都是signed 類型的有符號數

      將模擬音頻轉化爲二進制的數據後,要想將其存儲在電腦中需要考慮其數據組織的形式,這樣在後續對文件進行操作時會更加方便。WAV文件是一種基於RIFF規範的音頻文件格式。RIFFResource Interchange File Format)是一種自包含的文件組織格式,它的基本單位是Chunk,一個基於RIFF規範的文件是由若干個Chunk組成的。

Chunk:

1.基本格式:

struct chunk

{

u32   chunk_id;             /* 塊標誌 */

u32   chunk_size;          /* 塊大小*/

u8      data[chunk_size]; /* 塊內容*/

};

chunk_id是一個4字節的ASCII標識符,用來標識該Chunk中的數據,不足四字節的再末尾用空位佔位。可以有:'RIFF','LIST','fmt ','data','WAV ','AVI '等,採用小端序。

chunk_size也是四字節,存儲的是data中的數據長度(以字節爲單位),不包括chunk_idchunk_size本身所佔的內存單元。

data[chunk_size]:該Chunk中的數據,必須爲偶數個字節,若長度爲奇數則在最後添一個空字節。

2.各種子類:

Chunk有多種子類,其中兩種類型爲“RIFF”和“LIST”的兩種Chunk可以包含其他塊,其他的Chunk則只能有數據。

RIFF/LIST”子類格式如下:

struct chunk

{

u32   chunk_ id;                   /* 塊標誌 */

u32   chunk_size;                 /* 塊大小 ,由於此時的data部分分爲typerestdata兩部分,所以chunk_size應該爲typerestdata數據長度之和*/

u32    type;                           /* 類型 */

u8      restdata[chunk_size-4] /* data中除了type4個字節後的數據,可以有包含的其他Chunk的數據 */

};

 

WAV文件格式:

一個WAV文件就是一個RIFF文件。其組成方式爲:一個RIFF Chunk,其type爲“WAVE”,其restdata部分包含了兩個Chunk分別爲“fmt Chunk和“data Chunk

其詳細的結構如下:

ChunkID:四字節,“RIFF”(ASCII字符)

ChunkSize:四字節,表示該WAV文件除去ChunkID和ChunkSize之外的所有數據長度的總和,等於Format長度+SubChunk1長度(綠色部分)+Subchunk2長度(橙色部分),即4+4+4+Subchunk Size+4+4+Subchunk2 Size=4+24+8+Subchunk2 Size=36+Subchunk2 Size,由於只能用4字節來表示文件的大小,因此WAV文件限制在4GB內(有的程序限制其大小爲2GB)

Format:四字節,,表示該RIFF文件的類型,此處爲:“WAVE”(ASCII字符)

Subchunk1ID:四字節,“fmt ”(注意末尾有一個空格佔位,因爲一個Chunk的ID必須爲四位的ASCII字符)

Subchunk1Size:四字節,“fmt”chunk除去Subchunk1ID和Subchunk1Size之外的所有數據長度之和,爲2+2+4+4+2+2=16

AudioFormat:兩字節,表示音頻數據的編碼方式,PCM=1,若不爲1則表示其他的數據編碼方式,其值所代表的詳細編碼方式可以見文章末尾;

NumChannels:兩字節,表示聲道數,Mono = 1,Stereo = 2等

SampleRate:四字節,採樣率,常見的採樣率有8000,44100等(單位爲Hz);

ByteRate:四字節,表示一秒鐘內的音頻信號數據需要多少個字節來存儲,爲SampleRate* NumChannels * BitsPerSample/8

BlockAlign:兩字節,表示每一時刻的音頻信號的抽樣值需要幾個字節來表示,爲NumChannels* BitsPerSample/8

BitsPerSample:兩字節,表示量化比特數,8bits = 8, 16 bits = 16等;

(若該音頻文件不是PCM 編碼,則其fmt chunk後還會有一些其他的參數)

Subchunk2 ID:四字節,“data”ASCII字符);

Subchunk2 Size:四字節,data部分數據的長度,若爲奇數則在末尾添加空字節使得長度爲偶數;

DataSubchunk2Size個字節,實際的聲音數據。


下面是舉例說明一個WAV文件中的數據(只列舉了文件的前72字節):

其顏色與上面的結構圖相對應。由圖可知該WAV文件是雙聲道、16bit量化的,因此某一時刻的樣本值由四字節來表示。文件的音頻信號樣值若爲多聲道,其值是交叉排列的,例如雙聲道爲:左聲道樣值、右聲道樣值、左聲道樣值、右聲道樣值……如此排列,多聲道同理。


Audio Format這個參數的值,可以得知WAV文件中音頻數據的編碼方式,下列是目前WAV文件支持的編碼方式:

Code      Description
0 (0x0000)
      Unknown
1 (0x0001)
       PCM/uncompressed
2 (0x0002)
      Microsoft ADPCM
6 (0x0006)
      ITU G.711 a-law
7 (0x0007)
      ITU G.711 µ-law
17 (0x0011)
      IMA ADPCM
20 (0x0016)
     ITU G.723 ADPCM (Yamaha)
49 (0x0031)
     GSM 6.10
64 (0x0040)
     ITU G.721 ADPCM
80 (0x0050)
     MPEG
65,536 (0xFFFF)
 Experimental

 

本文參考網址:

http://www.codeguru.com/cpp/g-m/multimedia/audio/article.php/c8935/PCM-Audio-and-Wave-Files.htm

http://soundfile.sapp.org/doc/WaveFormat/

 

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