WAV ファイル形式
Waveform Audio。無圧縮(通常は PCM)の RIFF 音声コンテナ。
- MIME タイプ
- audio/wav
- 拡張子
- .wav
- カテゴリ
- 音声
マジックナンバー(ファイル署名)
| 0x00000000 | 52494646 | RIFF | RIFF container |
| 0x00000008 | 57415645 | WAVE | 'WAVE' form type |
WAV 形式について
WAV は音声を生の PCM サンプルとして RIFF コンテナに格納するため、ファイルは大きくなる代わりに音質の劣化がなく編集も簡単で、録音や制作の標準になっています。ヘッダは RIFF、長さ、フォームタイプ WAVE の順です。先頭 4 バイトから後ろはすべてリトルエンディアンで、ファイルはチャンクを平らに並べたものです。4 バイトのチャンク id、4 バイトのサイズ、その分のペイロード、そして偶数長へのパディング。WAV が書くのは簡単で、しかも微妙に間違えるのも簡単なのは、この配置のせいです。ファイル内で互いを照合するものが何ひとつないので、現実と食い違うサイズフィールドを持つファイルもまったく整形式の WAV であり、そしてどのプレイヤーもそれを同じようには扱いません。
ヘッダーの構造(バイト単位)
| オフセット | 長さ | フィールド | 意味 |
|---|---|---|---|
| 0 | 4 | RIFF chunk id | ASCII の RIFF、52 49 46 46。RIFF は Microsoft と IBM の汎用 Resource Interchange File Format なので、これは WAV のマーカーではまったくありません。AVI も WebP もまったく同じ 4 バイトで始まります。 |
| 4 | 4 | RIFF chunk size | この後ろ全体をリトルエンディアン符号なし 32 ビットで数えたもの、つまりファイル長から 8 を引いた値です。176478 バイトの録音ならここは 56 B1 02 00、176470 になります。強制する仕組みは何もなく、手書きの WAV ファイルでいちばんよくある欠陥がこの値の誤りです。 |
| 8 | 4 | WAVE form type | 57 41 56 45。実際に音声だと言っているのはこのフィールドで、AVI ならここが AVI、WebP なら WEBP です。オフセット 0 の RIFF を見て判定を終える検出器には、この 3 つが区別できません。 |
| 12 | 4 | 'fmt ' chunk id | 66 6D 74 20。末尾のスペースに注意してください。RIFF のチャンク id はちょうど 4 バイトで、fmt は 3 文字しかないからです。format チャンクは必須で、慣例として先頭に来ます。 |
| 16 | 4 | fmt chunk size | 素の PCM なら 16、2 バイトの拡張サイズが付くなら 18、WAVE_FORMAT_EXTENSIBLE なら 40 です。16 以外なら以降のチャンクがすべて後ろへずれるので、オフセット 36 は当てにできる目印ではありません。 |
| 20 | 2 | Audio format code | 1 は無圧縮の PCM、3 は 32 ビットの IEEE 浮動小数点、6 は A-law、7 は mu-law、FE FF(65534)は WAVE_FORMAT_EXTENSIBLE で、この場合の本当のコーデックは format 拡張の中の GUID が名指しします。 |
| 22 | 2 | Channel count | モノラルなら 1、ステレオなら 2、サラウンドならもっと多くなります。extensible 形式ではチャンネルマスクが各チャンネルの割り当てスピーカーを述べますが、素の PCM の WAV は何も述べないので、チャンネル順は慣習でしかありません。 |
| 24 | 4 | Sample rate | 1 秒あたりのフレーム数をリトルエンディアンで。44100 は 44 AC 00 00、48000 は 80 BB 00 00 と現れます。プレイヤーが再生速度を決めるのに使う唯一のフィールドです。 |
| 28 | 4 | Byte rate | サンプリング周波数 × チャンネル数 × ビット深度 ÷ 8 で、44.1 kHz ステレオ 16 ビットなら 176400 です。周囲の 3 フィールドから完全に導けるので、怪しいヘッダに対するただの整合性チェックとして使えます。 |
| 32 | 2 | Block align | 1 サンプルフレームあたりのバイト数、つまりチャンネル数 × ビット深度 ÷ 8 で、16 ビットステレオなら 4 です。シークの計算がこれを使うので、値が間違っているとシークするたびにノイズが噴き出します。 |
| 34 | 2 | Bits per sample | 8・16・24・32 のいずれか。8 ビットの PCM は符号なしで、それより広いものはすべて符号付きの 2 の補数です。この不連続は、変換器をゼロから書く人が必ず引っかかるところです。 |
| 36 | 4 | Next chunk id | これが data チャンクになるのは最小構成のときだけです。エンコーダは LIST INFO ブロックや fact チャンクを先に置くことが日常的にあり、よく使われるあるエンコーダが書いたファイルはここが 4C 49 53 54 になります。オフセットを決め打ちせず、チャンクのリストを歩いてください。 |
| variable | 4 | 'data' chunk size | 64 61 74 61 のチャンク id の直後にある 4 バイトで、後続するサンプルのバイト数を与えます。符号なし 32 ビットなので、WAV の 4 ギガバイトという厳しい天井の出どころでもあります。 |
似た形式との見分け方
| 紛らわしい形式 | 見分け方 |
|---|---|
| AVI | 先頭 8 バイトは同一です。どちらも RIFF コンテナで、オフセット 4 にリトルエンディアンの長さがあります。決めるのはオフセット 8 のフォームタイプで、音声なら 57 41 56 45、動画なら末尾スペース付きの AVI、41 56 49 20 です。RIFF で始まるかどうかだけ見る素朴なチェックが動画を音声と報告してしまうのは、この同じ罠です。 |
| WebP | RIFF ファミリーの 3 人目で、オフセット 8 が 57 45 42 50 です。つまりまったく無関係な 3 つのメディア型が先頭 8 バイトを共有し、たった 1 つの 4 バイトワードだけで違っているわけで、誠実な RIFF 検出器が 4 バイトではなく 12 バイト読むのはそのためです。 |
| RF64 / BW64 | 4 ギガバイトを超える録音は 32 ビットのフィールドで長さを表せないので、放送用の変種はオフセット 0 の id を 52 46 36 34(RF64)や 42 57 36 34(BW64)に置き換え、オフセット 4 のサイズを FF FF FF FF にして、本当の 64 ビットサイズを収めた ds64 チャンクを追加します。それ以外は普通の WAVE なので、開けるプレイヤーもあれば、ヘッダが壊れていると見なすものもあります。 |
| FLAC | どちらも可逆なので絶えず比較されますが、バイトの上では曖昧さがありません。ネイティブの FLAC は 66 4C 61 43(fLaC)に 34 バイトの STREAMINFO ブロックが続く形で始まります。FLAC ファイルを .wav にリネームしてもどこでも開けません。WAV リーダーはフォームタイプを探して走査したりしないからです。 |
| MP3 | MP3 にはコンテナがそもそもありません。ID3 タグか、あるいは直接フレーム同期、つまり 11 個の立ったビットなので FF に上位 3 ビットが立ったバイトが続く形で始まります。RIFF に似たところは何もなく、FF FB で始まる .wav はラベルを間違えた MP3 です。 |
よくある壊れ方
- クラッシュしたり強制終了したりした録音ソフト。音声データはディスクにあるのに、2 つのサイズフィールド、つまりオフセット 4 の RIFF サイズと data チャンクのサイズが、録音開始時に書かれた値、多くの場合 0 か事前確保した長さのままになっています。プレイヤーは早く止まるか、サンプルの先にある何かまで読み進みます。修復は算数です。実際のファイル長から両方を計算し直せば、問題なく再生できます。
- 4 ギガバイトの天井。サイズフィールドはどちらも符号なし 32 ビットなので、長いマルチトラックやフィールド録音は黙って値が回り込み、ヘッダはディスク上のものよりはるかに小さいファイルを記述することになります。RF64・BW64・Sony の Wave64 は、どれもこれを逃れるためだけに存在していて、そのどれも素の WAV ではありません。
- ビット深度がサンプルと食い違っている場合。オフセット 34 が 16 と言っているのにサンプルが 24 ビットで書かれていれば、フレーム境界がすべて狂い、だいたい正しい長さのリズミカルなノイズとして再生されます。ヘッダは正しく、そこにあるバイトとは別のバイトを記述しているだけです。
- チャンクのパディング忘れ。RIFF は奇数長のチャンクの後ろに、チャンクサイズに数えないパディングバイトを置くことを要求します。書き手がこれを忘れると、以降のチャンクのオフセットがすべて 1 バイト手前になるので、リーダーはチャンクの途中に着地して ata という NUL 込みのゴミみたいなチャンク id を報告します。
- 先頭に付いた余分なバイト。HTML のエラーページ、紛れ込んだ UTF-8 BOM、音声の前に保存されたメールヘッダなどが RIFF をオフセット 0 から押し出します。サンプルはすべて残っているので、52 49 46 46 より前をすべて削れば元どおりです。
この形式の現在地
WAV は今も音声制作の作業形式で、それが変わる見込みはありません。可逆で、どの DAW もどの OS も読め、配置は 1 ページのコードでゼロから書けるほど単純です。一方で配信形式ではありません。CD 品質のステレオ 1 時間でおよそ 600 MB になるので、スタジオから出るものはまず AAC・Opus・MP3 に符号化されますし、可逆配信は FLAC が引き取りました。同じサンプルをおよそ半分の容量に収め、きちんとしたメタデータの仕組みを持つからです。短いシステム音、サンプルライブラリ、音声コーパス、そしてマイコンやゲームエンジンがデコーダ抜きで鳴らさなければならないものについては、今も WAV が既定です。生の PCM は CPU をまったく使わないからです。本当の制約は 4 ギガバイトの天井と、標準的なメタデータの枠組みが無いことの 2 つで、放送の現場が RF64 や BWF へ移ったのはその両方が理由です。
WAV ファイルをこのサイトで開く
どれもブラウザ内で動きます。ファイルが端末から出ることはありません。
関連する形式
WAV と混同しやすい形式です。先頭バイトを見比べてください。