初期化・解放
忘れないうちに昔書いた代物をコピペしておきましょうかね。
…これはちょいと整理して書き直したいかもしれず。
・DirectSoundの初期化(ならびに解放)
「COMを使用する」方法と、
「DirectSoundCreate()を使用する」方法とがありますが、
とりあえず、わかりやすい後者の方を。
(ちなみに、僕のライブラリでは前者を使っています。)
「DirectSound」の初期化をするだけであれば、
・DirectSoundCreate()でオブジェクト作成
・SetCooperativeLevel()で協調レベル設定
の二つのプロセスを踏んでやるだけでOKです。
あくまでも、「DirectSoundの初期化のみ」なので、まだ音は鳴らせません。
具体的には…、
…こんな感じですかね。
// DirectSound8のオブジェクトを宣言しておく
LPDIRECTSOUND8 p_ds_object;
// ウィンドウのハンドルを貰っておく
// →本当は宣言はしない
HWND window_handle;
// DirectSound8のオブジェクトを作成
DirectSoundCreate( NULL, &p_ds_object, NULL );
// 協調レベルを設定
p_ds_object->SetCooperativeLevel( window_handle, DSSCL_PRIORITY );
注:実際に使う際は
必ず返り値を貰ってきて、関数が成功したかを確認してください。
文章だと面倒なので、関数の説明は表で済ませてしまいます。
DirectSoundCreate8( GUID*, DIRECTSOUND8 **, NULL ) |
|
引数その1 |
オブジェクトを作成するデバイスのGUID |
引数その2 |
オブジェクトのポインタ(のポインタ) |
引数その3 |
予約領域(→絶対に「NULL」を入れておくこと!) |
DIRECTSOUND8::SetCooperativeLevel( HWND, long ) |
|
引数その1 |
アクティブにしたいウィンドウのハンドル |
引数その2 |
協調レベルの値(定数) |
「定数」のところは桁だけみて「long」ってことにしておきました(苦笑)
おそらく本当は、「DWORD」あたり…?
…で、これだけ見て
何となくでもわかればいいのですが、
…多分わからない(かなりアバウト+不正確(苦笑))ので
ポイント毎にツッコミをば。
・DirectSoundCreate8()
まずは引数その1。
「GUID」って何ぞや?(笑)
→「Global Unique IDentifier」の略だそうです。
早い話が「認証番号」「型番」ってところですかね。
しかし、ここで「具体例」に注目して下さい。
…「NULL」が入っています。間違いではないですよ(笑)
詳しいことは後述(…というか次回?(笑))しますが、
ここに「NULL」を指定すると、「プライマリサウンドドライバ」のGUIDを勝手に入れてくれます。
なので、特に気にしないのであれば、この引数は何も考えずに「NULL」でも構いません。
次に引数その2。
「ポインタ」なのか、「ポインタのポインタ」なのか…と(汗)
正確には後者になるのですが、
オブジェクトは普通は具体例のようにポインタを基本として扱うので、
あまり「ポインタのポインタ」であることを意識する必要はないかな…と。
・SetCooperaticeLevel()
ツッコミの前に、
この関数は前述の「DirectSoundCreate8()」が成功していないと使用できません。
メンバ関数なので、当たり前と言えば当たり前ですが(笑)
引数その1。
「アクティブにしたいウィンドウ」って?
要するに、この「DirectSoundを使わせたいウィンドウ」のことです。
…と言っても、
一つのアプリで複数のウィンドウを作成するのは稀だと思われるので、
この初期化の前にウィンドウを作成して、そのハンドルを渡すだけでOKです。
これは同時に、ウィンドウが作成されていないとDirectSoundは初期化できないということも表していますね。
(他のDirectXの初期化においても共通だったりします。)
引数その2。
これは、
「DSSCL_WRITEPRIMARY」「DSSCL_PRIORITY」「DSSCL_NORMAL」
の3つから選んで使います。
「協調レベル」と言っても、
早い話が「(処理の)優先順位」のことなので、
上記の3つを言い換えると、
「最高優先順位」「優先順位:高」「優先順位:低」
となります(…多分(汗))
「最高優先順位」を使いたいところですが、
いろいろと面倒なことが多いのと、何故か僕の環境だと設定に失敗する(笑)ので
僕は「DSSCL_PRIORITY」を設定しています。
実際問題、「DSSCL_PRIORITY」でほとんど問題ないでしょう。
わざわざ「DSSCL_NORMAL」を選ぶ利点もあまりないと思われるので。
…結局ほとんど文章になってしまったわけですが…(汗)
…あ、わざわざ「赤字」で書いておいた返り値のことですが、
「FAILED()」(または「SUCCEED()」)を使うか、
HRESULT型の変数で返り値を貰っておいて、「DS_OK」か調べればOKです。
こんな感じで。
// 返り値用変数
HRESULT return_value;
// DirectSound8のオブジェクトを作成
return_value = DirectSoundCreate( NULL, &p_ds_object, NULL );
// 関数は成功した?
if( return_value != DS_OK )
{
// 失敗だった…。
// →即座に強制終了へ
return -1;
}
「FAILED()」等に関してはまた今度ということで…(汗)
アバウトで申し訳ない…(汗)
それと、初期化したら
必ず後述する「解放処理」を行ってください。
でないとメモリに負担が掛かります。 …というか、最悪壊れます。(苦笑)
・DirectSoundの解放
こちらは至って簡単です。
…以上です(笑)
// (存在するようなら)DirectSound8オブジェクトを解放
if( p_ds_object )
{
p_ds_object->Release();
// ついでにポインタも無効にする
p_ds_object = NULL;
}
実際に使用する際は、更にマクロを使って
としてやると、
// 解放用マクロ
#define RELEASE( object ) if(object){object->Release();object=NULL;}
// DirectSound8オブジェクトを解放
RELEASE( p_ds_object );
一行に収まり、見た目にもコンパクトになるので
非常に便利です。
…何やら、ものすごい量になってしまいました…(大汗)
…こんな調子で全部書けるんでしょうかね…。