【VB.NET】 PlaySoundでMP3を鳴らす その1
 音声をただ単に流すだけなら、PlaySoundが最も手軽である。また、MCIとは異なりメモリ上にあるデータの再生も可能だから、効果音などを定期的に使用するようなプログラムの場合、MCIだと都度ファイルを読み込む必要がある(か、デバイスを開放しないでおく)が、PlaySoundの場合は一度読み込めばあとは変数に格納したデータを都度呼び出すだけで再生できる。但しPlaySoundは通常のやり方ではMP3ファイルを再生することができないようなので、RIFFデータとして若干加工する必要がある。

 とりあえず今回は、PlaySoundの基本的な定義と使い方についておさらい。




WIN32APIを使用するので、まずはその定義から

    ' ファイルから再生する
_
Private Shared Function PlaySound( _
ByVal pszSound As String, _
ByVal hModule As Integer, _
ByVal dwFlags As Integer) _
As Integer
End Function

' メモリ上のバッファから再生する
_
Private Shared Function PlaySound( _
ByVal pszSound As Byte(), _
ByVal hModule As Integer, _
ByVal dwFlags As Integer) _
As Integer
End Function

' メモリ上のバッファから再生する その2
_
Private Shared Function PlaySound( _
ByVal pszSound As IntPtr, _
ByVal hModule As Integer, _
ByVal dwFlags As Integer) _
As Integer
End Function

' 再生フラグ
Private Const SND_SYNC As Integer = &H0 ' 同期再生
Private Const SND_ASYNC As Integer = &H1 ' 非同期再生
Private Const SND_PURGE As Integer = &H40 '停止
Private Const SND_MEMORY As Integer = &H4 ' バッファからの再生
Private Const SND_LOOP As Integer = &H8 ' ループ再生
Private Const SND_NOSTOP As Integer = &H10 ' 再生中のサウンドを停止しない
Private Const SND_NOWAIT As Integer = &H2000 ' ビジー状態なら即座に処理を返す

 メモリ上のバッファを再生するが2個あるのは、DOBON.NETに解説があるように、非同期再生時、.NETのガベージコレクタが働いてWAVEデータが移動させられてしまうことがありうまく再生されない場合があるということらしいです。
 それぞれの再生の指示の方法は下記の通り。


' ファイルを読み込んで非同期再生
' (同期再生時はSND_ASYNCをSND_SYNCに)
PlaySound("filenamefullpath.wav", IntPtr.Zero, SND_FILENAME Or SND_ASYNC)

' 再生の終了指示
PlaySound(Nothing, IntPtr.Zero, SND_PURGE)

' ファイルを読み込んでメモリに格納し、非同期再生
Dim sr As New System.IO.FileStream("filename.wav", FileMode.Open)
Dim buf() As Byte = New Byte(sr.Length) {}
sr.Read(buf, 0, buf.Length)
sr.Close()
PlaySound(buf, IntPtr.Zero, SND_FILENAME Or SND_ASYNC)

' 非同期再生がうまくいかない場合のPlaySoundの部分
Dim gcHandle As System.Runtime.InteropServices.GCHandle
Me.gcHandle = System.Runtime.InteropServices.GCHandle.Alloc( _
Me.buf2, System.Runtime.InteropServices.GCHandleType.Pinned)
PlaySound(Me.gcHandle.AddrOfPinnedObject(), _
Nothing, SND_MEMORY Or SND_ASYNC)


ファイルを読み込むやつにおいては、ファイルをバイト配列に格納するので、結局のところこれは埋め込まれたリソースにおいては、下記のように対象のストリームを変えるだけでよい。

Dim sr As System.IO.Stream = My.Resources.Voice1
Dim buf() As Byte = New Byte(sr.Length) {}
sr.Read(buf, 0, buf.Length)
sr.Close()


[PR]
by hidemite | 2009-02-27 18:50 | PC
<< 【春】 気付けばもう3月 【求人】 社風を前面に出すと >>