WAVE (WAV) ファイル フォーマット

研究 (のお手伝い) で、音声を PC のライン入力から WAVE ファイルへ録音するプログラムを書きました。その時に、WAVE ファイルの構造などについて少し調べたのでまとめておきます。

WAVE ファイルとは

WAVE ファイルについて「Wikipedia」では次のように述べられています。

WAV または WAVE (ウェーブ、ウェブ、ワブ、ウォブ) (RIFF waveform Audio Format) は、MicrosoftIBM により開発された音声データ記述のためのフォーマットである。RIFF の一種。主として Windows で使われるファイル形式である。ファイルに格納した場合の拡張子は、.wav。

WAV - Wikipedia

ここで、RIFF (Resource Interchange File Format) とは、画像や音声などのデータを1つのファイルに格納するための共通フォーマットで、RIFF の一種としては WAVE ファイルの他に AVI ファイルなどがあります (RIFF - IT用語辞典 e-Words)。WAVE ファイルは、この RIFF を基に作られた音声データのためのフォーマットということです。

RIFF の特徴として、チャンク (chunk) と呼ばれる概念があります。チャンクとは、データの論理的な単位で、その名の通りデータの塊のようなものです。チャンクの中にチャンクを含むこともでき、含まれている方のチャンクをサブチャンク (sub-chunk) と呼びます。RIFF は、このチャンクのいくつかを1つにまとめたような形になっています。

このほか RIFF については、「RIFFファイルフォーマット - うめっきぃ=umekkii」に詳しい解説があり、参考になります。

ところで、WAVE ファイル自体は音声のコーデックについては定義されていません。一般的には、リニア PCM (無圧縮) の格納に使われることが多いようですが、ADPCM や MP3 (MPEG-1 Audio Layer-3)、Indeo Audio といったコーデックを使うこともできます (WAV - IT用語辞典 e-Words)。この記事では、コーデックとしてリニア PCM を使用する場合を中心に記述しています。

WAVE ファイルの構造

基本的な WAVE ファイルの構造は次のようになっています。

オフセット (バイト) サイズ (バイト) 説明
0 4 チャンク識別子 "RIFF" (0x52494646)
4 4 チャンク サイズ = 全体のファイルサイズ - 8
8 4 フォーマット "WAVE" (0x57415645)
12 4 サブチャンク 1 識別子 "fmt " (0x666D7420)
16 4 サブチャンク 1 サイズ = 16 + 拡張パラメータのサイズ
20 2 音声フォーマット 1 - 65,535
22 2 チャンネル数 1 - 65,535
24 4 サンプリング周波数 1 - 0xFFFFFFFF
28 4 1 秒あたりバイト数の平均 1 - 0xFFFFFFFF
32 2 ブロックサイズ 1 - 65,535
34 2 1 サンプルあたりのビット数 2 - 65,535
- (2) 拡張パラメータのサイズ 0 - 65,535
- (*) 拡張パラメータ (拡張パラメータ)
36 4 サブチャンク 2 識別子 "data" (0x64617461)
40 4 サブチャンク 2 サイズ = 波形データのバイト数
44 * データ (波形データ)

WAVE ファイルは、全体が RIFF チャンクになっており、そのサブチャンクとしてフォーマット チャンク (12バイト以降) とデータ チャンク (36バイト以降) を含む構造になっています。

フォーマット チャンクとデータ チャンクの2つのサブチャンクは必須なので、どの WAVE ファイルにも含まれています。これら以外のサブチャンクとしては、Fact チャンクなどがあります。

バイトオーダーは、チャンク識別子とフォーマット、サブチャンク 1 識別子、サブチャンク 2 識別子がビッグエンディアン、それ以外はリトルエンディアンです。

RIFF チャンク

先述の通り、WAVE ファイルは全体が RIFF チャンクになっています。このうち先頭から8バイトをチャンク ヘッダ、それ以降をチャンク データと呼びます。

チャンク識別子 (Chunk ID)
文字列 "RIFF" (0x52494646)。
チャンク サイズ (Chunk Size)
以降のサイズ。全体のファイルサイズ - 8で求められる。
フォーマット (Format)
文字列 "WAVE" (0x57415645)。

フォーマット チャンク

続いて、12バイト以降はフォーマット チャンクです。RIFF チャンクと同様、先頭から8バイトがチャンク ヘッダ、それ以降がチャンク データです。

サブチャンク 1 識別子 (Subchunk 1 ID)
文字列 "fmt " (0x666d7420)。
サブチャンク 1 サイズ (Subchunk 1 Size)
以降のフォーマット チャンクのサイズ。リニア PCM の場合は16 (それ以外の場合は16 + 拡張パラメータのサイズ)。
フォーマット (Audio Format)
リニア PCM の場合は1 (それ以外の場合は「WAV ファイルフォーマット - 近藤正芳のウェブページ」などを参照)。
チャンネル数 (Num Channels)
モノラルの場合は1、ステレオの場合は2など。
サンプリング周波数 (Sample Rate)
サンプリング周波数 (Hz)。8kHz の場合は8000、44.1kHz の場合は44100など。
1 秒あたりバイト数の平均 (Byte Rate)
サンプリング周波数 * チャンネル数 * 1サンプルあたりのビット数 / 8または、サンプリング周波数 * ブロックサイズで求められる。
ブロックサイズ (Block Align)
ブロックの境界から境界までのサイズ。チャンネル数 * 1サンプルあたりのビット数 / 8で求められる。
1 サンプルあたりのビット数 (Bits Per Sample)
8ビットの場合は8、16ビットの場合は16など。
拡張パラメータのサイズ (Extra Param Size)
リニア PCM (フォーマットが1) の場合は使用しません。
拡張パラメータ (Extra Params)
リニア PCM (フォーマットが1) の場合は使用しません。

データ チャンク

そして、36バイト (リニア PCM の場合) 以降はデータ チャンクです。他のチャンクと同様、先頭から8バイトがチャンク ヘッダ、それ以降がチャンク データです。

サブチャンク 2 識別子 (Subchunk 2 ID)
文字列 "data" (0x64617461)。
サブチャンク 2 サイズ (Subchunk 2 Size)
波形データのサイズ (バイト)。
データ (Data)
実際の波形データを格納する。リニア PCM の場合は時間順に格納され、ステレオは左→右→左→右…のように格納される。また、8ビットの場合は符号無し整数 (0 - 255)、16ビットの場合は符号付き整数 (-32768 - 32767) で表わす。