Wave檔案格式


Wave檔案格式( Waveform Audio File Format )
WAVE檔案是多媒體中最常用的數字化聲音檔案格式之一,它是微軟專門為Windows系統定義的波形檔案(Waveform Audio),故又稱為波形聲音檔案,其擴展名為"*.wav"
WAVE檔案是以RIFF格式(Resource Interchange File Format,資源交互檔案格式)為標準的,每個WAVE檔案的頭四個位元組便是"RIFF"。而常見聲音檔案主要有2種,分別是分別對應於單聲道(11.025KHz取樣頻率、8Bit的取樣值)和雙聲道(44.1KHz取樣頻率、16Bit的取樣值)。取樣率是指:聲音信號在「類比→數位」轉換過程中單位時間內取樣的次數。取樣值是指每一次取樣週期內聲音類比信號的積分值。
WAVE檔案是由若干個Chunk組成的。按照在檔案中的出現位置包括:RIFF Type  ChunkFormat ChunkFact ChunkData Chunk。其中除了Fact Chunk外,其他三個Chunk是必須的。每個Chunk有各自的ID,位於Chunk最開始位置,作為標示,而且均為4個位元組。並且緊跟在ID後面的是Chunk大小(去除IDSize所佔的位元組數後剩下的其他位元組數目),4個位元組表示,低位元組表示數值低位元元,高位元組表示數值高位元。Chunk相對位置及具體結構介紹如下表五、表六所示:
     表五、WAVE檔案包含之Chunk位置關係
RIFF Type Chunk
Format Chunk
Data Chunk



表六、WAVE檔案包含之Chunk結構內容介紹
Chunk name
offest
size
Description
Value
RIFF Chunk
(12 Bytes)
0x00
4
ChunkID
"RIFF" (0x52494646)
0x04
4
Chunk Data Size
(file size) - 8
0x08
4
RIFF Type
"WAVE" (0x57415645)
Format Chunk
0x00
4
ChunkID
"fmt " (0x666D7420)
0x04
4
Chunk Data Size
16 + extra format bytes
0x08
2
Compression code
1 - 65535(PCM16)
0x0a
2
Number of channels
1 - 65535
0x0c
4
Sample rate
1 - 0xFFFFFFFF
0x10
4
Average bytes per second
1 - 0xFFFFFFFF
0x14
2
Block align
1 - 65535
0x16
2
Significant bits per sample
2 - 65535
0x18
2
Extra format bytes
0 - 65535
0x1a
Extra format bytes *
Fact Chunk
0x00
4
Chunk ID
"fact" (0x66616374)
0x04
4
Chunk Data Size
depends on format
0x08
Format Dependant Data
Data Chunk
0x00
4
ChunkID
“data” (0x64617461)
0x04
4
Chunk Data Size
depends on sample length and compression
0x08
Sample data
上表中,各Chunk具體介紹:
l          RIFF Chunk
這個Chunk的大小固定為12個位元組,ID”RIFF”,然後接著為size欄位,該size是整個wave檔案大小減去IDSize所佔用的位元組數,即FileSize - 8 = Size。然後是Type欄位,為'WAVE',表示是wave檔案。結構定義如下:
 struct RIFF_HEADER
 {     char szRiffID[4]
  // 'R''I''F''F'
        DWORD dwRiffSize

         char szRiffFormat[4]
 // 'W''A''V''E'
 }
l          Format Chunk
n          Chunk ID and Data SizeID"fmt " (0x666D7420)Size值為標準WAVE格式資料的大小(16個位元組)加上附加訊息的大小(2個位元組),所以值為1618。如果聲音資料是用未壓縮的PCM編碼格式則沒有附加訊息欄位。
n          Compression Code:壓縮的格式類別代碼,常見的如下表七所示:
表七、Common Wave Compression Codes
Code
Description
0 (0x0000)
Unknown
1 (0x0001)
Microsoft PCM /uncompressed
2 (0x0002)
Microsoft ADPCM
6 (0x0006)
ITU G.711 a-law(歐洲和世界剩餘地方)
7 (0x0007)
ITU G.711 μ-law(美國和日本)
17 (0x0011)
Interactive Multimedia Association ADPCM (IMA ADPCM)
20 (0x0016)
ITU G.723 ADPCM (Yamaha)
49 (0x0031)
Microsoft GSM 6.10 Audio (GSM 610)
64 (0x0040)
ITU G.721
80 (0x0050)
ADPCM MPEG
65536 (0xFFFF)
Experimental
n         Number of Channels:聲音頻道數
u        1 = 8 bit Mono
u        2 = 8 bit Stereo or 16 bit Mono
u        4 = 16 bit Stereo
n          Sample Rate:取樣頻率(每秒取樣數),常見的值為8000~44100,但這個值與聲音頻道數沒有關係
n          Average Bytes Per Second:每秒的資料量
u        其值AvgBytesPerSec = SampleRate * BlockAlign
u        (取樣頻率 * 每個完整樣本的byte 或 取樣頻率 * 聲音頻道數 * 每個樣本大小/8)
n         Block Align每個完整樣本的byte
u        其值BlockAlign = NumChannels * SignificantBitsPerSample / 8  
u        (聲音頻道數 * 每個樣本大小 / 8)
n          Significant Bits Per Sample:每個樣本的大小,常見的值有8162432
n          Extra Format Bytes:若為未壓縮之PCM檔案則不存在這個欄位,但採用除PCM以外的壓縮編碼格式則這個欄位一定存在。
WAVE的基本結構WAVEFORMATEX結構定義如下:
typedef struct
{  WORD wFormatTag              //編碼格式,包括WAVE_FORMAT_PCM
//WAVEFORMAT_ADPCM
WORD  nChannls                 //聲音頻道數,單聲道(mono)1
//雙聲道(stereo)2
DWORD nSamplesPerSec     //取樣頻率(每秒取樣數),通常為11025 22050
                         //或是44100
DWORD nAvgBytesperSec   //每秒的資料量(每秒需要的平均位元元組個數)
WORD  nBlockAlign             //每個完整樣本的byte
                                                  //通常值為wBitsPerSample *  nChannls / 8
WORD  wBitsPerSample      //每個樣本的大小,通常為8 bits16 bits
WORD  cbSize                //用來描述特殊的wave格式的其他欄位
// (Extra Format Bytes)的大小,PCM中忽略此值
}WAVEFORMATEX
l          Fact Chunk
在非PCM格式的WAVW檔案中,會在Format Chunk後面加上Fact Chunk結構如下:


typedef struct
{     char[4]                     //fact字串
       DWORD chunksize
       DWORD datafactsize    //資料轉換為PCM格式後的大小
}factchunk
datafactsize是這個chunk中最重要的資料,如果這是某種壓縮格式的聲音檔案,那麼從這裡就可以知道它解壓縮後的大小。對於解壓時的計算會有很大的好處!
l          Data Chunk
這個Chunk8個位元組儲存的是Chunk IDData SizeID”data”,後面接著Size儲存的是聲音資料的實際大小,也就是扣除掉整個表頭(44個位元組)的檔案大小。而從Data Chunk的第9個位元組開始,存儲的就是聲音信息的資料了,這些資料可以是PCM(沒有壓縮)ADPCM(壓縮)格式
WAVE檔案有多種不同的編碼格式,以下只介紹其中的PCM IMA-ADPCM兩種。
n          PCM
最基本的WAVE檔案是PCMPulse-code modulation,脈沖編碼調變)格式的,這種格式直接存儲取樣的聲音資料沒有經過任何的壓縮,是音效卡直接支援的資料格式,要讓音效卡正確播放其他被壓縮的聲音資料,就應該先把壓縮的資料解壓縮成PCM格式,然後再讓音效卡來播放。
所謂的PCM是一種未經壓縮的編碼格式,每個取樣的樣本為在取樣當時的振幅大小(Amplitude),而PCM又可分為Linear PCM(LPCM)Non-linear PCM兩種。所謂的LPCM指的是當使用 PCM 格式編碼記錄時,每一個取樣位階的間隔大小都是固定的;如果把每一個取樣位階的間隔大小改成對數形式,低電位時取樣位階比較密集,高電位時取樣位階比較稀疏,這樣如果取樣的對象大部分時間都是低電位訊號,我們就可以得到比較好的紀錄品質。這種記錄方式就稱為 Non-linear PCM。所以當我們只說 PCM 的時候,它可能是 LPCM,也可能是 Non-Linear PCM,沒有很明確的指定是哪一種形式,而 DVD 上則只能用 LPCM 音軌,所以它會很明確的把 LPCM "L" 標明上去。
PCM 是一種編碼格式,而WAVE則是一種檔案格式,WAVE裡面可以放LPCM編碼記錄後儲存的資料。WAVE開頭有WAVE檔案格式規定的檔頭,裡面會說明後面存放的是哪一種編碼的資料,有幾聲道,取樣頻率和位元大小等等基本資料,供處理的程式作識別。
我們也可以不需要用WAVE的檔案格式來記錄儲存PCM,把PCM 記錄下來的數位資料直接存成一個檔案,我們稱這種資料叫做RAW PCM,副檔名可以是 .raw .pcm。這種檔案由於沒有檔頭,檔案一開始就是資料的"內容",所以處理程式完全無法知道它有幾聲道,取樣頻率和位元大小,不知道這些就無法正確的分段,讀取正確的資料內容。所以在開啟這類檔案時,程式都會要求你先告訴它以上這些基本資料,然後它才能開始處理。
PCM中的聲音資料沒有被壓縮,對於單聲道聲音檔案,取樣數據為八位元的短整數(short int 00H-FFH),取樣按時間的先後順序依次存入(它的基本組織單位是BYTE(8bit)WORD(16bit);而對於雙聲道立體聲聲音檔案,每次取樣數據為一個16位元的整數(int),高八位元和低八位元分別代表左右兩個聲道,取樣資料按時間先後順序交叉地存入
WAVE檔案資料區塊包含以脈沖編碼調制 PCM)格式表示的樣本。WAVE檔案是由樣本組織而成的。在單聲道WAVE檔案中,聲道0代表左聲道,聲道1代表右聲道。在多聲道WAVE檔案中,樣本是交替出現的。如下表八所示:
表八、PCM資料的存放方式

樣本一
樣本二
8bit單聲道
0聲道
0聲道
16bit單聲道
0聲道()
1聲道()
0聲道()
1聲道()
8bit立體聲
0聲道低位元組
0聲道高位元組
0聲道低位元組
0聲道高位元組
16bit立體聲
0聲道()低位元組
0聲道()高位元組
1聲道()低位元組
1聲道()高位元組
WAVE檔案的每個樣本值包含在一個整數i中,i的大小為容納指定樣本大小所需的最小位元組數。首先存儲低有效位元組,表示樣本幅度的位元放在i的高有效位元上,剩下的位置為0PCM格式之8位元和16位元的波形樣本與檔頭如下表七、表八所示:
表九、8位元和16位元的PCM波形樣本的資料格式
樣本大小
資料格式
最大值
最小值
8位元PCM
unsigned int
225
0
16位元PCM
Int
32767
-32767
表十、PCM格式的WAVE檔案的檔頭
Chunk name
offset
size
Field name
Type
Description
RIFF Chunk
0
4
ChunkID
Char
存放"RIFF" (0x52494646)4個字元
4
4
ChunkSize
Long int
(file size)–8
8
4
Format
Char
存放"WAVE"(0x57415645)4個字元,告之此檔為WAVE格式
Format Chunk

12
4
Subchunk1ID
Char
"fmt " (0x666D7420)
16
4
Subchunk1Size
Lont int
結構PCMWAVEFORMAT的大小,值為16
20
2
AudioFormat
Short int
編碼格式(1PCM格式)
22
2
NumChannels
Short int
聲道頻道數(mono=1Stereo=2)
24
4
SampleRate
Long int
每秒取樣數
28
4
ByteRate
Long int
每秒資料量
32
2
BlockAlign
Short int
每次讀取的區塊大小
34
2
BitsPerSample
Short int
每個取樣的大小
Data Chunk
36
4
Subchunk2ID
Char
“data” (0x64617461)
40
4
Subchunk2Size
Long int
扣除掉WAVE檔頭大小(44Bytes)的聲音資料真正大小
44
~end
Data

聲音資料存放處
n          IMA-ADPCM
ADPCM (Adaptive Differential Pulse Code Modulation可適性差分脈衝編碼調變),使用一個差異化訊號(difference signal)。不將整個樣本加以編碼,ADPCM可以將目前樣本與前一個樣本比較出來的差異傳送出去。由於編碼方式只採取相鄰兩樣本之間差別作紀錄,ADPCM 所需的位元比 (Bit Rate) 較標準PCM為低,就是說ADPCM儲存同一聲音所需的空間比較小。
IMA-ADPCMIntel公司首先開發,是一種針對16bit (或者更高) 聲音波形資料的一種有損壓縮演算法,它將聲音流中每次取樣的 16bit 資料以 4bit 儲存,所以壓縮比 14。而壓縮/解壓縮演算法非常的簡單,所以是一種低空間消耗,高質量聲音獲得的好途徑。它是從PCM16位元的取樣壓縮成4位元的,對於單聲道的IMA-ADPCM來說,它是將PCM的資料按時間順序依次壓縮並寫入檔案中,每個byte中含兩個取樣,低4位元對應第一個取樣,高4位元對應第二個取樣。而對於雙聲道的IMA-ADPCM來說,它的儲存相對就麻煩一些了,它是將PCM的左聲道的前8個取樣依次壓縮並寫入到一個DWORD中,然後寫入Data Chunk裡。再來是右聲道的前8個取樣。以此循環,當取樣數不足8時(到資料尾端),應該把多出來的取樣用0填充。
IMAADPCMWAVEFORMAT結構定義如下:
Typedef struct
{  WAVEFORMATEX wfmt
    WORD nSamplesPerBlock
}IMAADPCMWAVEFORMAT
IMA-ADPCMwfmt->cbsize不能忽略,一般取值為2,表示此類型的WAVEFORMAT比一般的WAVEFORMAT多出2個位元組,這兩個字元也就是nSamplesPerBlock
PCM與非PCM主要的差異是聲音資料組織不同,在非PCM格式的檔案中其檔頭至少會加入一個Fact Chunk,這個Chunk是用來記錄資料解壓縮後的大小,這裡說的資料是指聲音資料而非檔案,這個Fact Chunk通常是放在Data Chunk前面。

留言

這個網誌中的熱門文章