WAVE (WAV) ファイル フォーマット
研究 (のお手伝い) で、音声を PC のライン入力から WAVE ファイルへ録音するプログラムを書きました。その時に、WAVE ファイルの構造などについて少し調べたのでまとめておきます。
WAVE ファイルとは
WAVE ファイルについて「Wikipedia」では次のように述べられています。
WAV または WAVE (ウェーブ、ウェブ、ワブ、ウォブ) (RIFF waveform Audio Format) は、Microsoft と IBM により開発された音声データ記述のためのフォーマットである。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) で表わす。