Ryuzのプログラミング講座
<第1回 Waveファイルのフォーマット編>

いったい誰が読むのかさっぱり分からないまま突発的に始まったプログラミング講座もついに第1回を迎えたわけですが、今回は Windows でおなじみのWAVEファイルについてお勉強していきましょう。


WAVEファイルの基本構造

えーと、まずWAVEファイルの構造ですが、これはRIFF(Resource Interchange File Format)と呼ばれるものでして、チャンクと呼ばれるブロックと、その中に含まれるサブチャンクと呼ばれるブロックで構成されています。

ではいったいどういうふうになっているかというと、WAVEファイルの場合、

内容バイト数  
"RIFF"の4文字4 RIFFヘッダ
RIFFデータサイズ4 
"WAVE"の4文字4 RIFFデータ
"fmt "の4文字4サブチャンク
fmt データのサイズ4
fmt データ---
"data"の4文字4サブチャンク
dataデータのサイズ4
dataデータ---

と言った構造をしています。ちなみにデータサイズの項はリトルエンディアンス(下位バイトから順に格納)になっているという86系のCPUを使ってる人には有り難い仕様です。

ちなみに時々、"fmt "チャンクと"data"チャンクの間に"fact"チャンクというものがあるものがあります。詳しくは知らないのですが、実際の演奏とは直接関係ないので読み飛ばしても構わないはずです。

実はWindowsにはこのRIFFファイルを簡単に扱う「マルチメディア ファイルI/O」というAPI群があります。RzPlayerでも録音部分にはこれを使っていますが、ここでは説明しませんので、興味のある方はがんばってSDKを読みましょう。


fmtサブチャンクのデータ

ここにはWAVEファイルについての情報が入っています。

以下にその内容を示します

内容バイト数
フォーマットタグ2
チャンネル数2
サンプル/秒4
バイト/秒4
ブロック境界2
ビット/サンプル2
拡張情報サイズ2
拡張情報---
フォーマットタグ
WAVEファイルのフォーマットを示す2バイトの数値です。
非圧縮のPCMフォーマットの場合ここが1になります。

チャンネル数
モノラルの場合は1ステレオの場合は2になります。

サンプル/秒
サンプリングレートです。例えば44.1kHzで録音した場合44100となります。

バイト/秒
一秒サンプリングするのに必要な必要な平均データ転送速度を示します。
一秒間の録音に必要な何バイト数と考えて問題無いはずです。

ブロック境界
WAVEデータのブロック境界を示します。
例えばPCMフォーマットでステレオ16bitなら4となります。
データの加工はこの単位で行なってください。圧縮されたファイルでもこの境界を守ればカット&ペーストが出来るはずです。

ビット/サンプル
1サンプルに何ビット必要かを示します。
ただし気をつけなければならないのは、これはチャンネル毎のビット数です。モノラルでもステレオでも変わりませんので注意が必要です。

拡張情報サイズ
この項目移行はフォーマットタグが1のものには存在しません。
拡張情報のデータサイズです。

拡張情報
圧縮されているフォーマットのものなどがその拡張情報を格納するための拡張領域です。

dataサブチャンクのデータ

さて、いよいよ肝心のデータ部分です。圧縮がかかったものについてはここでは触れません(私が知りません)。すなわちPCMフォーマットの場合ですね。

まずデータの表現ですが、8bitと16bitの場合で表現方法が違います。8bitの場合は0〜255まで、16bitの場合は−32768〜32767までとなります。早い話しが8bitのときは符号なしで、16bitのときは符号付きで表します。

次にデータの中の格納されかたですが、モノラルの場合はただひたすらそれらのデータが並んでいるだけ、ステレオの場合はまず左側のデータがあってその後に右側のデータが来ます。後はこれの繰り返しですから左右交互にデータが並ぶことになります。

WindowsでのWAVEファイルの再生方法

さて、ここまでWAVEファイルのフォーマットを見てきたわけですが、いよいよこれを再生する方法です。
OSはWindowsとします。ここまで読んできちんとWAVEファイルの構造を理解していれば再生はそれほど難しいものではありません。

前提としてここに"Sample.wav"というWAVEファイルがあったとします。C言語でこれを再生するルーチンを書くと。


sndPlaySound("Sample.wav", SND_SYNC);


とまあ、このようになりま......






長い説明の割にはくだらないオチだったなぁ。
果して第2回はあるのだろうか、その答えは次回わかります。

ちなみに内容に間違いがあっても私は責任を負いませんのでどうぞよろしく。


Ryuzのページに戻る