Platform SDK: DirectX |
ここでは、C++ でのアプリケーション開発について説明する。Visual Basic については、「DirectMusic Visual Basic チュートリアル」を参照すること。
このステップでは、関数 LoadMIDISegment を実装する。この関数は前のステップで作成した IDirectMusicLoader へのポインタを取得し、そのポインタを使って、MIDI ファイルからデータをカプセル化したセグメント オブジェクトを作成する。
IDirectMusicSegment* LoadMIDISegment(IDirectMusicLoader* pLoader, WCHAR wszMidiFileName ) { DMUS_OBJECTDESC ObjDesc; IDirectMusicSegment* pSegment = NULL;
演奏する MIDI ファイルはすべて、現在の作業ディレクトリに保存されているとする。検索ディレクトリを設定して、ローダーにディレクトリを指示する必要がある (検索ディレクトリをほかの場所に変更しない場合、この操作が必要なのは 1 度だけである。ファイルをロードするごとに指定する必要はない)。
char szDir[_MAX_PATH]; WCHAR wszDir[_MAX_PATH]; if(_getcwd( szDir, _MAX_PATH ) == NULL) { return NULL; } /* 次のマクロを使って、マルチバイト フォーマットから Unicode に変換する。 #define MULTI_TO_WIDE( x,y ) MultiByteToWideChar( CP_ACP, \ MB_PRECOMPOSED, y, -1, x, _MAX_PATH ); */ MULTI_TO_WIDE(wszDir, szDir); HRESULT hr = pLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wszDir, FALSE); if (FAILED(hr)) { return NULL; }
次に DMUS_OBJECTDESC 構造体で、ロードするオブジェクトを記述する。
ObjDesc.guidClass = CLSID_DirectMusicSegment; ObjDesc.dwSize = sizeof(DMUS_OBJECTDESC); wcscpy( ObjDesc.wszFileName, wszMidiFileName ); ObjDesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME;
ここで、オブジェクトをロードし、IDirectMusicSegment インターフェイスのクエリを行う。この操作は、IDirectMusicLoader::GetObject を一度呼び出すことで実行される。オブジェクトをロードすると、トラックが初期化され、MIDI データの再生を準備するために必要なすべての作業が行われる点に注意すること。
pLoader->GetObject(&ObjDesc, IID_IDirectMusicSegment2, (void**) &pSegment);
セグメントをスタンダード MIDI ファイルとして演奏するには、ここでバンド トラックにパラメータを設定する必要がある。dwGroupBits メソッド パラメータに -1 (または、0xFFFFFFFF) を渡し、IDirectMusicSegment::SetParam メソッドを使ってトラックを検索する。
g_pMIDISeg->SetParam(GUID_StandardMIDIFile, -1, 0, 0, (void*)g_pPerf);
DirectMusic がプログラム変更およびバンク選択を処理する方法は、スタンダード MIDI ファイルの場合と、DirectMusic 用にオーサリングされた MIDI コンテンツの場合では異なるため、このステップが必要となる。GUID_StandardMIDIFile パラメータは、音色をダウンロードする前に設定しなければならない。
次のステップは、音色のダウンロードである。デフォルトのソフトウェア シンセサイザは、General MIDI 音色セットの DLS データを必要とするため、単純な MIDI ファイルを演奏する場合でも、このステップが必要となる。このステップを省略すると、MIDI ファイルを演奏しても無音となる。GUID_Download パラメータを指定するために、もう一度セグメントで SetParam を呼び出す。
g_pMIDISeg->SetParam(GUID_Download, -1, 0, 0, (void*)g_pPerf);
LoadMIDISegment 関数で既にこの操作が完了している場合でも、ダウンロードの要求による実害はない点に注意すること。余分な要求は単に無視される。最終的には音色をアンロードしなければならないが、DirectMusic をシャットダウンする準備ができるまで待機することができる。
ここで、関数は演奏準備のできたセグメントへのポインタを返す。
return pSegment; } // LoadSegment()の終わり
新しいセグメントをロードする前に、既存のセグメントをクリーンアップする。続いて、LoadMIDISegment 関数にファイル名を渡す。
if (g_pMIDIseg) { g_pMIDIseg->Release(); g_pMIDIseg = NULL; } if (g_pLoader) { IDirectMusicSegment* g_pMIDIseg = LoadMIDISegment(g_pLoader, L"tune.mid"); }