Sound doesn't play instantly...but wait for next operation to complete!

Jayme65

Active member
Joined
Apr 5, 2011
Messages
35
Programming Experience
Beginner
I've a big interrogation concerning sound playback (WMP.lib)!
This code should play a sound, then compute...but it computes then play the sound!

VB.NET:
Class MainWindow
    Dim writingPath As String = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) & "\_UI Sounds\"
    Dim uiPlayer As New WMPLib.WindowsMediaPlayer
    Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        RunTest()
    End Sub
    Private Sub RunTest()
        Debug.Print("Started!")
        uiPlayer.URL = writingPath & "son1.wav"
        uiPlayer.controls.play()
        '
        Dim a As Integer = 0
        For i As Integer = 0 To 999999999
            a = i
        Next
        Debug.Print("Done!")
    End Sub
End Class

I thought that I perhaps should run the sound in a thread to be sure that it's played by its own!?
But this gives the same result

VB.NET:
Imports System.Threading
Class MainWindow
    Dim writingPath As String = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) & "\_UI Sounds\"
    Dim uiPlayer As New WMPLib.WindowsMediaPlayer
    Dim uiThread As Thread = New Thread(AddressOf PlayFile)
    Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        RunTest()
    End Sub
    Private Sub RunTest()
        uiThread = New Thread(AddressOf PlayFile)
        uiThread.Start()
        '
        Debug.Print("Started!")
        Dim a As Integer = 0
        For i As Integer = 0 To 999999999
            a = i
        Next
        Debug.Print("Done!")
    End Sub
    Private Sub PlayFile()
        uiPlayer.URL = writingPath & "son1.wav"
        uiPlayer.controls.play()
    End Sub
End Class

How should I please proceed to hear my sound 'instantly'?
What's my mistake?

Thanks for your help!!
 
Hmmm, this makes me curious. Try placing an Application.DoEvents inside the loop. Tell what happens.
 
It doesn't work better.
Well, I had posted a simple code, hoping that it would be more clear for users to help me...but I'm afraid that I'd better post something very similar to my actual code..if I want the problem to be clearly exposed...and help you to try to help me ;-)

There's a sound class, called UISound:

VB.NET:
Imports System.Threading
Public Class UISound
    Dim writingPath As String = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) & "\_UI Sounds\"
    Public Shared WithEvents uiPlayer As New WMPLib.WindowsMediaPlayer
    Public Shared uiThread As Thread = New Thread(AddressOf ReceiveSound)
    Public Shared Sub ReceiveSound(ByVal url As String)
        uiThread = New Thread(AddressOf PlayFile)
        uiThread.Start(url)
    End Sub
    Public Shared Sub PlayFile(ByVal url As String)
        uiPlayer.URL = writingPath & url
        uiPlayer.controls.play()
    End Sub
End Class

The sound is called from a sub in the MainWindow...which itself fires other subs in cascade that involve a heavy compute time:

VB.NET:
Sub one()
    UISound.ReceiveSound("sound1.wav")
    Dim a As Integer = 0
    For i As Integer = 0 To 999999999
        a = i
    Next
    Two()
End Sub
Sub two()
    Dim a As Integer = 0
    For i As Integer = 0 To 999999999
        a = i
    Next
    Three()
End Sub
Sub Three()
    Dim a As Integer = 0
    For i As Integer = 0 To 999999999
        a = i
    Next
End Sub

It appears that the sound is played after the whole "cascade" is runned, so after Sub Three() End.


If you try this code you will verify that inserting
VB.NET:
System.Windows.Forms.Application.DoEvents()
after uiPlayer.controls.play()...doesn't work better

Thanks for your help!!
 
Last edited:
Hi,

The issue is that you have still got code trying to execute on the UI Thread to start the Second Thread at the time that you get into the For Loops so those For loops are blocking the code to start that Second thread. Here is a quick rewrite using a BackgroundWorker which works fine:-

VB.NET:
Imports System.ComponentModel
 
Public Class Form1
  Private WithEvents myWorker As New BackgroundWorker
 
  Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    myWorker.RunWorkerAsync()
    one()
  End Sub
 
  Private Sub one()
    Dim a As Integer = 0
    For i As Integer = 0 To 999999999
      a = i
    Next
    two()
  End Sub
 
  Private Sub two()
    Dim a As Integer = 0
    For i As Integer = 0 To 999999999
      a = i
    Next
    Three()
  End Sub
 
  Private Sub Three()
    Dim a As Integer = 0
    For i As Integer = 0 To 999999999
      a = i
    Next
    MsgBox("Done!")
  End Sub
 
  Private Sub myWorker_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles myWorker.DoWork
    UISound.PlayFile()
  End Sub
End Class
 
Public Class UISound
  Private Shared writingPath As String = "d:\temp\Speech Off.wav"
  Private Shared uiPlayer As New WMPLib.WindowsMediaPlayer
 
  Public Shared Sub PlayFile()
    uiPlayer.URL = writingPath
    uiPlayer.controls.play()
  End Sub
End Class

Hope that helps.

Cheers,

Ian
 
Hi,

What do you mean by "It doesn't work better"? Are you saying it does work but its not as good as something else that you already have or are you saying that it still works the same way that you currently have?

I thought that want you wanted was to play a sound before you got into the For loops? If so, then that is what I have demonstrated.

Cheers,

Ian

Oh, you just deleted the last post, so did you get it working?
 
Ian,
Thanks so much for your help..and patience!! Really!!
Unfortunately, even if I do exactly what you submitted to me, it doesn't work for me!
Sure, I can see that it works when I copy/paste your code in a test window...but once I insert your code in mine the result stay the same: the sound is playing after the "cascading" subs completion.

I'm really wondering why it doesn't work..and how I could give you further indication :(
 
Last edited:
Hi,

Sure, I can see that it works when I copy/paste your code in a test window...but once I insert your code in mine the result stay the same

Well at least you can confirm that have seen a viable solution. Be sure that you do not add the BackgroundWorker to your UISound class and do make sure that the BackgroundWorker is declared and its RunWorkerAsync method is called on the UI thread in your Form before you call any other subroutine. It's then in the DoWork event of the BackgroundWorker that you make the call to your UISound class to play the sound as the For loops are running.

Cheers,

Ian

If this still does not work then post the whole routine as you have it now so that we can have another look.
 
Similar problem + resolution

I had a similar problem. It turned out that the processes following the call to media player used up all available runtime for the application. I solved this by adding 'wait' intervals with Doevents. Just adding Doevents didn't work because the program did not actually seem to stop long enough to do any. I had to force it to pause. I think this is essentially what IanRyder is saying - give the program a chance to do something before you start on the loops.

Hope this may be of some help.

David
 
Last edited:
Back
Top