1

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

4

1 回答 1

0

这是一个使用 mciSendString() API 的解决方案,它允许您播放取消WAV 文件,同时还会通知您 WAV 文件已完成播放

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
于 2013-07-02T21:22:20.220 回答