カクタスソフトウェア
カクタスソフトウェア
サウンド MIDI マルチメディア アプリケーション

ウェーブバッファ

ウェーブバッファはウェーブデータを再生デバイスへ書き込むために用いるバッファです。

WAVEHDR構造体

WAVEHDR構造体はウェーブバッファおよびその他必要な情報一式を格納した構造体です。再生デバイスへはWAVEHDR構造体の参照を伝えます。この構造体は再生と録音の双方のプロセスで用いられます。

typedef struct {
    LPSTR    lpData;
    DWORD    dwBufferLength;
    DWORD    dwBytesRecorded;
    DWORD    dwUser;
    DWORD    dwFlags;
    DWORD    dwLoops;
    struct wavehdr_tag * lpNext;
    DWORD    reserved;
} WAVEHDR, *LPWAVEHDR;

LPSTR lpData

ウェーブバッファへのポインターです。

DWORD dwBufferLength

ウェーブバッファのサイズです。単位はBYTEです。

DWORD dwBytesRecorded

録音された有功なデータサイズです。単位はBYTEです。再生プロセスでは用いられません。

DWORD dwUser

アプリケーションが自由に使える32Bitのエリアです。

DWORD dwFlags

バッファに関する情報を示すフラグです。以下のフラグが定義されています。

 フラグ 意味 
WHDR_PREPARED バッファが、waveInPrepareHeader()関数あるいはwaveOutPrepareHeader()関数によって準備されたことを示します。このフラグは、Windowsによってセットされます。
WHDR_DONE 再生時、バッファの再生が終了した事を示します。録音時、録音されたデータでバッファが一杯になった事を示します。このフラグは、デバイスドライバーによってセットされます。
このフラグがリセットされている間は、バッファがデバイスドライバーの管理下にあるため、アプリケーションはバッファの開放などを勝手に行ってはなりません。
WHDR_INQUEUE バッファが再生用キューに登録されたことを示します。このフラグは、Windowsによってセットされます。
WHDR_BEGINLOOP
WHDR_ENDLOOP
ループ再生させたい時に指定します。最初のバッファにWHDR_BEGINLOOP、最後のバッファにWHDR_ENDLOOPを指定します。これは再生プロセスの時のみ有効です。

DWORD dwLoops

ループ再生の回数を指定します。dwFlagsのループ再生フラグと共に用います。これは再生プロセスの時のみ有効です。

struct wavehdr_tag * lpNext

システムが内部で使用。

DWORD reserved

システムが内部で使用。

初期化

WAVEHDR構造体を初期化するには最低限以下の操作を行う必要があります。

ウェーブバッファの数

ウェーブデータを再生するために用いるバッファは、理屈上2つあれば動作することが分かります。しかし、これは必要なタイミングにCPUパワーを利用できるという条件があっての話です。

コンピュータ上には通常、複数のタスクが平行して走っていますが、その中にはある期間CPUを独占してしまうタスクが存在しています。仮想メモリのスワッピングやデータの保存などでシリアライズ機能が働いている場合がそうです。これらの処理は、マルチタスクで動作させるとデータの破壊や矛盾を起こすため、処理が一段落するまで制御が他へ移りません。

運悪くこれらの処理が次のウェーブデータを必要とするタイミングで起こると、バッファの準備が間に合わず、音が途切れてしまいます。

この不具合に対処するには、2つの方法が考えられます。

しかし、CPUの負荷は分散させた方が有利という考えから、後者のバッファの数を多くするという方法を取るのが一般的の様です。

バッファの数は具体的にどのくらいが良いかという問いには、絶対にこれこれという答えはありません。多ければそれだけ安心ですが、コストが高くなります。経験的に安定して動く数を設定することになります。

筆者は、4つくらいを選ぶことが多いです。

ウェーブバッファのサイズ

ウェーブバッファのサイズは、一般的に任意に決めることができます。ただ注意点として、大きすぎると、データを準備する時のCPU負荷が集中してしまう、また小さすぎるとオーバーヘッドが大きくなり再生が不安定となる、等の問題が起こります。これらの事を考え、64KByte辺りが良く用いられているようです。

サンプリング周波数48000Hzで16Bitのステレオというのが考えられる最大のデータ消費速度ですが、この場合、192KByte/Secとなります。つまり、64KByte当たり約341mSec。また最小では、11025Hzで8Bitのモノラルで、約10.8KByte/Sec。つまり、64KByte当たり約5.9Secとなります。

ウェーブフォーマットによって、上下17倍程度の速度差があることが分かります。サンプリング周波数に応じてバッファサイズを変える方法もありますが、この程度の差であれば、サイズ固定でも問題ないと思われます。むしろ最悪の条件でも動作できるバッファサイズとバッファ数を設定することの方が重要でしょう。

ドキュメントの先頭へ

カクタスソフトウェア 技術協力 資料室 資料室の広場 SourceForge.jp お問い合わせ