By: Ailson Jack
Date: 2020.03.29
個人博客:http://www.only2fire.com/
本文在我博客的地址是:http://www.only2fire.com/archives/114.html,排版更好,便於學習,也可以去我博客逛逛,興許有你想要的內容呢。
1、WAV文件概述
WAV是微軟公司開發的一種音頻格式文件,用於保存Windows平臺的音頻信息資源,它符合資源互換文件格式(Resource Interchange File Format,RIFF)文件規範。標準格式化的WAV文件和CD格式一樣,也是44.1K的取樣頻率,16位量化數字,因此在聲音文件質量和CD相差無幾!
WAV通常用來保存PCM格式的原始音頻數據,所以通常被稱爲無損音頻。但是嚴格意義上來講,WAV也可以存儲其它壓縮格式的音頻數據。
2、WAV文件格式
WAV符合RIFF文件格式標準,可以看作是RIFF文件的一個具體實例。既然WAV符合RIFF規範,其基本的組成單元也是chunk。一個WAV文件通常有三個chunk以及一個可選chunk,其在文件中的排列方式依次是:RIFF chunk,Format chunk,Fact chunk(附加塊,可選),Data chunk。示意圖如下:
一個WAV文件,首先是一個RIFF chunk,其格式類型爲'WAVE'。RIFF chunk包括兩個子chunk,ID分別爲 'fmt '和'data',還有一個可選的Fact chunk。Format chunk用於表示音頻數據的屬性,包括編碼方式、聲道數目、採樣頻率、每個採樣需要的bit數等等信息。Fact chunk是一個可選chunk,一般當WAVE文件由某些軟件轉化而成就包含Fact chunk。Data chunk包含WAVE文件的數字化波形聲音數據。 WAVE整體結構如下圖所示:
接下來講講各個chunk的具體內容。
3、各個chunk的具體內容
(1).RIFF chunk
- ID:4字節,值爲"RIFF"。
- Size:4字節,ChunkData字段中數據的大小,單位:字節。
- ChunkData:包含FormType和其他chunk的內容。
- FormType:4字節,值爲"WAVE"。
- Data:其他chunk的內容。
(2).Format chunk
- ID:4字節,值爲"fmt ",最後一個字符是空格。
- Size:4字節,數據字段(Data)包含的數據大小。如無擴展塊,則值爲16;有擴展塊,則值爲= 16 + 2字節擴展塊長度 + 擴展塊內容,或者值爲18(只有擴展塊長度爲2字節,並且擴展塊長度值爲0),單位:字節。
- Data:存放音頻格式、聲道數、採樣率等信息。
- audio_format:2字節,表示音頻數據的格式。如值爲1,表示使用PCM格式。
- channels:2字節,聲道數。值爲1則爲單聲道,爲2則是雙聲道。
- sample_rate:4字節,採樣頻率,主要有22.05KHz,44.1kHz和48KHz等,例如0xAC44表示44100Hz。
- bytes_per_sec:4字節,音頻的碼率,每秒播放的字節數。其值爲:聲道數 * 採樣頻率 * 量化位數 / 8,可以估算出使用緩衝區的大小。
- block_align:2字節,每個採樣點所需的字節數,其值爲:聲道數 * 量化位數 / 8。
- bits_per_sample:2字節,量化位數,有16位,24位和32位等。
- cbSize:2字節,擴展塊的長度,其值可以爲0或者22。
- cbContent:0字節或22字節,擴展塊內容,具體介紹在下文提及。
備註:這個區域只需要關心channels,sample_rate,bits_per_sample三個參數就可以了,其它的都是依據這三個計算出來的。
(3).Fact chunk(可選)
fact chunk爲可選的,在大多數的WAV文件中是不存在的。採用壓縮編碼的WAV文件,必須要有Fact chunk,該塊中只有一個數據,爲每個聲道的採樣總數。
ID:4字節,值爲"fact"。
Size:4字節,數據字段的長度,其值最小爲4。
Data:採樣總數。
(4).Data chunk
ID:4字節,值爲"data"。
Size:4字節,音頻數據的長度。
Data:具體的音頻數據內容存放在這裏。
4、Format chunk中的音頻數據格式
在format chunk中,有一個字段audio_format,該字段表示音頻數據是以何種方式進行編碼存放的。其可選的取值有:
0x0001:WAVE_FORMAT_PCM,採用PCM格式,此時WAV文件中不包含Fact chunk。
0x0002:WAVE_FORMAT_ADPCM,此時WAV文件中包含Fact chunk。
0x0006:WAVE_FORMAT_ALAW,此時WAV文件中包含Fact chunk。
0x0007:WAVE_FORMAT_MULAW,此時WAV文件中包含Fact chunk。
0xFFFE:WAVE_FORMAT_EXTENSIBLE,具體的編碼方式由Format chunk中擴展塊的sub_format字段決定。
備註:一般情況下,我們遇到的WAV文件的音頻數據編碼格式是PCM,介紹上述內容,只是讓大家多瞭解下其他的編碼格式的值與名稱,當遇到這類編碼時,能夠知道其名稱,從而方便查詢相關資料。
5、Format chunk中的擴展塊
當WAV文件使用的不是PCM編碼方式時,就需要擴展格式塊,它是在基本的Format chunk中又添加一段數據。該數據的前兩個字節,表示的是擴展塊的長度。緊接其後的是擴展塊的數據區,含有擴展的格式信息,其具體的長度取決於壓縮編碼的類型。當某種編碼方式的擴展塊的數據區長度爲0,此時擴展塊只包含了擴展塊長度字段,擴展塊的長度字段還必須保留,只是其值設置爲0。
擴展塊的各個字節的含義如下:
- cbSize:2字節,擴展塊的長度,其值可以爲0或者22。
- cbContent:0字節或22字節,擴展塊內容。
- valid_bits_per_sample:2字節,有效的採樣位數,最大值爲block_align * 8。可以使用更靈活的量化位數,通常音頻sample的量化位數爲8的倍數,但是使用了WAVE_FORMAT_EXTENSIBLE時,量化的位數由擴展塊中的valid_bits_per_sample來描述,可以小於Format chunk中指定的bits_per_sample。
- channle_mask:4字節,聲道掩碼。
- sub_format:16字節,數據格式碼。
在Format chunk中的audio_format設置爲0xFFFE時,表示使用擴展區中的sub_format來決定音頻的數據的編碼方式。在以下幾種情況下必須要使用WAVE_FORMAT_EXTENSIBLE:
- PCM數據的量化位數大於16。
- 音頻的採樣聲道大於2。
- 實際的量化位數不是8的倍數。
- 存儲順序和播放順序不一致,需要指定從聲道順序到聲卡播放順序的映射情況。
備註:一般情況下,我們遇到的WAV文件中是不含有擴展塊的。
6、聲音數據格式
Data chunk中的Data塊中存放的是音頻的採樣數據。每個sample按照採樣的時間順序寫入,對於使用多個字節的sample,使用小端模式存放(低位字節存放在低地址,高位字節存放在高地址)。對於多聲道的sample採用交叉存放的方式。例如:立體雙聲道的sample存儲順序爲:聲道1的第一個sample,聲道2的第一個sample;聲道1的第二個sample,聲道2的第二個sample;依次類推....。
對於Data chunk中的Data字段,也就是音頻數據內容的存儲,根據聲道數和採樣位數的不同情況,佈局如下(每1列代表8 bits):
1.8 bit 單聲道
採樣1 |
採樣2 |
數據1 |
數據2 |
2.8 bit 雙聲道
採樣1 |
|
採樣2 |
|
聲道1數據1 |
聲道2數據1 |
聲道1數據2 |
聲道2數據2 |
3.16 bit 單聲道
採樣1 |
|
採樣2 |
|
數據1低字節 |
數據1高字節 |
數據2低字節 |
數據2高字節 |
4.16 bit 雙聲道
聲道1採樣1 |
|
聲道2採樣1 |
|
聲道1數據1低字節 |
聲道1數據1高字節 |
聲道2數據1低字節 |
聲道2數據1高字節 |
聲道1採樣2 |
|
聲道2採樣2 |
|
聲道1數據2低字節 |
聲道1數據2高字節 |
聲道2數據2低字節 |
聲道2數據2高字節 |
7、WAV文件實例分析
利用winhex工具軟件可以非常方便的以十六進制查看文件,下圖是我用winhex軟件打開一個WAV音頻文件時的部分界面截圖:
下表對文件格式進行解讀:
偏移地址 |
字節數 |
16進制源碼 |
內容 |
00H |
4 |
52 49 46 46 |
'RIFF'標識符 |
04H |
4 |
F4 FE 83 01 |
數據長度:0x0183FEF4(注意順序) |
08H |
4 |
57 41 56 45 |
'WAVE'標識符 |
0CH |
4 |
66 6D 74 20 |
'fmt ',最後一位爲空格 |
10H |
4 |
10 00 00 00 |
Format chunk大小:0x10 |
14H |
2 |
01 00 |
編碼格式:0x01爲PCM |
16H |
2 |
02 00 |
聲道數目:0x02爲雙聲道 |
18H |
4 |
44 AC 00 00 |
採樣頻率:0xAC44表示44100Hz |
1CH |
4 |
10 B1 02 00 |
每秒字節數:0x02B110 |
20H |
2 |
04 00 |
每個採樣點所需的字節數:0x04 |
22H |
2 |
10 00 |
量化位數:0x10 |
24H |
4 |
64 61 74 61 |
'data'標識符 |
28H |
4 |
48 FE 83 01 |
音頻數據的長度:0x0183FE48 |
從偏移量2CH開始就是音頻數據了。
如果覺得文章寫的不錯,對你有幫助,歡迎點贊,關注博主喲!
排版更好的內容見我博客的地址:http://www.only2fire.com/archives/114.html
注:轉載請註明出處,謝謝!^_^