[VB6]DirectSoundを使ったWave再生
DirectX7.0のDirectSoundによるWaveファイルの再生をしてみましょう。ここでは単純に再生と停止を行うことにします。DirectSoundにはもっとさまざまな機能を使用することができますが、今回のところは単純な操作だけに留めます。
1. DirectSoundの準備
まずはDirectXおよびDirectSoundを初期化することからはじめます。初期化はお決まりでして、次のようにします。Formのハンドルを渡す必要があります。
Dim dx7 As New DirectX7 Dim ds7 As DirectSound Set ds7 = dx7.DirectSoundCreate("") Call ds7.SetCooperativeLevel(Form1.hWnd, DSSCL_PRIORITY) |
DirectX7のオブジェクトは他のDirectX(DirectDrawなど)と共有して使用できます。何度もSet dx7 = New DirectX7と実行する必要はありません。またDim宣言にてNewキーワードをつけることで最初からオブジェクトを初期化しておくことができます。
次にバッファを用意し、Waveファイルを読み込んで格納します。
Dim dsBuffer As DirectSoundBuffer Dim bufferDesc As DSBUFFERDESC Dim waveFormat As WAVEFORMATEX Dim soundFileName As String soundFileName = "C:\WINDOWS\Media\ringout.wav" bufferDesc.lFlags = DSBCAPS_CTRLFREQUENCY Or DSBCAPS_CTRLPAN Or _ DSBCAPS_CTRLVOLUME Or DSBCAPS_STATIC Set dsBuffer = ds7.CreateSoundBufferFromFile(soundFileName, bufferDesc, waveFormat) |
Waveファイルのフルパスを引数に渡すことでバッファへの格納が行われます。
DSBUFFERDESC構造体にはバッファのプロパティを設定しますが、今回は上記のようにしておきます。
WAVEFORMATEX構造体は読み込ませるデータ(Wave)のフォーマットを指定しますが、Wave形式の場合は初期値でかまいません。
2. 再生
準備までできると再生は非常に簡単です。先ほど作成したバッファをPlayするだけです。
dsBuffer.Play DSBPLAY_DEFAULT |
ここで引数に与えている値は、DSBPLAY_DEFAULT(= 0) が一回だけの再生、DSBPLAY_LOOPING(= 1) がループ再生になります。
3. 停止
停止も難しいことはありません。止めるだけ。ただし次の再生位置は止めたところになるので、停止という意味ではポジションを先頭に戻すことを忘れないようにします。
dsBuffer.Stop dsBuffer.SetCurrentPosition 0 'ポジション0 = 先頭 |
これで基本的な部分は完了です。
最後に全体をまとめておきます。FormにCommandButtonを2つ貼り付けてください。Command1は再生、Command2は停止となります。もちろんWaveファイルも必要ですよ。
Dim dx7 As New DirectX7 Dim ds7 As DirectSound Dim dsBuffer As DirectSoundBuffer Dim bufferDesc As DSBUFFERDESC Dim waveFormat As WAVEFORMATEX '再生ボタン Private Sub Command1_Click() dsBuffer.Play DSBPLAY_DEFAULT End Sub '停止ボタン Private Sub Command2_Click() dsBuffer.Stop dsBuffer.SetCurrentPosition 0 End Sub 'DirectSoundの初期化 Private Sub Form_Load() Dim soundFileName As String soundFileName = "C:\WINDOWS\Media\ringout.wav"'使用する環境に合わせて変更する Set ds7 = dx7.DirectSoundCreate("") Call ds7.SetCooperativeLevel(Me.hWnd, DSSCL_PRIORITY) bufferDesc.lFlags = DSBCAPS_CTRLFREQUENCY Or DSBCAPS_CTRLPAN Or _ DSBCAPS_CTRLVOLUME Or DSBCAPS_STATIC Set dsBuffer = ds7.CreateSoundBufferFromFile(soundFileName, bufferDesc, waveFormat) End Sub |
おっと、終了処理を入れておりませんね。プロジェクトの終了時にはDirectXの各オブジェクトを解放することを忘れないようにします。解放は確保した逆順でしたね。
Private Sub Form_Unload(Cancel As Integer) Set dsBuffer = Nothing Set ds7 = Nothing End Sub |
※今回の dx7 変数はNewキーワードで宣言されているので、Nothingを使用してもまた新しいオブジェクトを確保してしまいます。このため今回は解放処理を行いません。
DirectSoundBufferオブジェクトを作成するメソッドは上記のCreateSoundBufferFromFileとCreateSoundBufferFromResourceとあり、それぞれファイルやリソースから作成することになります。でも「やっぱりファイルじゃなくてメモリ上のWaveファイルを再生したい!!」という方いるでしょう。少々手間がかかりますが、次のようにすれば出来ます。実はCreateSoundBufferというメソッドがありますので、これによって空のバッファを作成し、後からメモリ上のWaveデータを書き込めばよいのです。では始めましょうか。
まず、Waveデータをバイト列に格納します。ここはお好みでどうぞ。
Dim fileBuffer() As Byte Dim fileName As String Dim freeNum As Long fileName = App.Path & "\sample.wav" 'Waveファイルのパスを適切に指定します freeNum = FreeFile() Open fileName For Binary As freeNum ReDim fileBuffer(LOF(freeNum) - 1) Get #freeNum, , fileBuffer Close #freeNum |
準備できたところでDirectSoundに戻ります。WaveファイルからDirectSoundBufferを作成した時にはDSBUFFERDESCやWAVEFORMATEXに必要最小限のパラメータしか与えませんでした。それはDirectX側がファイルを読み込む際に自動的に判断してくれたからです。今回は全てこちら側が指定しなければなりません。
まずDSBUFFERDESCですが、lBufferBytesというパラメータがあります。ここにはバッファのサイズを指定します。すなわち上記のバイト列の大きさになりますね。
次にWAVEFORMATEXですが、これから書き込むWaveデータの情報をあらかじめ与える必要があります。パラメータが結構多くて苦労しますが、がんばりましょう。
パラメータ名 | 設定値 |
---|---|
lAvgBytesPerSec | lSamplesPerSec * nBlockAlign の値 |
lExtra | 不使用。0とする |
lSamplesPerSec | サンプルレート。Hzで表されるもの。通常8000, 11025, 22050, 44100のいずれか |
nBitsPerSample | サンプルサイズ。8ビットか16ビットのどちらか |
nBlockAlign | nBitsPerSample * nChannels \ 8 の値 |
nChannels | チャンネル数。ステレオならば2、モノラルならば1とする |
nFormatTag | WAVE_FORMAT_PCMを指定する |
nSize | 設定不要。0とする |
さてバッファのサイズとWaveデータの情報をそろえたら、いよいよバッファの作成と書き込みとなります。作成はCreateSoundBufferメソッド、ロードはWriteBufferメソッドになります。使い方はこれまでの説明も含めて以下のようになります。
Dim dsBuffer As DirectSoundBuffer Dim bufferDesc As DSBUFFERDESC Dim waveFormat As WAVEFORMATEX Dim fSize As Long fSize = UBound(fileBuffer) 'Waveデータの長さ bufferDesc.lBufferBytes = fSize bufferDesc.lFlags = DSBCAPS_CTRLFREQUENCY Or DSBCAPS_CTRLPAN Or _ DSBCAPS_CTRLVOLUME Or DSBCAPS_STATIC With waveFormat .lAvgBytesPerSec = 22050 .lExtra = 0 .lSamplesPerSec = 22050 .nBitsPerSample = 8 .nBlockAlign = 1 .nChannels = 1 .nFormatTag = WAVE_FORMAT_PCM .nSize = 0 End With '空のDirectSoundBufferを作成する Set dsBuffer = ds7.CreateSoundBuffer(bufferDesc, waveFormat) 'DirectSoundBufferにWaveデータを書き込む Call dsBuffer.WriteBuffer(0, fSize, fileBuffer(0), DSBLOCK_FROMWRITECURSOR) |
※WriteBufferメソッドの引数は、(0, データのサイズ, データの先頭バイト, DSBLOCK_FROMWRITECURSOR)です。
0 comentários:
Postar um comentário