mirror of
https://github.com/aaru-dps/RedBookPlayer.git
synced 2025-12-16 19:24:41 +00:00
Make OpticalDisc have events
This commit is contained in:
@@ -6,11 +6,12 @@ using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.CommonTypes.Structs;
|
||||
using Aaru.Decoders.CD;
|
||||
using Aaru.Helpers;
|
||||
using ReactiveUI;
|
||||
using static Aaru.Decoders.CD.FullTOC;
|
||||
|
||||
namespace RedBookPlayer.Discs
|
||||
{
|
||||
public class CompactDisc : OpticalDisc
|
||||
public class CompactDisc : OpticalDisc, IReactiveObject
|
||||
{
|
||||
#region Public Fields
|
||||
|
||||
@@ -26,7 +27,7 @@ namespace RedBookPlayer.Discs
|
||||
|
||||
// Cache the value and the current track number
|
||||
int cachedValue = value;
|
||||
int cachedTrackNumber = _currentTrackNumber;
|
||||
int cachedTrackNumber;
|
||||
|
||||
// Check if we're incrementing or decrementing the track
|
||||
bool increment = cachedValue >= _currentTrackNumber;
|
||||
@@ -39,10 +40,10 @@ namespace RedBookPlayer.Discs
|
||||
else if(cachedValue < 0)
|
||||
cachedValue = _image.Tracks.Count - 1;
|
||||
|
||||
_currentTrackNumber = cachedValue;
|
||||
cachedTrackNumber = cachedValue;
|
||||
|
||||
// Cache the current track for easy access
|
||||
Track track = _image.Tracks[_currentTrackNumber];
|
||||
Track track = _image.Tracks[cachedTrackNumber];
|
||||
|
||||
// Set track flags from subchannel data, if possible
|
||||
SetTrackFlags(track);
|
||||
@@ -52,7 +53,7 @@ namespace RedBookPlayer.Discs
|
||||
|
||||
// If the track is playable, just return
|
||||
if(TrackType == TrackType.Audio || App.Settings.PlayDataTracks)
|
||||
return;
|
||||
break;
|
||||
|
||||
// If we're not playing the track, skip
|
||||
if(increment)
|
||||
@@ -60,7 +61,9 @@ namespace RedBookPlayer.Discs
|
||||
else
|
||||
cachedValue--;
|
||||
}
|
||||
while(cachedValue != cachedTrackNumber);
|
||||
while(cachedValue != _currentTrackNumber);
|
||||
|
||||
this.RaiseAndSetIfChanged(ref _currentTrackNumber, cachedTrackNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,12 +81,13 @@ namespace RedBookPlayer.Discs
|
||||
Track track = _image.Tracks[CurrentTrackNumber];
|
||||
|
||||
// Ensure that the value is valid, wrapping around if necessary
|
||||
ushort fixedValue = value;
|
||||
if(value > track.Indexes.Keys.Max())
|
||||
_currentTrackIndex = track.Indexes.Keys.Min();
|
||||
fixedValue = track.Indexes.Keys.Min();
|
||||
else if(value < track.Indexes.Keys.Min())
|
||||
_currentTrackIndex = track.Indexes.Keys.Max();
|
||||
else
|
||||
_currentTrackIndex = value;
|
||||
fixedValue = track.Indexes.Keys.Max();
|
||||
|
||||
this.RaiseAndSetIfChanged(ref _currentTrackIndex, fixedValue);
|
||||
|
||||
// Set new index-specific data
|
||||
SectionStartSector = (ulong)track.Indexes[CurrentTrackIndex];
|
||||
@@ -104,7 +108,7 @@ namespace RedBookPlayer.Discs
|
||||
// Cache the current track for easy access
|
||||
Track track = _image.Tracks[CurrentTrackNumber];
|
||||
|
||||
_currentSector = value;
|
||||
this.RaiseAndSetIfChanged(ref _currentSector, value);
|
||||
|
||||
if((CurrentTrackNumber < _image.Tracks.Count - 1 && CurrentSector >= _image.Tracks[CurrentTrackNumber + 1].TrackStartSector)
|
||||
|| (CurrentTrackNumber > 0 && CurrentSector < track.TrackStartSector))
|
||||
@@ -135,22 +139,43 @@ namespace RedBookPlayer.Discs
|
||||
/// <summary>
|
||||
/// Represents the 4CH flag
|
||||
/// </summary>
|
||||
public bool QuadChannel { get; private set; } = false;
|
||||
public bool QuadChannel
|
||||
{
|
||||
get => _quadChannel;
|
||||
private set => this.RaiseAndSetIfChanged(ref _quadChannel, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the DATA flag
|
||||
/// </summary>
|
||||
public bool IsDataTrack => TrackType != TrackType.Audio;
|
||||
public bool IsDataTrack
|
||||
{
|
||||
get => _isDataTrack;
|
||||
private set => this.RaiseAndSetIfChanged(ref _isDataTrack, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the DCP flag
|
||||
/// </summary>
|
||||
public bool CopyAllowed { get; private set; } = false;
|
||||
public bool CopyAllowed
|
||||
{
|
||||
get => _copyAllowed;
|
||||
private set => this.RaiseAndSetIfChanged(ref _copyAllowed, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the PRE flag
|
||||
/// </summary>
|
||||
public bool TrackHasEmphasis { get; private set; } = false;
|
||||
public bool TrackHasEmphasis
|
||||
{
|
||||
get => _trackHasEmphasis;
|
||||
private set => this.RaiseAndSetIfChanged(ref _trackHasEmphasis, value);
|
||||
}
|
||||
|
||||
private bool _quadChannel;
|
||||
private bool _isDataTrack;
|
||||
private bool _copyAllowed;
|
||||
private bool _trackHasEmphasis;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -369,8 +394,9 @@ namespace RedBookPlayer.Discs
|
||||
/// <param name="track">Track object to read from</param>
|
||||
private void SetDefaultTrackFlags(Track track)
|
||||
{
|
||||
QuadChannel = false;
|
||||
TrackType = track.TrackType;
|
||||
QuadChannel = false;
|
||||
IsDataTrack = track.TrackType != TrackType.Audio;
|
||||
CopyAllowed = false;
|
||||
TrackHasEmphasis = false;
|
||||
}
|
||||
@@ -390,9 +416,11 @@ namespace RedBookPlayer.Discs
|
||||
byte flags = (byte)(descriptor.CONTROL & 0x0D);
|
||||
TrackHasEmphasis = (flags & (byte)TocControl.TwoChanPreEmph) == (byte)TocControl.TwoChanPreEmph;
|
||||
CopyAllowed = (flags & (byte)TocControl.CopyPermissionMask) == (byte)TocControl.CopyPermissionMask;
|
||||
TrackType = (flags & (byte)TocControl.DataTrack) == (byte)TocControl.DataTrack ? TrackType.Data : TrackType.Audio;
|
||||
IsDataTrack = (flags & (byte)TocControl.DataTrack) == (byte)TocControl.DataTrack;
|
||||
QuadChannel = (flags & (byte)TocControl.FourChanNoPreEmph) == (byte)TocControl.FourChanNoPreEmph;
|
||||
|
||||
TrackType = IsDataTrack ? TrackType.Data : TrackType.Audio;
|
||||
|
||||
return;
|
||||
}
|
||||
catch(Exception)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace RedBookPlayer.Discs
|
||||
{
|
||||
public abstract class OpticalDisc
|
||||
public abstract class OpticalDisc : ReactiveObject
|
||||
{
|
||||
#region Public Fields
|
||||
|
||||
@@ -55,7 +56,7 @@ namespace RedBookPlayer.Discs
|
||||
/// <summary>
|
||||
/// Total sectors in the image
|
||||
/// </summary>
|
||||
public ulong TotalSectors => _image.Info.Sectors;
|
||||
public ulong TotalSectors => _image?.Info.Sectors ?? 0;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the time adjustment offset for the disc
|
||||
|
||||
@@ -19,6 +19,119 @@ namespace RedBookPlayer.GUI
|
||||
|
||||
#region Player Passthrough
|
||||
|
||||
#region OpticalDisc Passthrough
|
||||
|
||||
/// <summary>
|
||||
/// Current track number
|
||||
/// </summary>
|
||||
public int CurrentTrackNumber
|
||||
{
|
||||
get => _currentTrackNumber;
|
||||
private set => this.RaiseAndSetIfChanged(ref _currentTrackNumber, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Current track index
|
||||
/// </summary>
|
||||
public ushort CurrentTrackIndex
|
||||
{
|
||||
get => _currentTrackIndex;
|
||||
private set => this.RaiseAndSetIfChanged(ref _currentTrackIndex, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Current sector number
|
||||
/// </summary>
|
||||
public ulong CurrentSector
|
||||
{
|
||||
get => _currentSector;
|
||||
private set => this.RaiseAndSetIfChanged(ref _currentSector, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents if the disc has a hidden track
|
||||
/// </summary>
|
||||
public bool HiddenTrack
|
||||
{
|
||||
get => _hasHiddenTrack;
|
||||
private set => this.RaiseAndSetIfChanged(ref _hasHiddenTrack, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the 4CH flag [CompactDisc only]
|
||||
/// </summary>
|
||||
public bool QuadChannel
|
||||
{
|
||||
get => _quadChannel;
|
||||
private set => this.RaiseAndSetIfChanged(ref _quadChannel, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the DATA flag [CompactDisc only]
|
||||
/// </summary>
|
||||
public bool IsDataTrack
|
||||
{
|
||||
get => _isDataTrack;
|
||||
private set => this.RaiseAndSetIfChanged(ref _isDataTrack, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the DCP flag [CompactDisc only]
|
||||
/// </summary>
|
||||
public bool CopyAllowed
|
||||
{
|
||||
get => _copyAllowed;
|
||||
private set => this.RaiseAndSetIfChanged(ref _copyAllowed, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the PRE flag [CompactDisc only]
|
||||
/// </summary>
|
||||
public bool TrackHasEmphasis
|
||||
{
|
||||
get => _trackHasEmphasis;
|
||||
private set => this.RaiseAndSetIfChanged(ref _trackHasEmphasis, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the total tracks on the disc
|
||||
/// </summary>
|
||||
public int TotalTracks => _player.TotalTracks;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the total indices on the disc
|
||||
/// </summary>
|
||||
public int TotalIndexes => _player.TotalIndexes;
|
||||
|
||||
/// <summary>
|
||||
/// Total sectors in the image
|
||||
/// </summary>
|
||||
public ulong TotalSectors => _player.TotalSectors;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the time adjustment offset for the disc
|
||||
/// </summary>
|
||||
public ulong TimeOffset => _player.TimeOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the total playing time for the disc
|
||||
/// </summary>
|
||||
public ulong TotalTime => _player.TotalTime;
|
||||
|
||||
private int _currentTrackNumber;
|
||||
private ushort _currentTrackIndex;
|
||||
private ulong _currentSector;
|
||||
|
||||
private bool _hasHiddenTrack;
|
||||
private bool _quadChannel;
|
||||
private bool _isDataTrack;
|
||||
private bool _copyAllowed;
|
||||
private bool _trackHasEmphasis;
|
||||
|
||||
#endregion
|
||||
|
||||
#region SoundOutput Passthrough
|
||||
|
||||
/// <summary>
|
||||
/// Indicate if the model is ready to be used
|
||||
/// </summary>
|
||||
@@ -57,69 +170,6 @@ namespace RedBookPlayer.GUI
|
||||
|
||||
#endregion
|
||||
|
||||
#region Model-Provided Playback Information
|
||||
|
||||
private ulong _currentSector;
|
||||
public ulong CurrentSector
|
||||
{
|
||||
get => _currentSector;
|
||||
set => this.RaiseAndSetIfChanged(ref _currentSector, value);
|
||||
}
|
||||
|
||||
public int CurrentFrame => (int)(_currentSector / (75 * 60));
|
||||
public int CurrentSecond => (int)(_currentSector / 75 % 60);
|
||||
public int CurrentMinute => (int)(_currentSector % 75);
|
||||
|
||||
private ulong _totalSectors;
|
||||
public ulong TotalSectors
|
||||
{
|
||||
get => _totalSectors;
|
||||
set => this.RaiseAndSetIfChanged(ref _totalSectors, value);
|
||||
}
|
||||
|
||||
public int TotalFrames => (int)(_totalSectors / (75 * 60));
|
||||
public int TotalSeconds => (int)(_totalSectors / 75 % 60);
|
||||
public int TotalMinutes => (int)(_totalSectors % 75);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Disc Flags
|
||||
|
||||
private bool _quadChannel;
|
||||
public bool QuadChannel
|
||||
{
|
||||
get => _quadChannel;
|
||||
set => this.RaiseAndSetIfChanged(ref _quadChannel, value);
|
||||
}
|
||||
|
||||
private bool _isDataTrack;
|
||||
public bool IsDataTrack
|
||||
{
|
||||
get => _isDataTrack;
|
||||
set => this.RaiseAndSetIfChanged(ref _isDataTrack, value);
|
||||
}
|
||||
|
||||
private bool _copyAllowed;
|
||||
public bool CopyAllowed
|
||||
{
|
||||
get => _copyAllowed;
|
||||
set => this.RaiseAndSetIfChanged(ref _copyAllowed, value);
|
||||
}
|
||||
|
||||
private bool _trackHasEmphasis;
|
||||
public bool TrackHasEmphasis
|
||||
{
|
||||
get => _trackHasEmphasis;
|
||||
set => this.RaiseAndSetIfChanged(ref _trackHasEmphasis, value);
|
||||
}
|
||||
|
||||
private bool _hiddenTrack;
|
||||
public bool HiddenTrack
|
||||
{
|
||||
get => _hiddenTrack;
|
||||
set => this.RaiseAndSetIfChanged(ref _hiddenTrack, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -199,6 +249,9 @@ namespace RedBookPlayer.GUI
|
||||
/// Generate the digit string to be interpreted by the frontend
|
||||
/// </summary>
|
||||
/// <returns>String representing the digits for the frontend</returns>
|
||||
/// <remarks>
|
||||
/// TODO: The model shouldn't care about this
|
||||
/// </remarks>
|
||||
public string GenerateDigitString()
|
||||
{
|
||||
// If the disc isn't initialized, return all '-' characters
|
||||
@@ -259,12 +312,9 @@ namespace RedBookPlayer.GUI
|
||||
if(_player?.Initialized != true)
|
||||
return;
|
||||
|
||||
Playing = _player.Playing;
|
||||
ApplyDeEmphasis = _player.ApplyDeEmphasis;
|
||||
Volume = _player.Volume;
|
||||
|
||||
CurrentSector = _player.GetCurrentSectorTime();
|
||||
TotalSectors = _player.TotalTime;
|
||||
CurrentTrackNumber = _player.CurrentTrackNumber;
|
||||
CurrentTrackIndex = _player.CurrentTrackIndex;
|
||||
CurrentSector = _player.CurrentSector;
|
||||
|
||||
HiddenTrack = _player.HiddenTrack;
|
||||
|
||||
@@ -272,6 +322,10 @@ namespace RedBookPlayer.GUI
|
||||
IsDataTrack = _player.IsDataTrack;
|
||||
CopyAllowed = _player.CopyAllowed;
|
||||
TrackHasEmphasis = _player.TrackHasEmphasis;
|
||||
|
||||
Playing = _player.Playing;
|
||||
ApplyDeEmphasis = _player.ApplyDeEmphasis;
|
||||
Volume = _player.Volume;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Reference in New Issue
Block a user