DirectXの機能の1つでもある、DirectMusic。このDirectMusicを利用すれば、サウンド関連のハードウェアを独占したハイパフォーマンスなサウンド処理を実現できます。まずは初歩的なWAVE/MIDIファイルの再生に挑戦してみましょう。
3Dグラフィックスを描画するなら、Win32APIが提供する描画関数よりも、断然DirectXを利用したほうが高度な処理ができることは、皆さんご存知のとおりでしょう。では、Windowsが標準で提供しているMCIコマンドとDirectMusicとを比較した場合、どのような特徴をDirectMusicが持ち合わせることになるのでしょうか。また、どのような処理を行う場合にDirectMusicを取り入れたほうがよいのか、少し考えてみます。
DirectMusicはハードウェアをフル活用してサウンドの再生を行います。よって、MCIコマンドと比較するとサウンド再生の際に生じる時間的な誤差が少なくて済みます。これは、サウンドのテンポがキャラクタの動作に深く関係する場合などに要求されます。キャラクタの動きとサウンドテンポのズレを最小限に押さえる目的であれば、DirectMusicを活用しない手はないでしょう。
何かしらのサウンドを発しながら3D空間を動き回る物体を再現するためには、どのような処理を行う必要があるのでしょうか。左右(もしくは更に前後)のスピーカーの音量を計算することや、ドップラー効果に対するサウンド周波数の変化を考慮する必要があります。これらすべてを自動的に行ってくれるのがDirectMusic(厳密にはそれに関わるDirectSound)です。例えば、3D空間の中を救急車が疾走するプログラムは、DirectMusicを利用することで簡単に再現できます。
ABDXはDirectMusicを簡単に扱うためのCAudioクラスを提供しています。このクラスでは、以下のメンバ関数を呼び出すことで基本的なサウンド制御を行うことができます。
'WAVE形式またはMIDI形式のファイルを読み込み、メモリ上に展開します。 CAudio::Load( pszFileName As BytePtr 'サウンドファイルパス ) As Long 'サウンドイメージを再生します。 CAudio::Play() As Long 再生中のサウンドを停止します。 CAudio::Stop() As Long
※より詳しい仕様はヘルプファイルに記載されています
プロジェクト名を "dmtest" にセットして、DirectXアプリケーションのプロジェクトを新たに作成します。ここから、dmtest.abpに対してコーディングをしていきます。
CAudioオブジェクトポインタの定義を行います。
#include "dmtest.idx"
Dim ScreenX=640 As Long 'ディスプレイの幅 (ピクセル単位)
Dim ScreenY=480 As Long 'ディスプレイの高さ(ピクセル単位)
' TODO: この位置にグローバル変数を定義してください。
Dim pAudio As *CAudio
CAudioオブジェクトの生成を行います。Load関数には適当なWAVE/MIDIファイルを指定しておきます。
Function InitProc()
'DirectXを初期化
If dx_Init(hMainWnd,ScreenX,ScreenY,FALSE)=0 Then
InitProc=0
Exit Function
End If
'マウスカーソルを非表示にする
ShowCursor(FALSE)
' TODO: この位置にアプリケーションの初期化コードを記述してください。
'CAudioクラスの生成
pAudio=New CAudio
'サウンドファイルをロード(適当にWAVE/MIDIファイルを指定します)
pAudio->Load("C:\Winnt\Media\The Microsoft Sound.wav")
'再生
pAudio->Play()
InitProc=1
End Function
pAudioオブジェクトを解放します。
Sub QuitProc()
' TODO: この位置にアプリケーションの終了処理を記述してください。
'停止
pAudio->Stop()
'pAudioオブジェクトを破棄
Delete pAudio
'DirectXの終了処理
dx_Quit()
End Sub
実行してみると、真っ黒な画面に切り替わると同時に指定したサウンドが再生されます。プログラム終了の際に、サウンドは停止します。
上記のサンプルのように、DirectMusicのサウンド機能だけを利用したいのに、DirectGraphicsの初期化が自動的に行われてしまい、結果的に真っ黒な画面が映し出されてしまいます。そこで、InitProc関数及びメインループの部分を以下のように書き換えることで、このDirectGraphicsの初期化処理をキャンセルすることができます。
Function InitProc()
'COMを初期化
CoInitialize(NULL)
'DirectMusicを初期化
If dx_InitDMusic()=0 Then
InitProc=0
Exit Function
End If
' TODO: この位置にアプリケーションの初期化コードを記述してください。
'CAudioクラスの生成
pAudio=New CAudio
'サウンドファイルをロード(適当にWAVE/MIDIファイルを指定します)
pAudio->Load("C:\Winnt\Media\The Microsoft Sound.wav")
'再生
pAudio->Play()
InitProc=1
End Function
'------------------------------------------------
' メインループ
'------------------------------------------------
Dim msgMain As MSG, iResult As Long
Do
If PeekMessage(msgMain,0,0,0,PM_REMOVE) Then
'----------------------------------
' メインウィンドウのメッセージ処理
'----------------------------------
If msgMain.message=WM_QUIT Then Exit Do
TranslateMessage(msgMain)
DispatchMessage(msgMain)
Else
'---------------------------
' DirectXによる入力及び描画
'---------------------------
InputActionProc() '入力
RenderProc() 'レンダリング(描画)
End If
Loop
講座インデックスへ戻る | ©2005 Discoversoft |