WAVE文件格式解析


WAVE 文件作為Windows多媒體中使用的聲音波形文件格式之一,它是以RIFF(Resource Interchange File Format)格式為標准的。這里不針對RIFF文件格式做介紹,不太了解的可以參考“RIFF格式簡介”一文。

WAVE文件構成

每個WAVE文件的頭四個字節便是“RIFF”。WAVE 文件由文件頭和數據體兩大部分組成。其中文件頭又分為 RIFF/WAV 文件標識段和聲音數據格式說明段兩部分。相對於RIFF文件,只是將“RIFF”chunk的form id替換為“WAVE”。下表是一個典型的WAVE文件各部分構成及其長度字段。注意所有數據采用windows默認的小端存儲。(FOURCC是一個特殊的四字節碼,判斷時按照字符順序判斷即可。)

長度 內容說明
chunkID 4 Chunk ID: "RIFF",FOURCC四字節碼
chunksize 4 Chunk size: 4+n
  WAVEID 4 WAVE ID: "WAVE",FOURCC四字節碼
WAVE chunks n Wave chunks包含格式信息和音頻采樣數據,分為“format” chunk和“data”chunk兩部分。

 Format chunk

Format chunk用於說明data chunk中PCM數據的格式。主要三種不同的format chunk格式(不同的格式碼)。如下表:

長度 內容說明
ckID 4 Chunk ID: "fmt ",FOURCC四字節碼,注意最后一個填充是空格。
cksize 4 Chunk size: 16 or 18 or 40
  wFormatTag 2 Format code,格式碼
nChannels 2 Number of interleaved channels,采樣聲道數(交織存儲)
nSamplesPerSec 4 Sampling rate (blocks per second),音頻采樣率
nAvgBytesPerSec 4 Data rate,音頻碼率
nBlockAlign 2 Data block size (bytes),音頻數據塊大小(單位字節)
wBitsPerSample 2 Bits per sample,量化位數(比如8bits、16bits、32bits)

cbSize 2 Size of the extension (0 or 22),擴展字段長度

wValidBitsPerSample 2 Number of valid bits,有效的位長度
dwChannelMask 4 Speaker position mask,聲道描述掩碼,比如左聲道、右聲道等
SubFormat 16 GUID, including the data format code,數據格式碼

 標准中定義的wFormatTag(Format code)可取值范圍如下表:

Format Code PreProcessor Symbol Data
0x0001 WAVE_FORMAT_PCM PCM
0x0003 WAVE_FORMAT_IEEE_FLOAT IEEE float,[-1.0f,1.0f]
0x0006 WAVE_FORMAT_ALAW 8-bit ITU-T G.711 A-law
0x0007 WAVE_FORMAT_MULAW 8-bit ITU-T G.711 µ-law
0xFFFE WAVE_FORMAT_EXTENSIBLE Determined by SubFormat

PCM格式

當wFormatTag為0x0001時,表示WAVE文件中存儲的是PCM格式的音頻數據。

在數據域中除了單聲道-量化位數為8音頻數據之外PCM存儲格式按照補碼的形式存放。對於單聲道、量化位數為8的情況,使用offset binary(偏移二進制碼),有興趣的可以查看下對應的標准。

非PCM格式

對於非PCM格式的數據,使用擴展字段,擴展字段長度由cbSize指定。需要說明以下幾點:

  • 對於非PCM格式,必須有擴展字段,字段長度cbSize可以為0,但是擴展字段不可省略。
  • 對於浮點數據,最大峰值為1,量化位數(bits/sample)取值可以是32或64。
  • 對於 log-PCM formats (µ-law and A-law)的格式,量化位數(bits/sample)取值為8。
  • 對於非PCM格式,必須包含“FACT”chunk。

 擴展格式

當FormatTag為WAVE_FORMAT_EXTENSIBLE(0xFFFE)時,表示format chunk有擴展字段,其中包括有效量化位數(wValidBitsPerSample)、聲道位置掩碼、以及額外的GUID(SubFormat)。

  • 在正常PCM數據中量化位數(wBitsPerSample)必須是8的倍數,在WAVE_FORMAT_EXTENSIBLE下量化位數可以使用wValidBitsPerSample來描述,也就是會所wValidBitsPerSample有可能小於wBitsPerSample。
  • 對於聲道位置掩碼的信息,可參考如下文章:Multi-channel / high bit resolution formats, 2001-12-04: Multiple Channel Audio Data and WAVE Files
  • SubFormat代表的GUID前兩個字節是由PCM數據格式填充的,例如WAVE_FORMAT_EXTENSIBLE。后續的14個字節是固定的,"\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"。

在以下幾種情況下必須使用WAVE_FORMAT_EXTENSIBLE格式:

  1. PCM數據的量化位數(wBitsPerSample)大於16。
  2. 音頻采樣聲道數大於2。
  3. 實際量化位數不是8的倍數。
  4. 存儲順序和播放順序不一致,需要指定從聲道順序到聲卡播放順序映射的情況。

FACT chunk

通常PCM數據是不壓縮的,對於所有壓縮的非PCM格式都需要有FACT chunk。具體可參考:WAVE update (Revision: 3.0), 1994-04-15: Multimedia Registration Kit Revision 3.0 (Q120253))。FACT chunk至少定義一個字段,實際采樣數dwSampleLength。

關於FACT chunk可以了解,但是很少用到,如果有這種格式的wav文件,建議參考上述標准解析。

DATA chunk

data chunk中包含采樣數據。格式如下:

長度 內容說明
ckID 4 Chunk ID: "data"
cksize 4 Chunk size: n
  sampled data n Samples,音頻采樣數據,交織存儲
pad byte 0 or 1 Padding byte if n is odd,填充字節

 

實例

由於微軟將多媒體輸入輸出函數廢棄了(Using Multimedia File I/O),這里不給出專門讀寫的代碼,而是直接使用二進制形式分析。

先做如下假定:

  • Nc 表示channels,聲道數
  • Ns表示文件中包含的實際采樣塊數目,每個采樣塊包括Nc 個獨立采樣
  • 采樣率為 F (blocks per second,單位Hz)
  • 每個采樣的長度為M字節。

PCM文件格式如下表:

Field Length Contents
ckID 4 Chunk ID: "RIFF"
cksize 4 Chunk size: 4 + 24 +
(8 + Nc * Ns + (0
 or 1))
  WAVEID 4 WAVE ID: "WAVE"

ckID 4 Chunk ID: "fmt "
cksize 4 Chunk size: 16
  wFormatTag 2 WAVE_FORMAT_PCM
nChannels 2 Nc
nSamplesPerSec 4 F
nAvgBytesPerSec 4 F * M * Nc
nBlockAlign 2 Nc
wBitsPerSample 2 rounds up to 8 * M

ckID 4 Chunk ID: "data"
cksize 4 Chunk size: M * Nc* Ns
  sampled data M * Nc * Ns Nc * Ns channel-interleaved M-byte samples
pad 0 or 1 Padding byte if M * Nc * Nis odd

注意WAVE文件可能附加information chunk。所以程序解析是最好按照上述標准定義,不要認為去掉wav fmt chunk之后全是data chunk。

Extensible Format如下表:

Field Length Contents
ckID 4 Chunk ID: "RIFF"
cksize 4 Chunk size: 4 + 48 + 12 +
(8 + M * Nc * Ns + (0 
or 1))
  WAVEID 4 WAVE ID, "WAVE"

ckID 4 Chunk ID: "fmt "
cksize 4 Chunk size: 40
  wFormatTag 2 WAVE_FORMAT_EXTENSIBLE
nChannels 2 Nc
nSamplesPerSec 4 F
nAvgBytesPerSec 4 F * M * Nc
nBlockAlign 2 M * Nc
wBitsPerSample 2 8 * M
cbSize 2 Size of the extension: 22
wValidBitsPerSample 2 at most 8 * M
dwChannelMask 4 Speaker position mask: 0
SubFormat 16 GUID (first two bytes are the data format code)

ckID 4 Chunk ID: "fact"
cksize 4 Chunk size: 4
  dwSampleLength 4 Nc * Ns

ckID 4 Chunk ID: "data"
cksize 4 Chunk size: M * Nc * Ns
  sampled data M * Nc *Ns Nc * Ns channel-interleaved M-byte samples
pad 0 or 1 Padding byte if M * Nc * Ns is odd

本文主要參考:Audio File Format Specifications,相關測試wav文件及標准也從其鏈接下載。

寫作本文的目的主要是學習下wave文件格式,並能夠將音頻數據解析出來。

以上介紹的內容中針對WAVE文件我們可以只關心,fmt chunk、data chunk數據,其他數據chunk可以忽略,如果你對其他chunk感興趣,建議查看rfc2361及Microsoft提供的標准文檔。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM