WAV文件格式分析
特別說明,本文摘抄于:http://blog.csdn.net/zhihu008/article/details/7854529???? 只做筆記使用,絕無抄襲之意
一. RIFF概念
在Windows環(huán)境下,大部分的多媒體文件都依循著一種結(jié)構(gòu)來存放信息,這種結(jié)構(gòu)稱為"資源互換文件格式"(Resources lnterchange File Format),簡稱RIFF。例如聲音的WAV文件、視頻的AV1文件等等均是由此結(jié)構(gòu)衍生出來的。RIFF可以看做是一種樹狀結(jié)構(gòu),其基本構(gòu)成單位為chunk,猶如樹狀結(jié)構(gòu)中的節(jié)點,每個chunk由"辨別碼"、"數(shù)據(jù)大小"及"數(shù)據(jù)"所組成。
| 塊的標志符(4BYTES) |
| 數(shù)據(jù)大小 (4BYTES) |
| 數(shù)據(jù) |
?????????????????????????????? 圖一、 塊的結(jié)構(gòu)示意圖
辨別碼由4個ASCII碼所構(gòu)成,數(shù)據(jù)大小則標示出緊跟其后數(shù)據(jù)的長度(單位為Byte),而數(shù)據(jù)大小本身也用掉4個Byte,所以事實上一個chunk的長度為數(shù)據(jù)大小加8。一般而言,chunk本身并不允許內(nèi)部再包含chunk,但有兩種例外,分別為以"RIFF"及"L1ST"為辨別碼的chunk。而針對此兩種chunk,RIFF又從原先的"數(shù)據(jù)"中切出4個Byte。 此4個Byte稱為"格式辨別碼",然而RIFF又規(guī)定文件中僅能有一個以"RIFF"為辨別碼的chunk。
| RIFF/LIST標志符 | |
| 數(shù)據(jù)1大小 | |
| 數(shù)據(jù)1 | 格式/列表類型 |
| 數(shù)據(jù) | |
?????????????????????????????? 圖二、RIFF/LIST塊結(jié)構(gòu)
只要依循此一結(jié)構(gòu)的文件,我們均稱之為RIFF檔。此種結(jié)構(gòu)提供了一種系統(tǒng)化的分類。如果和MS一DOS文件系統(tǒng)作比較,"RIFF"chunk就好比是一臺硬盤的根目錄,其格式辨別碼便是此硬盤的邏輯代碼(C:或D:),而"L1ST"chunk即為其下的子目錄,其他的chunk則為一般的文件。至于在RIFF文件的處理方面,微軟提供了相關(guān)的函數(shù)。視窗下的各種多媒體文件格式就如同在磁盤機下規(guī)定僅能放怎樣的目錄,而在該目錄下僅能放何種數(shù)據(jù)。
二. WAV文件格式
WAVE文件是非常簡單的一種RIFF文件,它的格式類型為"WAVE"。RIFF塊包含兩個子塊,這兩個子塊的ID分別是"fmt"和"data",其中"fmt"子塊由結(jié)構(gòu)PCMWAVEFORMAT所組成,其子塊的大小就是sizeofof(PCMWAVEFORMAT),數(shù)據(jù)組成就是PCMWAVEFORMAT結(jié)構(gòu)中的數(shù)據(jù)。
| 標志符(RIFF) |
| 數(shù)據(jù)大小 |
| 格式類型("WAVE") |
| "fmt" |
| Sizeof(PCMWAVEFORMAT) |
| PCMWAVEFORMAT |
| "data" |
| 聲音數(shù)據(jù)大小 |
| 聲音數(shù)據(jù) |
圖三、WAVE文件結(jié)構(gòu)
PCMWAVEFORMAT結(jié)構(gòu)定義如下:
Typedefstruct...{
??? WAVEFORMAT wf;???????/波形格式;
??? WORD wBitsPerSample;???//WAVE文件的采樣大小;
} PCMWAVEFORMAT;
//WAVEFORMAT結(jié)構(gòu)定義如下:
typedefstruct
...{
??? WORD wFormatag;???????//編碼格式,包括WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM等
??? WORD nChannls;???????//聲道數(shù),單聲道為1,雙聲道為2;
??? DWORD nSamplesPerSec;???//采樣頻率;
??? DWORD nAvgBytesperSec;???//每秒的數(shù)據(jù)量;
????? WORD nBlockAlign;???????//塊對齊;
} WAVEFORMAT;
"data"子塊包含WAVE文件的數(shù)字化波形聲音數(shù)據(jù),其存放格式依賴于"fmt"子塊中wFormatTag成員指定的格式種類,在多聲道WAVE文件中,樣本是交替出現(xiàn)的。如16bit的單聲道WAVE文件和雙聲道WAVE文件的數(shù)據(jù)采樣格式分別如圖四所示:
16位單聲道:
| 采樣一 | 采樣二 | …… | ||
| 低字節(jié) | 高字節(jié) | 低字節(jié) | 高字節(jié) | …… |
16位雙聲道:
| 采樣一 | …… | |||
| 左聲道 | 右聲道 | …… | ||
| 低字節(jié) | 高字節(jié) | 低字節(jié) | 高字節(jié) | …… |
???????????????????????????? 圖四、WAVE文件數(shù)據(jù)采樣格式
WAV文件格式實例分析:
| 0?? 1?? 2?? 3?? 4?? 5?? 6?? 7?? 8?? 9?? A?? B?? C?? D?? E?? F | |
| 00000000H 00000010H 00000020H 00000030H 00000040H | 52? 49? 46? 46? 0A 06? 01? 00? 57? 41? 56? 45? 66? 6D 74? 20 12? 00? 00? 00? 01? 00? 02? 00? 44? AC 00 00? 10? B1? 02? 00 04? 00? 10? 00? 00? 00? 66? 61? 63? 74? 04? 00? 00? 00? 76? 41 00? 00? 64? 61? 74? 61? D8? 05? 01? 00 00? 00? 00? 00? FF? FF 00? 00? FE FF FE FF? 00? 00? 00? 00 FE? FF FE FF? 00? 00 |
| 偏移地址 | 字節(jié)數(shù) | 數(shù)據(jù)類型 | 內(nèi)容 | |
| 文件頭 | 00H | 4 | char | “RIFF”;??RIFF標志 |
| 04H | 4 | long int | 0x00 01 06 0A(注意數(shù)據(jù)存儲順序);??文件長度,這個長度是指”RIFF”;??RIFF標志占的長度,也就是說這個值等于文件的總長度減去RIFF標志占的4個字節(jié)和該值占的4個字節(jié) | |
| 08H | 4 | char | “WAVE”;??WAVE標志 | |
| 0CH | 4 | char | “fmt ”;??fmt標志,最后一位為空 | |
| 10H | 4 | long int | ?sizeof(PCMWAVEFORMAT) | |
| 14H | 2 | int | 1(WAVE_FORMAT_PCM);?格式類別,1表示為PCM形式的聲音數(shù)據(jù) | |
| 16H | 2 | int | 2;?通道數(shù),單聲道為1,雙聲道為2 | |
| 18H | 4 | long int | 44100;?采樣頻率(每秒樣本數(shù)) | |
| 1CH | 4 | long int | 0x0002b110;??每秒數(shù)據(jù)量;其值為通道數(shù)×每秒數(shù)據(jù)位數(shù)×每樣本的數(shù)據(jù)位數(shù)/8。播放軟件利用此值可以估計緩沖區(qū)的大小。 | |
| 20H | 2 | int | 數(shù)據(jù)塊的調(diào)整數(shù)(按字節(jié)算的),其值為通道數(shù)×每樣本的數(shù)據(jù)位值/8。播放軟件需要一次處理多個該值大小的字節(jié)數(shù)據(jù),以便將其值用于緩沖區(qū)的調(diào)整。 | |
| 22H | 2 | 每樣本的數(shù)據(jù)位數(shù),表示每個聲道中各個樣本的數(shù)據(jù)位數(shù)。如果有多個聲道,對每個聲道而言,樣本大小都一樣。 | ||
| 24H | 4 | char | “data”;??數(shù)據(jù)標記符 | |
| 28H | 4 | long int | 0x00 01 05 D8;??語音數(shù)據(jù)大小,這個長度是data標識符的所有長度,那么對這里來說該值就是有效數(shù)據(jù)長度,也即是從“data”; 該值等于 數(shù)據(jù)標記符的地址(50H)開始到這個標志結(jié)束減去標識符占的四個字節(jié)和本數(shù)值占的四個字節(jié) |
如下圖左邊是16BIT 16KHZ,左邊是8BIT 8KHZ:
注意:在fmt后面可能有“fact”格式標志:
“fact”,該部分是可選部分,一般當WAV文件是由某些軟件轉(zhuǎn)換而來時,包含該部分。若包含該部分: (1)該部分的前4字節(jié)為數(shù)據(jù)頭,一般為4個字母。 (2)隨后4個字節(jié)表示長度,即除去頭(4字節(jié))和長度(4字節(jié))之后,數(shù)據(jù)本身的長度。 (3)最后的字節(jié)為數(shù)據(jù)本身。 例如:“66 61 73 74 04 00 00 00F8 2F 14 00” 。“66 61 73 74”是fact字段的數(shù)據(jù)頭,“04 00 00 00”是數(shù)據(jù)本身的長度,“F8 2F 14 00”是數(shù)據(jù)本身。(注意是little-indian字節(jié)順序)這里我附上我從網(wǎng)上拿到的一些WAV格式的鈴聲,以備以后使用:
http://download.csdn.net/detail/chengdong1314/9732320
總結(jié)
- 上一篇: java学习(111):日期时间格式化
- 下一篇: java学习(145):file常用方法