Aula Dx7 DirectSound Japonês

Um dos Últimos (acho que o último) Tutorial sobre DirectSound no mundo, pesquisei a fundo e só achei isso, o site onde estava está para sair do ar, então deixo aqui como forma de estudo:


[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データの情報をあらかじめ与える必要があります。パラメータが結構多くて苦労しますが、がんばりましょう。
WAVEFORMATEXのパラメータ
パラメータ名設定値
lAvgBytesPerSeclSamplesPerSec * nBlockAlign の値
lExtra不使用。0とする
lSamplesPerSecサンプルレート。Hzで表されるもの。通常8000, 11025, 22050, 44100のいずれか
nBitsPerSampleサンプルサイズ。8ビットか16ビットのどちらか
nBlockAlignnBitsPerSample * nChannels \ 8 の値
nChannelsチャンネル数。ステレオならば2、モノラルならば1とする
nFormatTagWAVE_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: