VB.NETでDirectSoundを利用してWAVファイルを再生する
(その1)

概要

DirectSoundを利用してサウンド出力を行う方法』で作成したサンプルコードのVisual Basic版です。

Visual Basicから.NET FrameworkのDirectSoundを利用して音声ファイル(WAVファイル)の再生を行います。

C#版は『C#でDirectSoundを利用してWAVファイルを再生する』にあります。

サンプルコードの処理の流れを簡単に説明すると、以下のようになります。
(基本的にC/C++でDirectSoundを利用する場合と一緒です。)

  • サウンド出力を行うデバイスのオブジェクトを作成します。
  • サウンド出力を行うデバイスのオブジェクトからストリームバッファを作成します。
  • ストリームバッファの任意の位置に再生完了イベントを設定します。
  • 作成したストリームバッファにサウンド出力するデータを投入します。
  • ストリームバッファ上の任意の位置まで再生が完了したときにイベント通知が受けられるので、ストリームバッファで再生が完了した部分に新たにサウンド出力するデータを投入します。
  • 出力するデータがなくなった場合、サウンド出力を終了します。

.NET FrameworkでDirectSoundを利用するには、以下のクラスを参照設定で追加します。

追加するクラス

Microsoft.DirectX.DirectSound

サンプルプログラムの仕様

作成するサンプルプログラムは以下の仕様にします。

  • ウインドウ・スタイルはダイアログにする。
  • サウンドを出力するデバイスが複数ある場合、ユーザーが選択できる。
  • 再生するWAVファイルは、ユーザーが選択できる。
  • WAVファイルを選択後、[再生]ボタンで再生を開始する。
  • WAVファイルの再生中に[一時停止]ボタンを押すと、再生を一時中断し、[再生]ボタンを押すと中断した時点から、再生を再開する。
  • [停止]ボタンを押すと再生を終了し、[再生]ボタンを押すとファイルの先頭から再生を開始する。
  • 音量調節および左右のバランス調節をダイアログから行えるようにする。

サンプルプログラムの外観は以下のようにします。

ダイアログの初期処理

ダイアログのLoad()メソッドでダイアログの初期処理を行います。

ダイアログの初期処理では、サウンド出力デバイスのリストを作成します。

実は、本サンプルコードをVisual Studioから実行すると以下の警告メッセージが表示されます。

『マネージ デバッグ アシスタント 'LoaderLock' では 'sample_0005.vshost.exe' に問題を検出しました。
'Microsoft.DirectX.DirectSound.dll' は、OS ローダー ロック内でマネージ実行を試行しています。
DllMain またはイメージ初期化関数内でマネージ コードを実行しないでください。
この動作は、アプリケーションをハングさせる原因になる可能性があります。』

'DirectSound.dll'をロードするタイミングがアプリケーションのFormのロード時では問題があるようです。
DLLをロードするタイミングをFormのロード完了以降にずらせば良いのだろうと思いますが、ちょうど良いイベントが思いつかなかったので、とりあえずこのままにしておきます。
(調べてみると'DirectSound.dll'自体の問題かもしれないです。対策しなくても実用上は問題無いとは思うのですが。。。)

サンプルコードを以下に示します。


'****************************************************************************'
'*
'*  @brief  ダイアログの初期処理.
'*
'*  @param  [in]    sender  イベントの送信元のオブジェクト.
'*  @param  [in]    e       イベント情報.
'*
'*  @retval なし.
'*
Private Sub Form1_Load( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles MyBase.Load

    ' デバイス名コンボボックスにDataTableオブジェクトを作成する.
    Dim device_table As New DataTable()
    device_table.Columns.Add( "NAME", GetType(String) )
    device_table.Columns.Add( "GUID", GetType(Guid)   )

    Dim DsEnum  As New DevicesCollection
    Dim info    As DeviceInformation
    Dim i       As Long

    ' デバイス名コンボボックスにデバイス名と対応するGUIDを登録する.
    For i = 0 To DsEnum.Count() - 1
        info = DsEnum.Item( i )

        ' 列挙したデバイス名が"プライマリ・デバイス"の場合、コンボボックスには追加しない.
        If (info.DriverGuid() <> System.Guid.Empty _
                            And info.Description <> "") Then

            ' DataTableにデバイス名とGIUDを追加する.
            Dim row As DataRow = device_table.NewRow()
            row("NAME") = info.Description
            row("GUID") = info.DriverGuid
            device_table.Rows.Add( row )
        End If
    Next i
    DsEnum = Nothing

    device_table.AcceptChanges()

    'コンボボックスのDataSourceにDataTableを割り当てる.
    DeviceList_ComboBox.DataSource    = device_table
    DeviceList_ComboBox.DisplayMember = "NAME"      ' 表示.
    DeviceList_ComboBox.ValueMember   = "GUID"      ' コンボボックスの値.

End Sub
	

DirectSoundの出力デバイスをリストアップする

使用するオーディオドライバをユーザーが選択できるように、オーディオ出力可能なDirectSoundドライバをDevicesCollectionクラスから取得してコンボボックスにリストアップします。

DevicesCollectionクラスのプロパティは以下のとおりです。

クラス名Microsoft.DirectX.DirectSound.DevicesCollection
基本型

System.Object

プロパティ名説明
Count

オーディオ出力可能なDirectSoundドライバの個数を取得します。

Item

指定した番号のドライバ情報(DeviceInformation)を取得します。

DeviceInformation構造体の主なプロパティは以下のとおりです。

構造体名Microsoft.DirectX.DirectSound.DeviceInformation
プロパティ名説明
Description

出力デバイスの説明文を取得します。

DriverGuid

出力デバイスのGUIDを取得します。

ModuleName

出力デバイスのモジュール名を取得します。

サンプルコードでは、コンボボックスに出力デバイスのGUIDと表示用にデバイスの説明文を示す文字列をコンボボックスに登録しています。



Windows、DirectXおよびDirectSoundは米国Microsoft Corporationの登録商標です。