Better Audio Handling

This commit is contained in:
2015-10-29 22:48:54 +01:00
parent 615934557c
commit 1f2983d712
+47 -27
View File
@@ -12,8 +12,10 @@ namespace MusicPlayer
{ {
public class AudioHandler public class AudioHandler
{ {
public enum AudioState { PLAYING, STOPPED, PAUSED } public enum AudioState { PLAYING, WAITING, STOPPED, PAUSED }
public AudioState State { get; set; } public enum BufferState { EMPTY, BUFFERING, DONE }
public AudioState AState { get; set; }
public BufferState BState { get; set; }
private Stream ms; private Stream ms;
@@ -24,24 +26,32 @@ namespace MusicPlayer
public AudioHandler() public AudioHandler()
{ {
CreateThreads();
}
private void CreateThreads()
{
AState = AudioState.STOPPED;
BState = BufferState.EMPTY;
ms = new MemoryStream(); ms = new MemoryStream();
network = new Thread(LoadAudio); network = new Thread(LoadAudio);
audio = new Thread(PlayAudio); audio = new Thread(PlayAudio);
network.IsBackground = true; network.IsBackground = true;
audio.IsBackground = true; audio.IsBackground = true;
State = AudioState.STOPPED;
} }
public void Play(Song s) public void Play(Song s)
{ {
if (CurrentSong == s) if (CurrentSong == s)
State = AudioState.PLAYING; AState = AudioState.PLAYING;
else else
{ {
State = AudioState.STOPPED; Stop();
network = new Thread(LoadAudio);
audio = new Thread(PlayAudio);
CurrentSong = s; CurrentSong = s;
network.Start(s); network.Start(s);
@@ -51,20 +61,24 @@ namespace MusicPlayer
public void Stop() public void Stop()
{ {
State = AudioState.STOPPED; CreateThreads();
} }
public void Pause() public void Pause()
{ {
State = AudioState.PAUSED; AState = AudioState.PAUSED;
} }
private void PlayAudio() private void PlayAudio()
{ {
while (ms.Length < 65536 * 10) AState = AudioState.WAITING;
while (ms.Length < 65536 * 10 && BState != BufferState.DONE)
Thread.Sleep(1000); Thread.Sleep(1000);
AState = AudioState.PLAYING;
ms.Position = 0; long position = 0;
ms.Position = position;
using (WaveStream blockAlignedStream = new BlockAlignReductionStream(WaveFormatConversionStream.CreatePcmStream(new Mp3FileReader(ms)))) using (WaveStream blockAlignedStream = new BlockAlignReductionStream(WaveFormatConversionStream.CreatePcmStream(new Mp3FileReader(ms))))
{ {
using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback())) using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
@@ -73,21 +87,25 @@ namespace MusicPlayer
waveOut.Play(); waveOut.Play();
while (waveOut.PlaybackState != PlaybackState.Stopped) while (waveOut.PlaybackState != PlaybackState.Stopped)
{ {
System.Threading.Thread.Sleep(100); System.Threading.Thread.Sleep(10);
if(State == AudioState.PAUSED && waveOut.PlaybackState == PlaybackState.Playing)
{ if(AState == AudioState.PLAYING && waveOut.PlaybackState == PlaybackState.Paused)
waveOut.Pause();
}
if (State == AudioState.PLAYING && waveOut.PlaybackState == PlaybackState.Paused)
{ {
ms.Position = position;
waveOut.Play(); waveOut.Play();
} }
if (State == AudioState.STOPPED) if (AState == AudioState.PAUSED && waveOut.PlaybackState == PlaybackState.Playing)
{
position = ms.Position;
waveOut.Pause();
}
if(AState == AudioState.STOPPED)
{ {
waveOut.Stop(); waveOut.Stop();
} }
} }
State = AudioState.STOPPED;
AState = AudioState.STOPPED;
} }
} }
} }
@@ -96,24 +114,26 @@ namespace MusicPlayer
{ {
Song s = (Song) o; Song s = (Song) o;
var response = WebRequest.Create(s.Url).GetResponse(); var response = WebRequest.Create(s.Url).GetResponse();
State = AudioState.PLAYING;
BState = BufferState.EMPTY;
using (var stream = response.GetResponseStream()) using (var stream = response.GetResponseStream())
{ {
byte[] buffer = new byte[65536]; // 64KB chunks byte[] buffer = new byte[65536]; // 64KB chunks
int read; int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) BState = BufferState.BUFFERING;
AState = AudioState.WAITING;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0 && AState != AudioState.STOPPED)
{ {
var pos = ms.Position; var pos = ms.Position;
ms.Position = ms.Length; ms.Position = ms.Length;
ms.Write(buffer, 0, read); ms.Write(buffer, 0, read);
ms.Position = pos; ms.Position = pos;
if(State == AudioState.STOPPED)
{
stream.Close();
return;
}
} }
} }
BState = BufferState.DONE;
} }
} }