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