VB.NETでDirectSoundを利用してWAVファイルを再生する
(その2)
ダイアログの[再生]ボタンを押されたときに、WAVファイルの再生を開始します。
WAVファイルがオープンされていない場合、WAVファイルをオープンします。
次にオープンしたWAVファイルの情報を元に以下の手順でサウンド出力デバイスに対応したストリームバッファを作成します。
- DirectSoundの再生オブジェクトを作成。
- 再生オブジェクトに対するアプリケーションの協調レベルを設定。
- ストリームバッファ・オブジェクトを作成。
- 再生イベントを設定。
- 再生イベントをタスクを起動。
サンプルコードを以下に示します。
'****************************************************************************'
'*
'* @brief WAVファイルを再生する.
'*
'* @param なし.
'*
'* @retval なし.
'*
Private Sub Play_WaveSound()
On Error Goto error_exit
' WAVファイルをオープンしていない場合、オープンする.
If ( m_File.IsOpen() = False ) Then
' -1.ダイアログから再生するWAVファイル名を取得する.
m_FileName = FileName_TextBox.Text
' -2.再生するWAVファイル名をオープンする.
If ( m_File.Open( m_FileName ) <> True ) Then
MsgBox( "ファイルをオープンできません", MsgBoxStyle.OKOnly )
Exit Sub
End If
End If
If ( IsNothing( m_DX ) = True ) Then
' WAVファイルからオーディオフォーマットを取得する.
Dim wf As New WaveFormat
m_File.GetWaveInfo( wf )
' デバイス選択リストからサウンド・デバイスのGUIDを取得する.
Dim dev_guid As System.Guid
dev_guid = DeviceList_ComboBox.SelectedValue()
' DirectSoundをオープンする
If ( OpenSoundOutDevice( dev_guid, wf ) = False ) Then
Exit Sub
End If
'WAVファイルの読込み用バッファを確保する.
m_DataBuf = Nothing
m_DataBuf = New Byte( (m_BufSize / 2) - 1 ){}
' 再生カーソルの位置を初期化する.
m_DXBuf.SetCurrentPosition( 0 )
m_WritePos = 0
End If
' サウンド再生を開始する
If ( IsNothing( m_DXBuf ) = False ) Then
m_DXBuf.Play( 0, BufferPlayFlags.Looping )
End If
' 再生状態を「再生中」にする.
m_IsPlay = True
Play_Button.Enabled = False
Stop_Button.Enabled = True
Pause_Button.Enabled = True
DeviceList_ComboBox.Enabled = False
FileName_TextBox.Enabled = False
FileSel_Button.Enabled = False
Exit Sub
error_exit:
' エラーメッセージを表示する.
MsgBox( Err.Description, vbOKOnly, "再生" )
End Sub
'****************************************************************************'
'*
'* @brief サウンド出力デバイスをオープンする.
'*
'* @param [in] dev_guid サウンド出力デバイスのGUID.
'* @param [in] wf WAVEフォーマット構造体.
'*
'* @retval True = OK. / False = NG.
'*
Private Function OpenSoundOutDevice( ByVal dev_guid As System.Guid, ByVal wf As WaveFormat ) As Boolean
On Error Goto error_exit
' DirectSoundの再生オブジェクトを作成する.
m_DX = new Device( dev_guid )
' 再生オブジェクトに対するアプリケーションの協調レベルを設定する.
m_DX.SetCooperativeLevel( Me, CooperativeLevel.Priority )
' ストリームバッファ・オブジェクトを作成する.
Dim desc As New BufferDescription
desc.Format = wf
desc.BufferBytes = wf.AverageBytesPerSecond / 4
desc.Flags = BufferDescriptionFlags.GlobalFocus _
+ BufferDescriptionFlags.ControlPositionNotify _
+ BufferDescriptionFlags.ControlVolume _
+ BufferDescriptionFlags.ControlPan
m_DXBuf = New SecondaryBuffer( desc, m_DX )
desc = Nothing
' 確保されたストリームバッファのサイズを取得する.
Dim caps As BufferCaps
caps = m_DXBuf.Caps()
m_BufSize = caps.BufferBytes()
If ( IsNothing( m_Thread ) = True ) Then
' イベントタスクを生成する.
m_Thread = New Thread( New System.Threading.ThreadStart( AddressOf OutputEventTask ) )
' 再生イベントのオブジェクトを作成する.
m_Event = New AutoResetEvent( False )
End If
' 再生イベントを設定する.
m_DXNotify = New Notify( m_DXBuf )
Dim psa(1) As BufferPositionNotify
psa(0).EventNotifyHandle = m_Event.Handle
psa(0).Offset = (m_BufSize / 2) - 1
psa(1).EventNotifyHandle = m_Event.Handle
psa(1).Offset = m_BufSize - 1
m_DXNotify.SetNotificationPositions( psa, psa.Length )
' イベントタスクを起動する.
m_IsDoing = True
m_Thread.Start()
Return True
Exit Function
error_exit:
' エラーメッセージを表示する.
MsgBox( Err.Description, vbOKOnly, "オープン" )
' エラーが発生した場合、サウンド出力デバイスをクローズする.
Call CloseSoundOutDevice()
Return False
End Function
Deviceクラスのオブジェクトを、使用する出力デバイスのGUIDを用いて作成します。
Deviceクラスの主なメソッドとプロパティは以下のとおりです。
クラス名 | Microsoft.DirectX.DirectSound.Device |
---|---|
基本型 | System.MarshalByRefObject |
メソッド名 | 説明 |
SetCooperativeLevel | デバイスに対するアプリケーションの協調レベルを設定します。 |
プロパティ名 | 説明 |
Caps | デバイスの性能を取得します。 |
SpeakerConfig | スピーカ構成の設定と取得を行います。 |
Certified | ドライバが DirectX で認証されているかどうかを確認します。 |
DirectSoundでは1つの出力デバイスを複数のアプリケーションから同時に利用できる為、DeviceクラスのSetCooperativeLevel()メソッドを呼び出して、使用するサウンド出力デバイスのアプリケーション間の協調レベルを設定します。
Public Sub SetCooperativeLevel(
ByVal owner As System.Windows.Forms.Control, _
ByVal level As Microsoft.DirectX.DirectSound.CooperativeLevel )
引数 | 説明 |
---|---|
owner | DirectSoundを使用するFormのオブジェクト。 |
level |
アプリケーションの協調レベル。 |
DirectSoundのストリームバッファはSecondaryBufferクラスのオブジェクトにより管理されます。
SecondaryBufferクラスのオブジェクトをDeviceクラスのオブジェクトを用いて作成します。
SecondaryBufferクラスの主なメソッドとプロパティは以下のとおりです。
クラス名 | Microsoft.DirectX.DirectSound.SecondaryBuffer |
---|---|
基本型 | Microsoft.DirectX.DirectSound.Buffer |
メソッド名 | 説明 |
Play | オーディオの再生を開始します。 |
Stop | オーディオの再生を停止します。 |
Write | ストリームバッファにオーディオデータを書き込みます。 |
Read | ストリームバッファからオーディオデータを読み込みます。 |
GetCurrentPosition | バッファの再生カーソルおよび読み込みカーソルの位置を取得します。 |
SetCurrentPosition | バッファの再生カーソルの位置を設定します。 |
Restore | 失われたバッファへのメモリ割り当てを復元します。 |
プロパティ名 | 説明 |
Format | オーディオ・フォーマットの取得と設定を行います。 |
Frequency | サンプルレートの取得と設定を行います。 |
Caps | バッファの能力を取得します。 |
Status | バッファのステータスを取得します。 |
PlayPosition | バッファの再生カーソルの位置を取得します。 |
WritePosition | バッファの書き込みカーソル位置を取得します。 |
Volume | ボリュームレベルの取得と設定を行います。 |
Pan | 左右のボリュームバランスの取得と設定を行います。 |
作成するストリームバッファの設定はBufferDescriptionクラスのオブジェクトで指定します。
BufferDescriptionクラスの主なプロパティは以下のとおりです。
クラス名 | Microsoft.DirectX.DirectSound.BufferDescription |
---|---|
基本型 | System.MarshalByRefObject |
プロパティ名 | 説明 |
BufferBytes | 作成するバッファのサイズ(バイト数)を設定します。 |
Flags |
サンプルコードで設定しているフラグは以下のとおりです。 |
Format | オーディオ・フォーマットを設定します。 |
作成したSecondaryBufferクラスのオブジェクトから実際に作成したストリームバッファのサイズを取得します。
ストリームバッファのサイズを取得するには、BufferCaps構造体のプロパティBufferBytesを参照します。
BufferCaps構造体はSecondaryBufferクラスのプロパティCaps()を使用して取得します。
BufferCaps構造体の主なプロパティは以下のとおりです。
構造体名 | Microsoft.DirectX.DirectSound.BufferCaps |
---|---|
プロパティ名 | 説明 |
BufferBytes | ストリームバッファのサイズ(バイト数)。 |
CanGetCurrentPosition | True=正確な再生カーソルを取得できます。 |
Control3D | True=3Dサウンドを利用できます。 |
ControlEffects | True=エフェクト処理をサポートしています。 |
ControlFrequency | True=サンプルレートの設定ができます。 |
ControlPan | True=左右のボリュームバランスの設定ができます。 |
ControlPositionNotify | True=通知イベントを利用できます。 |
ControlVolume | True=ボリュームレベルの設定ができます。 |
GlobalFocus | True=グローバルなサウンド・バッファを使用しています。 |
LocateInHardware | True=ハードウェア・ミキシングを行います。 |
LocateInSoftware | True=ソフトウェア・ミキシングを行います。 |
LocationDefer | True=再生時にハードウェア/ソフトウェアのリソースにバッファを割り当てます。 |
Mute3DAtMaximumDistance | True=サウンドは最大距離で無音になります。 |
PlayCpuOverhead | サウンド・バッファをミキシングするために必要な時間。 |
PrimaryBuffer | True=バッファはプライマリ・バッファです。 |
StaticBuffer | True=オンボード・ハードウェア・メモリを使用しています。 |
StickyFocus | True=DirectSoundを使用していない他のアプリケーションに切り替えても、継続してオーディオ出力を行います。 |
UnlockTransferRate | データをバッファ・メモリに転送する速度 (KB/秒)。 |
ストリームバッファにWAVEデータを書き込むタイミングを発生させるために、ストリームバッファの任意の再生位置でイベントを発行してもらうように Notify()クラスのオブジェクトを生成して再生イベントの通知位置を設定します。
NotifyクラスノオブジェクトはSecondaryBufferクラスのオブジェクトを用いて作成します。
クラス名 | Microsoft.DirectX.DirectSound.Notify |
---|---|
基本型 | System.MarshalByRefObject |
メソッド名 | 説明 |
SetNotificationPositions | 再生イベントを設定します。 |
再生イベントの通知位置を設定するには、NotifyクラスのSetNotificationPositions()を使用します。
設定したイベントは、再生中に再生カーソルが指定されたオフセットに到達するたびに、イベントが通知されます。
Public Sub SetNotificationPositions( _
ByVal notify() As Microsoft.DirectX.DirectSound.BufferPositionNotify, _
ByVal numNotificationPositions As Integer )
引数 | 説明 |
---|---|
notify | イベント設定構造体(BufferPositionNotify)の配列。 |
numNotificationPositions | 設定する再生イベントの個数。 |
BufferPositionNotify構造体の主なプロパティは以下のとおりです。
構造体名 | Microsoft.DirectX.DirectSound.BufferPositionNotify |
---|---|
プロパティ名 | 説明 |
EventNotifyHandle | 通知されるイベントのハンドル。 |
Offset | バッファの先頭から通知イベントが発生する場所までのオフセット(バイト単位)。 |
サンプルコードではストリームバッファの中間点と最後の2点に再生イベントを設定しています。
SecondaryBufferクラスのSetCurrentPosition()メソッドを呼び出して再生開始位置を設定します。
サンプルコードでは再生開始位置の初期化なので、引数に0を設定します。
Public Sub SetCurrentPosition( ByVal newPosition As Integer )
引数 | 説明 |
---|---|
newPosition | バッファの先頭からの再生カーソルのオフセット(バイト単位)。 |
SecondaryBufferクラスのPlay()メソッドを呼び出して再生を開始します。
Public Sub Play( ByVal priority As Integer, _
ByVal flags As Microsoft.DirectX.DirectSound.BufferPlayFlags )
引数 | 説明 |
---|---|
priority | サウンドの優先度。通常は0を指定します。 |
flags | ストリームバッファをリングバッファとして動作させますのでBufferPlayFlags.Loopingを指定します。 |