第1回 DirectSound(初期化・後処理)


はじめに…。

 いきなりですが、DirectXのライブラリ作成を主にやっていきたいと思います。
だから一番とっつきやすいDirectSoundから作っていこうと思いますf(^^;
某専門の授業にちゃんと出てた方は、見る必要も無いと思いますが、なにせ私は何ヶ月かぶりに触るものでちょっと自身ないです(ぇ
 だから、復習ついでにライブラリを作れたらな〜という感じです。
本来は、WindowsプログラミングやCOMの概念なんかも絡むはずなんですがサッパリわからんので自分で調べてください(汗

COMモデル

 復習もかねているのでもちろん授業用ノート見ながらやってますw
んで、COMモデルの事について書いてあったので一応書いときましょう☆(自分では覚えてなかったんかい!)

・初期のDirectXでは、デフォルトがDirectX1のインターフェースだったが、DirectX8からは、デフォルトがDirectX8という設定になった。
・APIからDirectXにオブジェクト作成命令を出すとオブジェクトのアドレスが返ってくる。

あ〜、なんかCOMモデルっていう表題にした割には全然内容がちがうw
だからって絵とかつけるのもなんなので、頑張ってくださいm(__)m
プログラマーは日々勉強だ(ぉぃ

ということで…。

・必要なファイル DirectSoundに関してなら最初の内は、この2つで間に合うでしょう。
必要になったら随時追加していきます。

 そして、DirectX(というか自分の知る限り…)では決まり文句とも言って良いでしょう。
まず、DirectXはCOMの仕様によって出来てるらしいので…、DirectX(今回はDirectSoundね☆)を扱うためのポインタをグローバルで作成します。

IDirectSound*   g_lpDirectSound;    // DirectSoundオブジェクトへのポインタ
または、
LPDIRECTSOUND   g_lpDirectSound;	// DirectSoundオブジェクトへのポインタ
のようにどちらかでインターフェースへのポインタを作ってくれれば良いです。
ヘッダでtypdefされているのでどちらでも可能です。
個人的に良く使うのは後者の方かな

このポインタに「オブジェクト作ってくれよ〜!」って、APIを呼びながら叫ぶと勝手にオブジェクトが出来てアクセスが出来るようになります(まぁ、ここらへんはC++頑張ってw
なんでこんなに面倒くさい事をしなくちゃあならないかって言うとある意味でDirectXというのを言語に依存したくないためみたいです。だからDirectXは、CだろうがC++だろうがVBからだってアクセス出来ちゃうわけです。
そこら変は、COMのおかげって事で…。

んで、参考までにCとC++からの呼び出し方の違いを書いておきます。(ぉ
C++          g_lpDirectSound->Release();
C              g_lpDirectSound->lpVtbl->Release(g_lpDirectSound);
C(マクロ版)  IDirectSound_Release(g_lpDirectSound);
と、↑こんな感じらしいです。(ぉぃ
面倒くさいのでソースを書くときの拡張子は.cppで書くことにします。
ただ、タイプ数は少ないのですがC++のエラーは半端じゃなく面倒くさいことは頭に入れておきましょう♪

余談ですが、C++でクラスを作る時に最後のブロックの後に";"を入れておくのを忘れずに☆
あのエラーは嫌いです。
それにテンプレートなんか絡めた日にゃあもぅ叫びたくなりますw
慣れれば可愛いものなんだが…。

初期化と後処理

 プログラムは、「前処理」「主処理」「後処理」とはよく言ったものです。
というかプログラミングをする時は、出来るだけこの3つの流れになるように心がけながらコーディングしてるつもりです。(っていうか、その前に設計をしろ(--;
そこで、プロトタイプぐらいは決めておかないといけないだろ〜ということで↓

INT     InitializeDS(HWND hWnd);    // 初期化
void    ReleaseDS();                // 後処理
と一応最初は、このぐらいが無難でしょう…。なにせ全く考えてません(殴

じゃあ、プログラムしましょうか。ってことで↓

int InitializeDS(HWND hWnd)

{
    INT     ret = 0;
    HRESULT hr;
    
    // オブジェクト作成
    hr = DirectSoundCreate(NULL, &g_lpDirectSound, NULL);
    if (FAILED(hr)) {
        ret = -1;
        goto DS_INITIALIZEDS_ERR;
    }
    
    // 協調レベル設定
    hr = g_lpDirectSound->SetCooperativeLevel(hWnd, DSSCL_NORMAL);
    if (FAILED(hr)) {
        ret = -2;
        goto DS_INITIALIZEDS_ERR;
    }
    
DS_INITIALIZEDS_ERR:	// エラー時
    
    return ret;
}

void ReleaseDS(void)

{
    if (g_lpDirectSound != NULL) {
        g_lpDirectSound->Release();
    }
}

InitializeDS()は、まずオブジェクトを作るAPIを呼んでオブジェクトを指定したポインタに作ってもらってからSetCooperativeLeve()で音をどのくらいの制御下で出力するかというアプリケーション間での協調度の設定をしています。ヘルプにはSetCooperativelevelは、オブジェクト作成直後に呼ぶだとか書いてあるので処理上一緒にしてしまいました。
ReleaseDSは、単にRelease()を呼んで開放やCOMの参照を1減らしてるだけでしょう。だから、あんま考えないで終了する時はこう書くんだなと常套手段として覚えても構わないんじゃないかな。っていうか他に説明のしようがないしな…。

例外処理は未だに悩み所です…。
う〜ん、これもしっかりとスタイルを決めてないからだな…。(--#
とりあえず、エラーが発生したらエラーコードを入れて関数の最後まで一気に飛ばしてます。
「CゲンガーのC言語によるC言語のための例外処理」なぁ〜んてお題もありかもw
DirectXで使用されるオブジェクトは大抵Object->Release()っていう呼び出しをするからReleaseDS()に関しては、↓みたいなマクロを作っちゃって1行だけってのもありかもね…。っていうか常識なのかもな〜(汗
#define RELEASE(o)      {if (o) {(o)->Release();}}
最後に今回作った(?)気もしないけど一応サンプルです。
サンプルにもならんが、これからどう変わっていくか見るのには良いかな〜とおもってねw