diff --git a/RedBookPlayer.Models/Hardware/IAudioBackend.cs b/RedBookPlayer.Models/Hardware/IAudioBackend.cs new file mode 100644 index 0000000..b461c2a --- /dev/null +++ b/RedBookPlayer.Models/Hardware/IAudioBackend.cs @@ -0,0 +1,30 @@ +namespace RedBookPlayer.Models.Hardware +{ + public interface IAudioBackend + { + /// + /// Pauses the audio playback + /// + void Pause(); + + /// + /// Starts the playback. + /// + void Play(); + + /// + /// Stops the audio playback + /// + void Stop(); + + /// + /// Get the current playback state + /// + PlayerState GetPlayerState(); + + /// + /// Set the new volume value + /// + void SetVolume(float volume); + } +} \ No newline at end of file diff --git a/RedBookPlayer.Models/Hardware/Linux/AudioBackend.cs b/RedBookPlayer.Models/Hardware/Linux/AudioBackend.cs new file mode 100644 index 0000000..b84ffa2 --- /dev/null +++ b/RedBookPlayer.Models/Hardware/Linux/AudioBackend.cs @@ -0,0 +1,52 @@ +using CSCore.SoundOut; + +namespace RedBookPlayer.Models.Hardware.Linux +{ + public class AudioBackend : IAudioBackend + { + /// + /// Sound output instance + /// + private ALSoundOut _soundOut; + + public AudioBackend() { } + + public AudioBackend(PlayerSource source) + { + _soundOut = new ALSoundOut(100); + _soundOut.Initialize(source); + } + + #region IAudioBackend Implementation + + /// + public void Pause() => _soundOut.Pause(); + + /// + public void Play() => _soundOut.Play(); + + /// + public void Stop() => _soundOut.Stop(); + + /// + public PlayerState GetPlayerState() + { + return (_soundOut?.PlaybackState) switch + { + PlaybackState.Paused => PlayerState.Paused, + PlaybackState.Playing => PlayerState.Playing, + PlaybackState.Stopped => PlayerState.Stopped, + _ => PlayerState.NoDisc, + }; + } + + /// + public void SetVolume(float volume) + { + if (_soundOut != null) + _soundOut.Volume = volume; + } + + #endregion + } +} \ No newline at end of file diff --git a/RedBookPlayer.Models/Hardware/Mac/AudioBackend.cs b/RedBookPlayer.Models/Hardware/Mac/AudioBackend.cs new file mode 100644 index 0000000..6f7949d --- /dev/null +++ b/RedBookPlayer.Models/Hardware/Mac/AudioBackend.cs @@ -0,0 +1,52 @@ +using CSCore.SoundOut; + +namespace RedBookPlayer.Models.Hardware.Mac +{ + public class AudioBackend : IAudioBackend + { + /// + /// Sound output instance + /// + private ALSoundOut _soundOut; + + public AudioBackend() { } + + public AudioBackend(PlayerSource source) + { + _soundOut = new ALSoundOut(100); + _soundOut.Initialize(source); + } + + #region IAudioBackend Implementation + + /// + public void Pause() => _soundOut.Pause(); + + /// + public void Play() => _soundOut.Play(); + + /// + public void Stop() => _soundOut.Stop(); + + /// + public PlayerState GetPlayerState() + { + return (_soundOut?.PlaybackState) switch + { + PlaybackState.Paused => PlayerState.Paused, + PlaybackState.Playing => PlayerState.Playing, + PlaybackState.Stopped => PlayerState.Stopped, + _ => PlayerState.NoDisc, + }; + } + + /// + public void SetVolume(float volume) + { + if (_soundOut != null) + _soundOut.Volume = volume; + } + + #endregion + } +} \ No newline at end of file diff --git a/RedBookPlayer.Models/Hardware/SoundOutput.cs b/RedBookPlayer.Models/Hardware/SoundOutput.cs index c89a223..ed6c71d 100644 --- a/RedBookPlayer.Models/Hardware/SoundOutput.cs +++ b/RedBookPlayer.Models/Hardware/SoundOutput.cs @@ -1,8 +1,6 @@ using System; using System.Linq; using System.Threading.Tasks; -using CSCore.SoundOut; -using NWaves.Audio; using ReactiveUI; using RedBookPlayer.Models.Discs; @@ -92,7 +90,7 @@ namespace RedBookPlayer.Models.Hardware /// /// Sound output instance /// - private ALSoundOut _soundOut; + private IAudioBackend _soundOut; /// /// Filtering stage for audio output @@ -183,7 +181,7 @@ namespace RedBookPlayer.Models.Hardware public int ProviderRead(byte[] buffer, int offset, int count) { // Set the current volume - _soundOut.Volume = (float)Volume / 100; + _soundOut.SetVolume((float)Volume / 100); // If we have an unreadable track, just return if(_opticalDisc.BytesPerSector <= 0) @@ -230,7 +228,7 @@ namespace RedBookPlayer.Models.Hardware /// public void Play() { - if(_soundOut.PlaybackState != PlaybackState.Playing) + if(_soundOut.GetPlayerState() != PlayerState.Playing) _soundOut.Play(); PlayerState = PlayerState.Playing; @@ -241,7 +239,7 @@ namespace RedBookPlayer.Models.Hardware /// public void Pause() { - if(_soundOut.PlaybackState != PlaybackState.Paused) + if(_soundOut.GetPlayerState() != PlayerState.Paused) _soundOut.Pause(); PlayerState = PlayerState.Paused; @@ -252,7 +250,7 @@ namespace RedBookPlayer.Models.Hardware /// public void Stop() { - if(_soundOut.PlaybackState != PlaybackState.Stopped) + if(_soundOut.GetPlayerState() != PlayerState.Stopped) _soundOut.Stop(); PlayerState = PlayerState.Stopped; @@ -368,8 +366,14 @@ namespace RedBookPlayer.Models.Hardware if(_source == null) { _source = new PlayerSource(ProviderRead); - _soundOut = new ALSoundOut(100); - _soundOut.Initialize(_source); + +#if LINUX + _soundOut = new Linux.AudioBackend(_source); +#elif MACOS + _soundOut = new Mac.AudioBackend(_source); +#elif WINDOWS + _soundOut = new Windows.AudioBackend(_source); +#endif } else { diff --git a/RedBookPlayer.Models/Hardware/Windows/AudioBackend.cs b/RedBookPlayer.Models/Hardware/Windows/AudioBackend.cs new file mode 100644 index 0000000..da3cc6c --- /dev/null +++ b/RedBookPlayer.Models/Hardware/Windows/AudioBackend.cs @@ -0,0 +1,53 @@ +using CSCore.SoundOut; +using PortAudioSharp; + +namespace RedBookPlayer.Models.Hardware.Windows +{ + public class AudioBackend : IAudioBackend + { + /// + /// Sound output instance + /// + private ALSoundOut _soundOut; + + public AudioBackend() { } + + public AudioBackend(PlayerSource source) + { + _soundOut = new ALSoundOut(100); + _soundOut.Initialize(source); + } + + #region IAudioBackend Implementation + + /// + public void Pause() => _soundOut.Pause(); + + /// + public void Play() => _soundOut.Play(); + + /// + public void Stop() => _soundOut.Stop(); + + /// + public PlayerState GetPlayerState() + { + return (_soundOut?.PlaybackState) switch + { + PlaybackState.Paused => PlayerState.Paused, + PlaybackState.Playing => PlayerState.Playing, + PlaybackState.Stopped => PlayerState.Stopped, + _ => PlayerState.NoDisc, + }; + } + + /// + public void SetVolume(float volume) + { + if (_soundOut != null) + _soundOut.Volume = volume; + } + + #endregion + } +} \ No newline at end of file diff --git a/RedBookPlayer.Models/RedBookPlayer.Models.csproj b/RedBookPlayer.Models/RedBookPlayer.Models.csproj index 7ed4a85..4b505f2 100644 --- a/RedBookPlayer.Models/RedBookPlayer.Models.csproj +++ b/RedBookPlayer.Models/RedBookPlayer.Models.csproj @@ -5,6 +5,16 @@ true + + LINUX + + + MAC + + + WINDOWS + +