Platform SDK: DirectX |
ここでは、C++ でのアプリケーション開発について説明する。
ほとんどのアプリケーションは DirectSound ミキサーを使用する。このミキサーはほぼすべてのミキシングの要求を満たし、利用可能なすべてのハードウェア アクセラレーションを自動的に活用する。しかし、DirectSound が提供しない機能をアプリケーションが必要とする場合は、プライマリ サウンド バッファへの書き込みアクセスを取得し、そこでストリームを直接ミキシングできる。
カスタム ミキサーを実装するには、アプリケーションは最初に DSSCL_WRITEPRIMARY 協調レベルを設定し、プライマリ サウンド バッファを作成しなければならない。(「プライマリ バッファへのアクセス」を参照。)次にバッファをロックし、データを書き込み、バッファをアンロックし、他のバッファと同じように再生する。ただし、DSBPLAY_LOOPING フラグを指定しなければならない。さもないと IDirectSoundBuffer::Play の呼び出しが失敗する点に注意すること。
次の例は、アプリケーションがカスタム ミキサーを実装する方法を示す。サウンド デバイスがデータ ブロックの再生を繰り返さないよう、AppMixIntoPrimaryBuffer 関数を一定の間隔で呼び出さなければならない。CustomMixer 関数はアプリケーションが定義した関数であり、アプリケーションが定義した AppStreamInfo 構造体の指定に従って複数のストリームをミキシングし、結果を指定のポインタに書き込む。
BOOL AppMixIntoPrimaryBuffer( LPAPPSTREAMINFO lpAppStreamInfo, LPDIRECTSOUNDBUFFER lpDsbPrimary, DWORD dwDataBytes, DWORD dwOldPos, LPDWORD lpdwNewPos) { LPVOID lpvPtr1; DWORD dwBytes1; LPVOID lpvPtr2; DWORD dwBytes2; HRESULT hr; // 書き込みポインタを取得する。 hr = lpDsbPrimary->lpVtbl->Lock(lpDsbPrimary, dwOldPos, dwDataBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); // DSERR_BUFFERLOST が返された場合、復元とロックの再試行を行う。 if (DSERR_BUFFERLOST == hr) { lpDsbPrimary->lpVtbl->Restore(lpDsbPrimary); hr = lpDsbPrimary->lpVtbl->Lock(lpDsbPrimary, dwOldPos, dwDataBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); } if SUCCEEDED(hr) { // データをミキシングして、返されたポインタに書き込む。 CustomMixer(lpAppStreamInfo, lpvPtr1, dwBytes1); *lpdwNewPos = dwOldPos + dwBytes1; if (NULL != lpvPtr2) { CustomMixer(lpAppStreamInfo, lpvPtr2, dwBytes2); *lpdwNewPos = dwBytes2; // ラップ アラウンドした (先頭へ戻った) ため。 } // データを解放して DirectSound へ返す。 hr = lpDsbPrimary->lpVtbl->Unlock(lpDsbPrimary, lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); if SUCCEEDED(hr) { return TRUE; } } // ロックまたはアンロックが失敗した。 return FALSE; }