I've been working on a program which has this feature of allowing the user to select a WAV sound for the program to play.
Since this feature is placed on the options dialogue, I wanted this to happen:
1) Click the button
2) The button changes the image from A to B and the sound is played
a) The user doesn't like the sound and wants to stop it - clicks again and goes to 3)
3) The sound reaches the end and the image comes back to A.
My main objective is to allow the user to interrupt the sound at any time (on step 2 a).
I've tried two methods:
Dim p as New Media.SoundPlayer
p.SoundLocation = fn 'Where fn is the FileName, the WAV location
p.Play
This works out fine, except I can't detect when the sound reaches its end, even when I tried to use p.Stream.Length and p.Stream.Position it returns an error, because it was actually null, and when it wasn't (I tried My.Computer.Audio.Play with the WAV represented by a Stream) those properties had the same value even before the sound had stopped.
After this, I tried:
My.Computer.Audio.Play(fn,AudioPlayMode.WaitToComplete)
But what happens, as I suspected, is that the program freezes until the sound ends, disabling the user to interrupt it or do anything at all.
Fortunately, System.Media.SoundPlayer allows you to declare it with events, like this:
Private WithEvents p as System.Media.SoundPlayer
Even though, none of those events are useful to do what I need.
Any suggestions? Thanks in advance
Here's a solution using the mciSendString() API which allows you to PLAY and CANCEL a WAV file, while also giving you a notification that the WAV file has COMPLETED playing:
Imports System.Runtime.InteropServices
Public Class Form1
Private PlayingWav As Boolean = False
Private Const MM_MCINOTIFY As Integer = 953
<DllImport("winmm.dll")> _
Private Shared Function mciSendString( _
ByVal command As String, _
ByVal buffer As System.Text.StringBuilder, _
ByVal bufferSize As Integer, _
ByVal hwndCallback As IntPtr _
) As Integer
End Function
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
If Not PlayingWav Then
PlayWavFile(TextBox1.Text)
Else
StopWavFile()
End If
End Sub
Public Sub PlayWavFile(ByVal WavFilePath As String)
Dim cmd As String = "open " & Chr(34) & WavFilePath & Chr(34) & " type waveaudio alias wav"
If mciSendString(cmd, Nothing, 0, IntPtr.Zero) = 0 Then
PlayingWav = True
Button1.Text = "Stop"
mciSendString("play wav notify", Nothing, 0, Me.Handle)
Else
MessageBox.Show(WavFilePath, "Error Loading Wav", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Sub
Public Sub StopWavFile()
mciSendString("close wav", Nothing, 0, IntPtr.Zero)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Select Case m.Msg
Case MM_MCINOTIFY
WavStopped()
End Select
MyBase.WndProc(m)
End Sub
Private Sub WavStopped()
PlayingWav = False
Button1.Text = "Play"
End Sub
End Class