■ DirectXを使用したMIDIファイルの再生
前回に引き続き、今回もDirectXを使用したサウンドファイルの再生を紹介します。
前回はWAVEファイルを再生しましたが、今回はMIDIファイルの再生に挑戦します。
そして最後にMIDI、WAVEファイルを使った多重再生のサンプルを紹介したいと思います。
さっそくMIDI再生のコードをみてみましょう。
' モジュール宣言部に記述ここから −−−−−−−−−−−−−−−−−−−−−−−−−−
Dim DX8 As New DirectX8
Dim BufBgmTest As DirectMusicPerformance8
Dim DMLoader As DirectMusicLoader8
Dim DMSegment As DirectMusicSegment8
Dim DMSegmentState As DirectMusicSegmentState8
Dim AudioParam As DMUS_AUDIOPARAMS
' モジュール宣言部に記述ここまで −−−−−−−−−−−−−−−−−−−−−−−−−−
Public Sub ReadMusicBuffer()
MyWindow = FindWindow("XLMAIN", Application.Caption)
WrkSndFile = ThisWorkbook.Path & "\test.mid"
Set DMLoader = DX8.DirectMusicLoaderCreate()
Set DMSegment = DMLoader.LoadSegment(WrkSndFile)
DMSegment.SetStartPoint mtStart:=0
DMSegment.SetRepeats lRepeats:=0
Set BufBgmTest = DX8.DirectMusicPerformanceCreate()
BufBgmTest.InitAudio Hwnd:=MyWindow, _
lFlags:=DMUS_AUDIOF_ALL, _
audioparams:=AudioParam, _
DirectSound:=Nothing, _
lDefaultPathType:=DMUS_APATH_DYNAMIC_3D, _
lPChannelCount:=16
BufBgmTest.SetMasterAutoDownload b:=True
End Sub
Public Sub StartMidi()
Call ReadMusicBuffer
Set DMSegmentState = BufBgmTest.PlaySegmentEx(DMSegment, 0, 0)
End Sub
Public Sub StopMidi()
BufBgmTest.StopEx ObjectToStop:=DMSegmentState, lStopTime:=0, lFlags:=0
End Sub
割愛してありますが、API関数のFindWindowは前回と同じものを使います。もちろん参照設定の
"DirectX 8 for Visual Basic Type Library"も前回同様必要になります。念のため。
順をおって説明していきましょう。
まず前回同様、DX8にDirectX8の新しいオブジェクトを宣言します。次にサウンドデータをロードするためのコンポーネントオブジェクトであるDirectMusicLoader8のオブジェクトを作成します。
このオブジェクトはDirectMusicLoaderCreateメソッドを使って作成されます。前回のDirectSound8オブジェクト同様ですね。
同様にDirectMusicPerformance8オブジェクトも作成しています。
このオブジェクトが音楽再生の総合的なマネージャを務めます。
このオブジェクトがもっているメソッドは実に多様で、セグメントの演奏やメッセージの送信、イベント通知の送受信、ミュージックパラメータの設定や取得、タイミングに関する情報の取得など音楽再生に必要なほとんどの機能を備えています。
BufBgmTest.InitAudio この部分でDirectMusicPerformanceの初期化を行っています。
lFlagsのDMUS_AUDIOF_ALLのパラメータはシンセサイザのすべての機能を使う指定です。
lDefaultPathTypeのDMUS_APATH_DYNAMIC_3Dは再生効果の指定です。他に、
・DMUS_APATH_DYNAMIC_STEREO:ステレオで再生
・DMUS_APATH_SHARED_STEREOPLUSREVERB:エコーがかかる
などを指定することができます。
lPChannelCountの16は同時発音数です16なら16和音再生という意味になります。試しに1から一つづつ増やしていくとMIDIがどのようなチャンネル構成で音を重ねているかがよくわかります。
BufBgmTest.SetMasterAutoDownload b:=True この部分でMIDIが使用するサウンドフォント(各楽器の音色)を自動で準備するように設定しています。
StartMidiプロシージャでMIDIの再生を行います。前回同様、ReadMusicBufferの処理は、ブックもしくはフォームを開いた時点で一度実行しておけばOKです。
StopMidiプロシージャでMIDIの再生を停止させています。
ちなみに演奏中かどうかを調べたい場合はBufBgmTest.IsPlaying(DMSegment, DMSegmentState)の戻り値でわかります。
TRUEなら演奏中で、FALSEなら演奏が終了しています。
■ DirectXで多重再生に挑戦しよう!
これぞDirectXの醍醐味、MIDI、WAVEの多重再生です。PlaySoundではとてもかなわなかった未知の世界がDierctXでは可能になります。
早速、多重再生のサンプルコードにいきましょう。
' モジュール宣言部に追加ここから −−−−−−−−−−−−−−−−−−−−−−−−−−
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
' モジュール宣言部に追加ここまで −−−−−−−−−−−−−−−−−−−−−−−−−−
Public Sub MixingPlaySample()
Dim i As Long
MyWindow = FindWindow("XLMAIN", Application.Caption)
WrkSndFile = ThisWorkbook.Path & "\test.mid"
Set DMLoader = DX8.DirectMusicLoaderCreate()
Set DMSegment = DMLoader.LoadSegment(WrkSndFile)
DMSegment.SetStartPoint mtStart:=0
DMSegment.SetRepeats lRepeats:=0
Set BufBgmTest = DX8.DirectMusicPerformanceCreate()
BufBgmTest.InitAudio Hwnd:=MyWindow, _
lFlags:=DMUS_AUDIOF_ALL, _
audioparams:=AudioParam, _
DirectSound:=Nothing, _
lDefaultPathType:=DMUS_APATH_DYNAMIC_3D, _
lPChannelCount:=32
BufBgmTest.SetMasterAutoDownload b:=True
Set DMSegmentState = BufBgmTest.PlaySegmentEx(DMSegment, 0, 0)
Set DS8 = DX8.DirectSoundCreate(vbNullString)
DS8.SetCooperativeLevel Hwnd:=MyWindow, Level:=DSSCL_PRIORITY
For i = 1 To 4
Call Sleep(1000)
WrkSndFile = ThisWorkbook.Path & "\test" & i & ".wav"
Set BufSndTest(i) = DS8.CreateSoundBufferFromFile( _
Filename:=WrkSndFile, _
bufferdesc:=BufDsc _
)
BufSndTest(i).Play DSBPLAY_DEFAULT
Next i
End Sub
あまり説明の必要がないサンプルですね。
モジュールの宣言部は前回と同じものに、今回はAPIのSleep関数を追加しています。
これは指定した時間(単位ミリ秒)処理を止めることができる便利な関数です。止めている間はCPUの負荷がかかりませんので、ループの忙しい処理の中にSleep関数でほんの少し停止時間を作ることでPCがうなり出すのを防ぐことができます。しょっちゅう使いますのでこの機会に覚えておいてください。
このサンプルではまずtest.midというMIDIファイルを再生します。次にtest1〜4までのWAAVEファイルを1秒間隔で順番に鳴らしていきます。
当然、このtest.midとtest1.wav〜test4.wavは用意していただかないといけません。
音の重なり具合がよくわかるように長め(4〜5秒)のWAVEファイルがいいでしょう。MIDIは10秒以上のものであればなんでもかまいません。
実行してみるとまず、MIDIが鳴り、1秒間隔でずれながらWAVEファイルが再生されていくのがお分かりいただけると思います。
ゲームならばコマンドの実行やアクションの操作などでWAVEファイルを再生したとき、後から再生した音が前に再生している音を消さずにきれいに重なります。
これぞDirectXの威力、Excelでもこれだけの音再生が可能なのです。
ただ使い道はゲーム開発くらいにしか使えないのが残念ですが…
(ちなみにMIDIは重ねて再生することはできません)
DirectX8の詳細なリファレンスは下記を参照してください。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdx8_vb/hh/directx8_vb/dxintro_vb_6rxr.asp
|