Reputation: 4466
I have a problem with this code. The function is playing a music track, so it takes a while to finish executing.... However, even through it is threaded, it does not return untill it is done, holding up the rest of the program. Can I have the function exit so that the program continues but have the music keep on it's own thread. Any solutions are welcome.
using System;
using Gtk;
using NAudio;
using NAudio.Wave;
using System.Threading;
public class Trackbox {
public static void Main() {
Application.Init();
//Create the Window
Window myWin = new Window("Trackbox");
myWin.SetIconFromFile("Assets//logo.png");
myWin.Resize(200, 100);
//Add the label to the form
//myWin.Add(myLabel);
Button playButton = new Button("Play Sound");
//This when playwav is called here, the rest of the application waits for it to finish playing
playButton.Clicked += new EventHandler(playWav);
myWin.Add(playButton);
myWin.DeleteEvent += delegate { Application.Quit(); };
//Show Everything
myWin.ShowAll();
Application.Run();
}
private static void playWav(object sender, EventArgs e)
{
var soundFile = @"C:\sound.wav";
using (var wfr = new WaveFileReader(soundFile))
using (WaveChannel32 wc = new WaveChannel32(wfr) { PadWithZeroes = false })
using (var audioOutput = new DirectSoundOut())
{
audioOutput.Init(wc);
audioOutput.Play();
while (audioOutput.PlaybackState != PlaybackState.Stopped)
{
Thread.Sleep(20);
}
audioOutput.Stop();
}
}
}
Thanks for the help. If you have any ideas please post.
Upvotes: 1
Views: 1002
Reputation: 49492
DirectSoundOut
already creates its own playback thread. Get rid of the Thread.Sleep
altogether which is blocking your thread and simply call Play
. Subscribe to the PlaybackStopped
event to detect when playback has finished. The audioOutput
would need to be a class member so you could Dispose
it after playback had finished.
Upvotes: 0
Reputation: 12954
Your playWav
is executed on the same thread as your UI is running on. That is why your UI is blocked.
You can start a new thread like this:
private volatile bool _QuitThread;
private void playWav(object sender, EventArgs e)
{
_QuitThread = false;
Thread thread = new Thread(playWavThread);
thread.Start();
}
// This method should be called when the music should stop. Perhapse when a button has been pressed.
private void StopTheMusic()
{
_QuitThread = true;
}
private void playWavThread()
{
var soundFile = @"C:\sound.wav";
using (var wfr = new WaveFileReader(soundFile))
using (WaveChannel32 wc = new WaveChannel32(wfr) { PadWithZeroes = false })
using (var audioOutput = new DirectSoundOut())
{
audioOutput.Init(wc);
audioOutput.Play();
while (!_QuitThread && audioOutput.PlaybackState != PlaybackState.Stopped)
{
Thread.Sleep(20);
}
audioOutput.Stop();
}
}
EDIT
At request, I added code to quit the thread.
Upvotes: 4