DirectSoundの技術的理解

DirectSound を利用してサウンド再生を行う場合、プログラムからサウンド・バッファーを確保する必要があります。このサウンド・バッファーはDirectSound API を通じて獲得します。サウンド再生の能力はサウンド・バッファーを確保する際に決定します。「サウンド・バッファーの能力=サウンド再生の能力」です。サウンド・バッファーの最大能力はDirectSound が提供する範囲で決ます。このサウンド・バッファーの実体はDirectSound ではIDirectSoundBuffer8 と呼ばれています。

DirectSound に関する技術文章はMSDN — Microsoft Developer Network を通じて公開、提供されています。ここからは、IDirectSoundBuffer8 に関する文章を読みDirectSoundについての技術的理解を進めていきます。

ここで、注意すべきことがあります。IDirectSoundBuffer8 に関する文章を読み、応用するには多くの知識を要求されます。DirectSound で定義される用語、コンピューター・サウンド関連の用語、プログラミング用語といった広範囲の知識を理解する必要があります。次に、「文章の迷宮」を探検する心意気が必要です。ここから先の文章は、私の探検手記兼、探検案内でもあります。

まず、プログラムがIDirectSoundBuffer8 を取得するには

このインターフェイスを取得するには、IDirectSound8::CreateSoundBuffer メソッドを使って IDirectSoundBuffer を取得し、IID_IDirectSoundBuffer8 を IDirectSoundBuffer::QueryInterface に渡す。

と、あります。ですから次にIDirectSound8::CreateSoundBuffer のページを読みます。ページは、このメソッドを呼び出すのに必要な引数について解説しています。pcDSBufferDesc 引数の項目にはDSBUFFERDESC 構造体を使用すると書いてあります。ほかの項目はプログラムを書く上で必要なことが書いてあります、今の時点ではこれらは無視します。

次に、DSBUFFERDESC 構造体のページを読みます。結論から言いますと、このページに書いてあることがIDirectSoundBuffer8 の再生能力を決定付けるものです。ここでは、構文の項目にある

DWORD dwFlags; 
DWORD dwBufferBytes;

だけが重要です。ほかの事柄はゲーム・プログラミングの観点からは重要ではありませんし、使いません。こう断言した理由は後ほど述べます。

まず先に、dwBufferBytes から読み解きます。これはバッファーのサイズ、つまりサウンド・データーのサイズについてです。この項目には

セカンダリ バッファで許容される最小サイズと最大サイズは、dsound.h で定義されている DSBSIZE_MIN と DSBSIZE_MAX である。

と書いてあります。RubyInstaller for Windows で配布しているDevelopment Kit に付属してたdsound.h には

#define DSBSIZE_MIN 4
#define DSBSIZE_MAX 0xFFFFFFF

とありました。つまり、最小サイズは4バイト、最大サイズは約268MBです。

最大サイズのほうは実用的に問題はありません。CD音質のサウンド・データーであれば25分収録できるサイズです。しかし、最小サイズについては話が続きます。まず、0バイトにできません。当たり前と思えるかもしれませんがプログラミング的には注意が必要です。次に、dwFlags の項目にある表のDSBCAPS_CTRLFX の説明には

また、バッファには、少なくとも DSBSIZE_FX_MIN ミリ秒のデータを格納できるサイズが必要である。

と、書いてあります。先ほどのdsound.h にはDSBSIZE_FX_MIN 定数が記載されていませんでしたが、その数値は調べることができます。値は150です。バッファでのエフェクトの設定 のページに

DirectSound では、150 ミリ秒未満のデータしか保持できないエフェクト使用可能なバッファは作成できない。この値は、DSBSIZE_FX_MIN として定義されている。

と書かれているからです。もし、DirectSound が提供するサウンド・エフェクトを利用する場合は、この条件を守る必要があります。また、このDSBSIZE_FX_MIN の単位はミリ秒です。本当に必要なバッファー・サイズはプログラムで計算して求める必要があります。

dwBufferBytes については以上です。次はdwFlags の項目です。多くのフラグが用意されていますが、次の条件を元にすれば理解すべきフラグはわずかです。

  1. サウンド・バッファーはセカンダリー・バッファーとしてのみ使う。プリマリー・バッファーとしての利用はしない。複数のサウンドを並列して再生したければセカンダリー・バッファー以外の選択肢はない。
  2. 3Dサウンド機能を使用しない。3D音響をデザインするには専用のツールとプログラミング環境が必要となる。そういった開発環境を手に入れられるの立場ならば、この文章自体を読む必要がないだろう。
  3. サウンド・ハードウェアーに関する機能を使用しない。DirectSound はDirectX9 からはソフトウェアーによる実装にシフトしている。もし、サウンド・ハードウェアーを利用できたとしても、それに関する知識がなければ制御できない。そして、サウンド・ハードウェアーごとに性能や特徴が違うため個別の知識が必要になる。

これでDSBCAPS_CTRL3D, DSBCAPS_LOCDEFER, DSBCAPS_LOCHARDWARE, DSBCAPS_MUTE3DATMAXDISTANCE, DSBCAPS_PRIMARYBUFFER, DSBCAPS_STATIC の各項目について理解する必要がなくなります。3D音響に関しては3Dのゲームを作成しているならば関心があるかもしれません。ここでは、まず音を鳴らすことに集中していきます。

それでも多くのフラグが残りました。フラグの数が多いのには理由があります。音響処理は昔のCPUにとっては負荷のかかる処理でした。ですから機能を細かく分け、使わない機能をオフにしてサウンド再生処理を軽量化するのが目的だったのでしょう。今は状況が変わりました、CPUの性能は向上しましたし、ゲーム・サウンドにおいて音響処理を経ないサウンドは考えられません。

音量調整のDSBCAPS_CTRLVOLUME 、左右の定位置を決めるDSBCAPS_CTRLPAN 、再生時の音程を決めるDSBCAPS_CTRLFREQUENCY 、サウンド・エフェクトの機能を使うDSBCAPS_CTRLFX はプログラム時に機能を使うか使わないか各自で判断できる内容です。DSBCAPS_CTRLPAN は3D音響と同時に使えません。DSBCAPS_CTRLFX はサウンド・データーのフォーマットに制限があります。それと、先ほどの150ミリ秒以上のバッファー・サイズが必要です。

DSBCAPS_CTRLPOSITIONNOTIFY, DSBCAPS_GETCURRENTPOSITION2 はプログラミングに関する内容です。常に立てておけばいいでしょう。この2つについては機能の選択よりも、機能そのものを理解する必要があります。

DSBCAPS_GLOBALFOCUS, DSBCAPS_STICKYFOCUS についてはアプリケーションとしてのサウンド再生動作を決定します。表の説明に書いてある通りなのですが、解説をするには“DirectSound を使っているアプリケーション”について理解する必要があります。ここでの理解とは、一般的な状況ではどうなるか? 具体的にDirectSound を使っているアプリケーションと使っていないアプリケーションを挙げることを指します。現時点では私には、それを解説する能力はありません。

最後にDSBCAPS_LOCSOFTWARE ですが、これは使用すべきです。サウンド・ハードウェアーが関わるとDirectSoundのサウンド再生をプログラム側から柔軟に利用しずらくなります。

ここまでで、IDirectSoundBuffer8 を取得するのに必要な事がわかりました。しかし、取得を行うにはまだ十分ではありません。実際に音を鳴らす所までを調べて、初めてIDirectSoundBuffer8 の機能設定を決定ができるようになります。

続きは、別の記事とします。

Show your support

Clapping shows how much you appreciated しのかろ’s story.