diff --git a/RedBookPlayer.Common/Discs/CompactDisc.cs b/RedBookPlayer.Common/Discs/CompactDisc.cs
index eb51c0c..8f123ef 100644
--- a/RedBookPlayer.Common/Discs/CompactDisc.cs
+++ b/RedBookPlayer.Common/Discs/CompactDisc.cs
@@ -34,16 +34,30 @@ namespace RedBookPlayer.Common.Discs
do
{
- // Ensure that the value is valid, wrapping around if necessary
- if(cachedValue >= _image.Tracks.Count)
- cachedValue = 0;
- else if(cachedValue < 0)
- cachedValue = _image.Tracks.Count - 1;
+ // If we're over the last track, wrap around
+ if(cachedValue > _image.Tracks.Max(t => t.TrackSequence))
+ {
+ cachedValue = (int)_image.Tracks.Min(t => t.TrackSequence);
+ if(cachedValue == 0 && !_loadHiddenTracks)
+ cachedValue++;
+ }
+
+ // If we're under the first track and we're not loading hidden tracks, wrap around
+ else if(cachedValue < 1 && !_loadHiddenTracks)
+ {
+ cachedValue = (int)_image.Tracks.Max(t => t.TrackSequence);
+ }
+
+ // If we're under the first valid track, wrap around
+ else if(cachedValue < _image.Tracks.Min(t => t.TrackSequence))
+ {
+ cachedValue = (int)_image.Tracks.Max(t => t.TrackSequence);
+ }
cachedTrackNumber = cachedValue;
// Cache the current track for easy access
- Track track = _image.Tracks[cachedTrackNumber];
+ Track track = GetTrack(cachedTrackNumber);
// Set track flags from subchannel data, if possible
SetTrackFlags(track);
@@ -78,7 +92,7 @@ namespace RedBookPlayer.Common.Discs
return;
// Cache the current track for easy access
- Track track = _image.Tracks[CurrentTrackNumber];
+ Track track = GetTrack(CurrentTrackNumber);
// Ensure that the value is valid, wrapping around if necessary
ushort fixedValue = value;
@@ -106,18 +120,18 @@ namespace RedBookPlayer.Common.Discs
return;
// Cache the current track for easy access
- Track track = _image.Tracks[CurrentTrackNumber];
+ Track track = GetTrack(CurrentTrackNumber);
this.RaiseAndSetIfChanged(ref _currentSector, value);
- if((CurrentTrackNumber < _image.Tracks.Count - 1 && CurrentSector >= _image.Tracks[CurrentTrackNumber + 1].TrackStartSector)
+ if((CurrentTrackNumber < _image.Tracks.Count - 1 && CurrentSector >= GetTrack(CurrentTrackNumber + 1).TrackStartSector)
|| (CurrentTrackNumber > 0 && CurrentSector < track.TrackStartSector))
{
foreach(Track trackData in _image.Tracks.ToArray().Reverse())
{
if(CurrentSector >= trackData.TrackStartSector)
{
- CurrentTrackNumber = (int)trackData.TrackSequence - 1;
+ CurrentTrackNumber = (int)trackData.TrackSequence;
break;
}
}
@@ -136,6 +150,9 @@ namespace RedBookPlayer.Common.Discs
}
}
+ ///
+ public override int BytesPerSector => GetTrack(CurrentTrackNumber).TrackRawBytesPerSector;
+
///
/// Represents the 4CH flag
///
@@ -206,6 +223,11 @@ namespace RedBookPlayer.Common.Discs
///
private bool _loadDataTracks = false;
+ ///
+ /// Indicate if hidden tracks should be loaded
+ ///
+ private bool _loadHiddenTracks = false;
+
///
/// Current disc table of contents
///
@@ -217,10 +239,12 @@ namespace RedBookPlayer.Common.Discs
/// Constructor
///
/// Generate a TOC if the disc is missing one
+ /// Load hidden tracks for playback
/// Load data tracks for playback
- public CompactDisc(bool generateMissingToc, bool loadDataTracks)
+ public CompactDisc(bool generateMissingToc, bool loadHiddenTracks, bool loadDataTracks)
{
_generateMissingToc = generateMissingToc;
+ _loadHiddenTracks = loadHiddenTracks;
_loadDataTracks = loadDataTracks;
}
@@ -257,47 +281,101 @@ namespace RedBookPlayer.Common.Discs
#region Seeking
+ ///
+ public override void NextTrack()
+ {
+ if(_image == null)
+ return;
+
+ CurrentTrackNumber++;
+ LoadTrack(CurrentTrackNumber);
+ }
+
+ ///
+ public override void PreviousTrack()
+ {
+ if(_image == null)
+ return;
+
+ CurrentTrackNumber--;
+ LoadTrack(CurrentTrackNumber);
+ }
+
///
public override bool NextIndex(bool changeTrack)
{
if(_image == null)
return false;
- if(CurrentTrackIndex + 1 > _image.Tracks[CurrentTrackNumber].Indexes.Keys.Max())
+ // Cache the current track for easy access
+ Track track = GetTrack(CurrentTrackNumber);
+
+ // If the index is greater than the highest index, change tracks if needed
+ if(CurrentTrackIndex + 1 > track.Indexes.Keys.Max())
{
if(changeTrack)
{
NextTrack();
- CurrentSector = (ulong)_image.Tracks[CurrentTrackNumber].Indexes.Values.Min();
+ CurrentSector = (ulong)GetTrack(CurrentTrackNumber).Indexes.Values.Min();
return true;
}
}
+
+ // If the next index has an invalid offset, change tracks if needed
+ else if(track.Indexes[(ushort)(CurrentTrackIndex + 1)] < 0)
+ {
+ if(changeTrack)
+ {
+ NextTrack();
+ CurrentSector = (ulong)GetTrack(CurrentTrackNumber).Indexes.Values.Min();
+ return true;
+ }
+ }
+
+ // Otherwise, just move to the next index
else
{
- CurrentSector = (ulong)_image.Tracks[CurrentTrackNumber].Indexes[++CurrentTrackIndex];
+ CurrentSector = (ulong)track.Indexes[++CurrentTrackIndex];
}
return false;
}
///
- public override bool PreviousIndex(bool changeTrack, bool playHiddenTrack)
+ public override bool PreviousIndex(bool changeTrack)
{
if(_image == null)
return false;
- if(CurrentTrackIndex - 1 < _image.Tracks[CurrentTrackNumber].Indexes.Keys.Min())
+ // Cache the current track for easy access
+ Track track = GetTrack(CurrentTrackNumber);
+
+ // If the index is less than the lowest index, change tracks if needed
+ if(CurrentTrackIndex - 1 < track.Indexes.Keys.Min())
{
if(changeTrack)
{
- PreviousTrack(playHiddenTrack);
- CurrentSector = (ulong)_image.Tracks[CurrentTrackNumber].Indexes.Values.Max();
+ PreviousTrack();
+ CurrentSector = (ulong)GetTrack(CurrentTrackNumber).Indexes.Values.Max();
return true;
}
}
+
+ // If the previous index has an invalid offset, change tracks if needed
+ else if (track.Indexes[(ushort)(CurrentTrackIndex - 1)] < 0)
+ {
+ if(changeTrack)
+ {
+ PreviousTrack();
+ CurrentSector = (ulong)GetTrack(CurrentTrackNumber).Indexes.Values.Max();
+ return true;
+ }
+ }
+
+ // Otherwise, just move to the previous index
else
{
- CurrentSector = (ulong)_image.Tracks[CurrentTrackNumber].Indexes[--CurrentTrackIndex];
+ CurrentSector = (ulong)track.Indexes[--CurrentTrackIndex];
}
return false;
@@ -310,7 +388,7 @@ namespace RedBookPlayer.Common.Discs
///
public override void LoadFirstTrack()
{
- CurrentTrackNumber = 0;
+ CurrentTrackNumber = 1;
LoadTrack(CurrentTrackNumber);
}
@@ -320,6 +398,12 @@ namespace RedBookPlayer.Common.Discs
/// True to enable loading data tracks, false otherwise
public void SetLoadDataTracks(bool load) => _loadDataTracks = load;
+ ///
+ /// Set the value for loading hidden tracks
+ ///
+ /// True to enable loading hidden tracks, false otherwise
+ public void SetLoadHiddenTracks(bool load) => _loadHiddenTracks = load;
+
///
public override void SetTotalIndexes()
{
@@ -330,17 +414,37 @@ namespace RedBookPlayer.Common.Discs
}
///
- protected override void LoadTrack(int track)
+ protected override void LoadTrack(int trackNumber)
{
if(_image == null)
return;
- if(track < 0 || track >= _image.Tracks.Count)
+ // If the track number is invalid, just return
+ if(trackNumber < _image.Tracks.Min(t => t.TrackSequence) || trackNumber > _image.Tracks.Max(t => t.TrackSequence))
return;
- ushort firstIndex = _image.Tracks[track].Indexes.Keys.Min();
- int firstSector = _image.Tracks[track].Indexes[firstIndex];
- CurrentSector = (ulong)(firstSector >= 0 ? firstSector : _image.Tracks[track].Indexes[1]);
+ // Cache the current track for easy access
+ Track track = GetTrack(trackNumber);
+
+ // Select the first index that has a sector offset greater than or equal to 0
+ CurrentSector = (ulong)(track?.Indexes.OrderBy(kvp => kvp.Key).First(kvp => kvp.Value >= 0).Value ?? 0);
+ }
+
+ ///
+ /// Get the track with the given sequence value, if possible
+ ///
+ /// Track number to retrieve
+ /// Track object for the requested sequence, null on error
+ private Track GetTrack(int trackNumber)
+ {
+ try
+ {
+ return _image.Tracks.FirstOrDefault(t => t.TrackSequence == trackNumber);
+ }
+ catch
+ {
+ return null;
+ }
}
///
diff --git a/RedBookPlayer.Common/Discs/OpticalDisc.cs b/RedBookPlayer.Common/Discs/OpticalDisc.cs
index 985b741..b522574 100644
--- a/RedBookPlayer.Common/Discs/OpticalDisc.cs
+++ b/RedBookPlayer.Common/Discs/OpticalDisc.cs
@@ -40,7 +40,7 @@ namespace RedBookPlayer.Common.Discs
///
/// Number of bytes per sector for the current track
///
- public int BytesPerSector => _image.Tracks[CurrentTrackNumber].TrackRawBytesPerSector;
+ public abstract int BytesPerSector { get; }
///
/// Represents the track type
@@ -97,36 +97,12 @@ namespace RedBookPlayer.Common.Discs
///
/// Try to move to the next track, wrapping around if necessary
///
- public void NextTrack()
- {
- if(_image == null)
- return;
-
- CurrentTrackNumber++;
- LoadTrack(CurrentTrackNumber);
- }
+ public abstract void NextTrack();
///
/// Try to move to the previous track, wrapping around if necessary
///
- /// True to play the hidden track, if it exists
- public void PreviousTrack(bool playHiddenTrack)
- {
- if(_image == null)
- return;
-
- if(CurrentSector < (ulong)_image.Tracks[CurrentTrackNumber].Indexes[1] + 75)
- {
- if(playHiddenTrack && CurrentTrackNumber == 0 && CurrentSector >= 75)
- CurrentSector = 0;
- else
- CurrentTrackNumber--;
- }
- else
- CurrentTrackNumber--;
-
- LoadTrack(CurrentTrackNumber);
- }
+ public abstract void PreviousTrack();
///
/// Try to move to the next track index
@@ -139,9 +115,8 @@ namespace RedBookPlayer.Common.Discs
/// Try to move to the previous track index
///
/// True if index changes can trigger a track change, false otherwise
- /// True to play the hidden track, if it exists
/// True if the track was changed, false otherwise
- public abstract bool PreviousIndex(bool changeTrack, bool playHiddenTrack);
+ public abstract bool PreviousIndex(bool changeTrack);
#endregion
diff --git a/RedBookPlayer.Common/Discs/OpticalDiscFactory.cs b/RedBookPlayer.Common/Discs/OpticalDiscFactory.cs
index 416cbe4..52ad9d8 100644
--- a/RedBookPlayer.Common/Discs/OpticalDiscFactory.cs
+++ b/RedBookPlayer.Common/Discs/OpticalDiscFactory.cs
@@ -13,10 +13,11 @@ namespace RedBookPlayer.Common.Discs
///
/// Path to load the image from
/// Generate a TOC if the disc is missing one [CompactDisc only]
+ /// Load hidden tracks for playback [CompactDisc only]
/// Load data tracks for playback [CompactDisc only]
/// True if the image should be playable immediately, false otherwise
/// Instantiated OpticalDisc, if possible
- public static OpticalDisc GenerateFromPath(string path, bool generateMissingToc, bool loadDataTracks, bool autoPlay)
+ public static OpticalDisc GenerateFromPath(string path, bool generateMissingToc, bool loadHiddenTracks, bool loadDataTracks, bool autoPlay)
{
try
{
@@ -32,7 +33,7 @@ namespace RedBookPlayer.Common.Discs
image.Open(filter);
// Generate and instantiate the disc
- return GenerateFromImage(image, generateMissingToc, loadDataTracks, autoPlay);
+ return GenerateFromImage(image, generateMissingToc, loadHiddenTracks, loadDataTracks, autoPlay);
}
catch
{
@@ -46,10 +47,11 @@ namespace RedBookPlayer.Common.Discs
///
/// IOpticalMediaImage to create from
/// Generate a TOC if the disc is missing one [CompactDisc only]
+ /// Load hidden tracks for playback [CompactDisc only]
/// Load data tracks for playback [CompactDisc only]
/// True if the image should be playable immediately, false otherwise
/// Instantiated OpticalDisc, if possible
- public static OpticalDisc GenerateFromImage(IOpticalMediaImage image, bool generateMissingToc, bool loadDataTracks, bool autoPlay)
+ public static OpticalDisc GenerateFromImage(IOpticalMediaImage image, bool generateMissingToc, bool loadHiddenTracks, bool loadDataTracks, bool autoPlay)
{
// If the image is not usable, we don't do anything
if(!IsUsableImage(image))
@@ -63,7 +65,7 @@ namespace RedBookPlayer.Common.Discs
{
case "Compact Disc":
case "GD":
- opticalDisc = new CompactDisc(generateMissingToc, loadDataTracks);
+ opticalDisc = new CompactDisc(generateMissingToc, loadHiddenTracks, loadDataTracks);
break;
default:
opticalDisc = null;
diff --git a/RedBookPlayer.Common/Hardware/Player.cs b/RedBookPlayer.Common/Hardware/Player.cs
index 6a4d20e..0fdc4d4 100644
--- a/RedBookPlayer.Common/Hardware/Player.cs
+++ b/RedBookPlayer.Common/Hardware/Player.cs
@@ -188,10 +188,11 @@ namespace RedBookPlayer.Common.Hardware
///
/// Path to the disc image
/// Generate a TOC if the disc is missing one [CompactDisc only]
+ /// Load hidden tracks for playback [CompactDisc only]
/// Load data tracks for playback [CompactDisc only]
/// True if playback should begin immediately, false otherwise
/// Default volume between 0 and 100 to use when starting playback
- public Player(string path, bool generateMissingToc, bool loadDataTracks, bool autoPlay, int defaultVolume)
+ public Player(string path, bool generateMissingToc, bool loadHiddenTracks, bool loadDataTracks, bool autoPlay, int defaultVolume)
{
// Set the internal state for initialization
Initialized = false;
@@ -199,7 +200,7 @@ namespace RedBookPlayer.Common.Hardware
_soundOutput.SetDeEmphasis(false);
// Initalize the disc
- _opticalDisc = OpticalDiscFactory.GenerateFromPath(path, generateMissingToc, loadDataTracks, autoPlay);
+ _opticalDisc = OpticalDiscFactory.GenerateFromPath(path, generateMissingToc, loadHiddenTracks, loadDataTracks, autoPlay);
if(_opticalDisc == null || !_opticalDisc.Initialized)
return;
@@ -295,8 +296,7 @@ namespace RedBookPlayer.Common.Hardware
///
/// Move to the previous playable track
///
- /// True to play the hidden track, if it exists
- public void PreviousTrack(bool playHiddenTrack)
+ public void PreviousTrack()
{
if(_opticalDisc == null || !_opticalDisc.Initialized)
return;
@@ -304,7 +304,7 @@ namespace RedBookPlayer.Common.Hardware
bool? wasPlaying = Playing;
if(wasPlaying == true) Pause();
- _opticalDisc.PreviousTrack(playHiddenTrack);
+ _opticalDisc.PreviousTrack();
if(_opticalDisc is CompactDisc compactDisc)
_soundOutput.SetDeEmphasis(compactDisc.TrackHasEmphasis);
@@ -334,8 +334,7 @@ namespace RedBookPlayer.Common.Hardware
/// Move to the previous index
///
/// True if index changes can trigger a track change, false otherwise
- /// True to play the hidden track, if it exists
- public void PreviousIndex(bool changeTrack, bool playHiddenTrack)
+ public void PreviousIndex(bool changeTrack)
{
if(_opticalDisc == null || !_opticalDisc.Initialized)
return;
@@ -343,7 +342,7 @@ namespace RedBookPlayer.Common.Hardware
bool? wasPlaying = Playing;
if(wasPlaying == true) Pause();
- _opticalDisc.PreviousIndex(changeTrack, playHiddenTrack);
+ _opticalDisc.PreviousIndex(changeTrack);
if(_opticalDisc is CompactDisc compactDisc)
_soundOutput.SetDeEmphasis(compactDisc.TrackHasEmphasis);
@@ -389,6 +388,12 @@ namespace RedBookPlayer.Common.Hardware
/// True to enable loading data tracks, false otherwise
public void SetLoadDataTracks(bool load) => (_opticalDisc as CompactDisc)?.SetLoadDataTracks(load);
+ ///
+ /// Set the value for loading hidden tracks [CompactDisc only]
+ ///
+ /// True to enable loading hidden tracks, false otherwise
+ public void SetLoadHiddenTracks(bool load) => (_opticalDisc as CompactDisc)?.SetLoadHiddenTracks(load);
+
///
/// Set the value for the volume
///
diff --git a/RedBookPlayer.Common/PlayerViewModel.cs b/RedBookPlayer.Common/PlayerViewModel.cs
index 635b4a4..04c62a2 100644
--- a/RedBookPlayer.Common/PlayerViewModel.cs
+++ b/RedBookPlayer.Common/PlayerViewModel.cs
@@ -186,16 +186,17 @@ namespace RedBookPlayer.Common
///
/// Path to the disc image
/// Generate a TOC if the disc is missing one [CompactDisc only]
+ /// Load hidden tracks for playback [CompactDisc only]
/// Load data tracks for playback [CompactDisc only]
/// True if playback should begin immediately, false otherwise
/// Default volume between 0 and 100 to use when starting playback
- public void Init(string path, bool generateMissingToc, bool loadDataTracks, bool autoPlay, int defaultVolume)
+ public void Init(string path, bool generateMissingToc, bool loadHiddenTracks, bool loadDataTracks, bool autoPlay, int defaultVolume)
{
// Stop current playback, if necessary
if(Playing != null) Playing = null;
// Create and attempt to initialize new Player
- _player = new Player(path, generateMissingToc, loadDataTracks, autoPlay, defaultVolume);
+ _player = new Player(path, generateMissingToc, loadHiddenTracks, loadDataTracks, autoPlay, defaultVolume);
if(Initialized)
{
_player.PropertyChanged += PlayerStateChanged;
@@ -228,8 +229,7 @@ namespace RedBookPlayer.Common
///
/// Move to the previous playable track
///
- /// True to play the hidden track, if it exists
- public void PreviousTrack(bool playHiddenTrack) => _player?.PreviousTrack(playHiddenTrack);
+ public void PreviousTrack() => _player?.PreviousTrack();
///
/// Move to the next index
@@ -241,8 +241,7 @@ namespace RedBookPlayer.Common
/// Move to the previous index
///
/// True if index changes can trigger a track change, false otherwise
- /// True to play the hidden track, if it exists
- public void PreviousIndex(bool changeTrack, bool playHiddenTrack) => _player?.PreviousIndex(changeTrack, playHiddenTrack);
+ public void PreviousIndex(bool changeTrack) => _player?.PreviousIndex(changeTrack);
///
/// Fast-forward playback by 75 sectors, if possible
@@ -270,6 +269,12 @@ namespace RedBookPlayer.Common
/// True to enable loading data tracks, false otherwise
public void SetLoadDataTracks(bool load) => _player?.SetLoadDataTracks(load);
+ ///
+ /// Set the value for loading hidden tracks [CompactDisc only]
+ ///
+ /// True to enable loading hidden tracks, false otherwise
+ public void SetLoadHiddenTracks(bool load) => _player?.SetLoadHiddenTracks(load);
+
///
/// Set the value for the volume
///
diff --git a/RedBookPlayer.GUI/PlayerView.xaml.cs b/RedBookPlayer.GUI/PlayerView.xaml.cs
index ef7d3b9..16f43cc 100644
--- a/RedBookPlayer.GUI/PlayerView.xaml.cs
+++ b/RedBookPlayer.GUI/PlayerView.xaml.cs
@@ -55,7 +55,7 @@ namespace RedBookPlayer.GUI
{
return await Dispatcher.UIThread.InvokeAsync(() =>
{
- PlayerViewModel.Init(path, App.Settings.GenerateMissingTOC, App.Settings.PlayDataTracks, App.Settings.AutoPlay, App.Settings.Volume);
+ PlayerViewModel.Init(path, App.Settings.GenerateMissingTOC, App.Settings.PlayHiddenTracks, App.Settings.PlayDataTracks, App.Settings.AutoPlay, App.Settings.Volume);
if (PlayerViewModel.Initialized)
MainWindow.Instance.Title = "RedBookPlayer - " + path.Split('/').Last().Split('\\').Last();
@@ -66,7 +66,11 @@ namespace RedBookPlayer.GUI
///
/// Update the view model with new settings
///
- public void UpdateViewModel() => PlayerViewModel.SetLoadDataTracks(App.Settings.PlayDataTracks);
+ public void UpdateViewModel()
+ {
+ PlayerViewModel.SetLoadDataTracks(App.Settings.PlayDataTracks);
+ PlayerViewModel.SetLoadHiddenTracks(App.Settings.PlayHiddenTracks);
+ }
///
/// Generate the digit string to be interpreted by the frontend
@@ -83,7 +87,7 @@ namespace RedBookPlayer.GUI
int[] numbers = new int[]
{
- PlayerViewModel.CurrentTrackNumber + 1,
+ PlayerViewModel.CurrentTrackNumber,
PlayerViewModel.CurrentTrackIndex,
(int)(sectorTime / (75 * 60)),
@@ -138,7 +142,7 @@ namespace RedBookPlayer.GUI
ulong sectorTime = PlayerViewModel.CurrentSector;
if(PlayerViewModel.SectionStartSector != 0)
sectorTime -= PlayerViewModel.SectionStartSector;
- else
+ else if (PlayerViewModel.CurrentTrackNumber > 0)
sectorTime += PlayerViewModel.TimeOffset;
return sectorTime;
@@ -261,11 +265,11 @@ namespace RedBookPlayer.GUI
public void NextTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.NextTrack();
- public void PreviousTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousTrack(App.Settings.AllowSkipHiddenTrack);
+ public void PreviousTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousTrack();
public void NextIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.NextIndex(App.Settings.IndexButtonChangeTrack);
- public void PreviousIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousIndex(App.Settings.IndexButtonChangeTrack, App.Settings.AllowSkipHiddenTrack);
+ public void PreviousIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousIndex(App.Settings.IndexButtonChangeTrack);
public void FastForwardButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.FastForward();
diff --git a/RedBookPlayer.GUI/Settings.cs b/RedBookPlayer.GUI/Settings.cs
index 2329e7c..855b2c8 100644
--- a/RedBookPlayer.GUI/Settings.cs
+++ b/RedBookPlayer.GUI/Settings.cs
@@ -21,9 +21,14 @@ namespace RedBookPlayer.GUI
public bool IndexButtonChangeTrack { get; set; } = false;
///
- /// Indicates if the index 0 of track 1 is treated like a hidden track
+ /// Indicates if hidden tracks should be played
///
- public bool AllowSkipHiddenTrack { get; set; } = false;
+ ///
+ /// Hidden tracks can be one of the following:
+ /// - TrackSequence == 0
+ /// - Larget pregap of track 1 (> 150 sectors)
+ ///
+ public bool PlayHiddenTracks { get; set; } = false;
///
/// Indicates if data tracks should be played like old, non-compliant players
diff --git a/RedBookPlayer.GUI/SettingsWindow.xaml b/RedBookPlayer.GUI/SettingsWindow.xaml
index ba416ba..158ba9e 100644
--- a/RedBookPlayer.GUI/SettingsWindow.xaml
+++ b/RedBookPlayer.GUI/SettingsWindow.xaml
@@ -17,8 +17,8 @@
Index navigation can change track
-
- Treat index 0 of track 1 as track 0 (hidden track)
+
+ Play hidden tracks