diff --git a/RedBookPlayer.Models/Hardware/Player.cs b/RedBookPlayer.Models/Hardware/Player.cs
index 89cecb0..fef2b22 100644
--- a/RedBookPlayer.Models/Hardware/Player.cs
+++ b/RedBookPlayer.Models/Hardware/Player.cs
@@ -829,7 +829,6 @@ namespace RedBookPlayer.Models.Hardware
///
/// Track number to attempt to load
/// True if the track was changed, false otherwise
- /// TODO: This needs to reset the pointer in the track playback order
public bool SelectTrack(int trackNumber)
{
if(_opticalDiscs[CurrentDisc] == null || !_opticalDiscs[CurrentDisc].Initialized)
@@ -972,6 +971,99 @@ namespace RedBookPlayer.Models.Hardware
return true;
}
+ ///
+ /// Select a track by number within a disc
+ ///
+ /// Track number to attempt to load
+ /// True if the track was changed, false otherwise
+ public bool SelectTrackWithinDisc(int trackNumber)
+ {
+ if(_opticalDiscs[CurrentDisc] == null || !_opticalDiscs[CurrentDisc].Initialized)
+ return false;
+
+ PlayerState wasPlaying = PlayerState;
+ if(wasPlaying == PlayerState.Playing)
+ Pause();
+
+ // CompactDisc needs special handling of track wraparound
+ if (_opticalDiscs[CurrentDisc] is CompactDisc compactDisc)
+ {
+ // Cache the value and the current track number
+ int cachedValue = trackNumber;
+ int cachedTrackNumber;
+
+ // If we have an invalid current track number, set it to the minimum
+ if(!compactDisc.Tracks.Any(t => t.TrackSequence == _currentTrackNumber))
+ _currentTrackNumber = (int)compactDisc.Tracks.Min(t => t.TrackSequence);
+
+ // Check if we're incrementing or decrementing the track
+ bool increment = cachedValue >= _currentTrackNumber;
+
+ do
+ {
+ // If we're over the last track, wrap around
+ if(cachedValue > compactDisc.Tracks.Max(t => t.TrackSequence))
+ {
+ cachedValue = (int)compactDisc.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)compactDisc.Tracks.Max(t => t.TrackSequence);
+ }
+
+ // If we're under the first valid track, wrap around
+ else if(cachedValue < compactDisc.Tracks.Min(t => t.TrackSequence))
+ {
+ cachedValue = (int)compactDisc.Tracks.Max(t => t.TrackSequence);
+ }
+
+ cachedTrackNumber = cachedValue;
+
+ // Cache the current track for easy access
+ Track track = compactDisc.GetTrack(cachedTrackNumber);
+ if(track == null)
+ return false;
+
+ // If the track is playable, just return
+ if((track.TrackType == TrackType.Audio || DataPlayback != DataPlayback.Skip)
+ && (SessionHandling == SessionHandling.AllSessions || track.TrackSession == 1))
+ {
+ break;
+ }
+
+ // If we're not playing the track, skip
+ if(increment)
+ cachedValue++;
+ else
+ cachedValue--;
+ }
+ while(cachedValue != _currentTrackNumber);
+
+ // Load the now-valid value
+ compactDisc.LoadTrack(cachedTrackNumber);
+ ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
+ }
+ else
+ {
+ if(trackNumber >= _opticalDiscs[CurrentDisc].TotalTracks)
+ trackNumber = 1;
+ else if(trackNumber < 1)
+ trackNumber = _opticalDiscs[CurrentDisc].TotalTracks - 1;
+
+ _opticalDiscs[CurrentDisc].LoadTrack(trackNumber);
+ }
+
+ LoadTrackList();
+ if(wasPlaying == PlayerState.Playing)
+ Play();
+
+ return true;
+ }
+
///
/// Select a track in the relative track list by number
///
@@ -995,7 +1087,7 @@ namespace RedBookPlayer.Models.Hardware
_currentTrackInOrder = relativeTrackNumber;
KeyValuePair discTrackPair = _trackPlaybackOrder[relativeTrackNumber];
SelectDisc(discTrackPair.Key);
- if(SelectTrack(discTrackPair.Value))
+ if(SelectTrackWithinDisc(discTrackPair.Value))
break;
}
while(true);