mirror of
https://github.com/aaru-dps/RedBookPlayer.git
synced 2025-12-16 11:14:39 +00:00
177 lines
4.7 KiB
C#
177 lines
4.7 KiB
C#
using System.Runtime.InteropServices;
|
|
using ReactiveUI;
|
|
|
|
namespace RedBookPlayer.Models.Audio
|
|
{
|
|
public class SoundOutput : ReactiveObject
|
|
{
|
|
#region Public Fields
|
|
|
|
/// <summary>
|
|
/// Indicate if the output is ready to be used
|
|
/// </summary>
|
|
public bool Initialized
|
|
{
|
|
get => _initialized;
|
|
private set => this.RaiseAndSetIfChanged(ref _initialized, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indicates the current player state
|
|
/// </summary>
|
|
public PlayerState PlayerState
|
|
{
|
|
get => _playerState;
|
|
private set => this.RaiseAndSetIfChanged(ref _playerState, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Current playback volume
|
|
/// </summary>
|
|
public int Volume
|
|
{
|
|
get => _volume;
|
|
private set
|
|
{
|
|
int tempVolume = value;
|
|
if(value > 100)
|
|
tempVolume = 100;
|
|
else if(value < 0)
|
|
tempVolume = 0;
|
|
|
|
this.RaiseAndSetIfChanged(ref _volume, tempVolume);
|
|
}
|
|
}
|
|
|
|
private bool _initialized;
|
|
private PlayerState _playerState;
|
|
private int _volume;
|
|
|
|
#endregion
|
|
|
|
#region Private State Variables
|
|
|
|
/// <summary>
|
|
/// Data provider for sound output
|
|
/// </summary>
|
|
private PlayerSource _source;
|
|
|
|
/// <summary>
|
|
/// Sound output instance
|
|
/// </summary>
|
|
private IAudioBackend _soundOut;
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
/// <param name="read">ReadFunction to use during decoding</param>
|
|
/// <param name="defaultVolume">Default volume between 0 and 100 to use when starting playback</param>
|
|
public SoundOutput(PlayerSource.ReadFunction read, int defaultVolume = 100)
|
|
{
|
|
Volume = defaultVolume;
|
|
SetupAudio(read);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialize the output with a given image
|
|
/// </summary>
|
|
/// <param name="autoPlay">True if playback should begin immediately, false otherwise</param>
|
|
public void Init(bool autoPlay)
|
|
{
|
|
// Reset initialization
|
|
Initialized = false;
|
|
|
|
// Initialize playback, if necessary
|
|
if(autoPlay)
|
|
_soundOut.Play();
|
|
|
|
// Mark the output as ready
|
|
Initialized = true;
|
|
PlayerState = PlayerState.Stopped;
|
|
|
|
// Begin loading data
|
|
_source.Start();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset the current internal state
|
|
/// </summary>
|
|
public void Reset()
|
|
{
|
|
_soundOut.Stop();
|
|
Initialized = false;
|
|
PlayerState = PlayerState.NoDisc;
|
|
}
|
|
|
|
#region Playback
|
|
|
|
/// <summary>
|
|
/// Start audio playback
|
|
/// </summary>
|
|
public void Play()
|
|
{
|
|
if(_soundOut.GetPlayerState() != PlayerState.Playing)
|
|
_soundOut.Play();
|
|
|
|
PlayerState = PlayerState.Playing;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pause audio playback
|
|
/// </summary>
|
|
public void Pause()
|
|
{
|
|
if(_soundOut.GetPlayerState() != PlayerState.Paused)
|
|
_soundOut.Pause();
|
|
|
|
PlayerState = PlayerState.Paused;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stop audio playback
|
|
/// </summary>
|
|
public void Stop()
|
|
{
|
|
if(_soundOut.GetPlayerState() != PlayerState.Stopped)
|
|
_soundOut.Stop();
|
|
|
|
PlayerState = PlayerState.Stopped;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eject the currently loaded disc
|
|
/// </summary>
|
|
public void Eject() => Reset();
|
|
|
|
#endregion
|
|
|
|
#region Helpers
|
|
|
|
/// <summary>
|
|
/// Set the value for the volume
|
|
/// </summary>
|
|
/// <param name="volume">New volume value</param>
|
|
public void SetVolume(int volume)
|
|
{
|
|
Volume = volume;
|
|
_soundOut?.SetVolume((float)Volume / 100);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets or resets the audio playback objects
|
|
/// </summary>
|
|
/// <param name="read">ReadFunction to use during decoding</param>
|
|
private void SetupAudio(PlayerSource.ReadFunction read)
|
|
{
|
|
_source = new PlayerSource(read);
|
|
if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
|
_soundOut = new Linux.AudioBackend(_source);
|
|
else if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
_soundOut = new Windows.AudioBackend(_source);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |