Microsoft DirectX 8.0 (C++)

ウェーブ ファイルの読み込み

ここでは、DirectMusic ローダーおよびパフォーマンスを使用せずに、ウェーブ ファイルのデータを DirectSound バッファにロードする方法について説明する。ほとんどのアプリケーションでは、ウェーブ データやバッファを直接処理する必要はない。ウェーブのロードや再生の優先される方法については、「オーディオ データのロード」および「サウンドの再生」を参照すること。

ウェーブ ファイルは RIFF (Resource Interchange File Format、リソース交換ファイル フォーマット) を採用しており、ヘッダー情報 (たとえばサウンド サンプルのウェーブ フォーマット) とデータ (サンプル自体) を保持する、任意の数のチャンクによって構成されている。Win32 API は、RIFF ファイルを開いたり閉じたりするための関数や、チャンクの検索関数などを提供する。これらの関数の名前はすべて "mmio" で始まる。

DirectSound API は、ウェーブ ファイルを処理するためのメソッドを備えていない。ただし、多くの SDK サンプル アプリケーションで使用される Dsutil.cpp ファイルは、次のパブリック メソッドを持つ CWaveFile クラスを実装する。

ウェーブ ファイルを読み込む最初のステップは、CWaveFile::Open メソッドを呼び出すことである。このメソッドは、ファイルが RIFF フォーマットであることを確認し、ウェーブ フォーマットに関する情報を取得する。パラメータはファイル名、フォーマットの NULL、および WAVEFILE_READ フラグである。このメソッドは HRESULT を返す。

次のコードは、ウェーブ ファイルを開く。

CWaveFile waveFile;
 
if (FAILED(waveFile.Open("mywave.wav", NULL, WAVEFILE_READ)))
{
    waveFile.Close();
}

これで、アプリケーションはファイルからセカンダリ バッファへのコピーを開始できる。通常は、ウェーブのフォーマットを取得するまではサウンド バッファを作成しない。次のコードは、ファイル内の全データを保持するのにちょうどよいサイズのスタティック バッファを作成する。

LPDIRECTSOUNDBUFFER  lpdsbStatic;
DSBUFFERDESC         dsbdesc;
 
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); 
dsbdesc.dwSize = sizeof(DSBUFFERDESC); 
dsbdesc.dwFlags = 0; 
 
/* ウェーブ フォーマットとデータ チャンクのサイズは、
// CWaveFile::Open が呼び出された後、CWaveFile に格納される。 
 
dsbdesc.dwBufferBytes = waveFile.GetSize(); 
dsbdesc.lpwfxFormat = waveFile.m_pwfx; 
 
// lpds は有効な IDirectSound8 ポインタである。
 
if FAILED(lpds->CreateSoundBuffer(&dsbdesc, &lpdsbStatic, NULL))
{
    // エラー処理。
    .
    .
    .
}

これで、バッファにデータを書き込むことができる。この場合、アプリケーションはデータのストリーミングを行わないので、バッファ全体が先頭からロックされる。ラップアラウンド (先頭へ戻る) も発生しないので、必要なのは 1 つのポインタとバイト カウントである。

LPVOID lpvAudio1;
DWORD  dwBytes1;
 
if FAILED(lpdsbStatic->Lock(
        0,              // ロック開始のオフセット。
        0,              // ロックのサイズ。この場合は無視される。
        &lpvAudio1,     // ロック開始のアドレス。
        &dwBytes1,      // ロックされるバイト数。
        NULL,           // ラップアラウンドの開始。使用されない。
        NULL,           // ラップアラウンドのサイズ。使用されない。
        DSBLOCK_ENTIREBUFFER))  
{
    // エラー処理。
    .
    .
    .
}

CWaveFile::Read メソッドを使って、次のようにバッファに書き込むことができる。

DWORD dwBytesRead;
 
waveFile.Read((BYTE*)lpvAudio1, dwBytes1, &dwBytesRead);
 

最後にアプリケーションはバッファをアンロックし、ウェーブ ファイルを閉じる。

lpdsbStatic->Unlock(lpvAudio1, dwBytes1, NULL, 0);
waveFile.Close();

ストリーム バッファの場合は、通常、再生カーソルの動きによって決定される一定の間隔で CWaveFile::Read を呼び出す。バッファのロックされた部分がラップ アラウンドしている場合は、ロックの各セグメントごとにこのメソッドを呼び出す。

ストリーミングの詳細については、「ストリーム バッファの使い方」および「再生バッファの通知」を参照すること。

CWaveFile クラスの使い方のその他の例については、DirectX SDK インストールに含まれるサンプル アプリケーションを参照すること。