mirror of
https://github.com/aaru-dps/RedBookPlayer.git
synced 2025-12-16 19:24:41 +00:00
Use relative track locations
This commit is contained in:
@@ -465,11 +465,17 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
currentFoundTrack = _trackPlaybackOrder.FindIndex(kvp => kvp.Key == CurrentDisc && kvp.Value == CurrentTrackNumber);
|
currentFoundTrack = _trackPlaybackOrder.FindIndex(kvp => kvp.Key == CurrentDisc && kvp.Value == CurrentTrackNumber);
|
||||||
if(currentFoundTrack == -1)
|
if(currentFoundTrack == -1)
|
||||||
currentFoundTrack = _trackPlaybackOrder.Where(kvp => kvp.Key == CurrentDisc).Min(kvp => kvp.Value);
|
currentFoundTrack = _trackPlaybackOrder.Where(kvp => kvp.Key == CurrentDisc).Min(kvp => kvp.Value);
|
||||||
|
|
||||||
|
CurrentDisc = _trackPlaybackOrder[currentFoundTrack].Key;
|
||||||
|
CurrentTrackNumber = _trackPlaybackOrder[currentFoundTrack].Value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int lowestDiscNumber = _trackPlaybackOrder.Min(kvp => kvp.Key);
|
int lowestDiscNumber = _trackPlaybackOrder.Min(kvp => kvp.Key);
|
||||||
currentFoundTrack = _trackPlaybackOrder.Where(kvp => kvp.Key == lowestDiscNumber).Min(kvp => kvp.Value);
|
currentFoundTrack = _trackPlaybackOrder.Where(kvp => kvp.Key == lowestDiscNumber).Min(kvp => kvp.Value);
|
||||||
|
|
||||||
|
CurrentDisc = _trackPlaybackOrder[currentFoundTrack].Key;
|
||||||
|
CurrentTrackNumber = _trackPlaybackOrder[currentFoundTrack].Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentTrackInOrder = currentFoundTrack;
|
_currentTrackInOrder = currentFoundTrack;
|
||||||
@@ -562,8 +568,7 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_soundOutput.Stop();
|
_soundOutput.Stop();
|
||||||
CurrentTrackNumber = 0;
|
SelectRelativeTrack(0);
|
||||||
SelectTrack(1);
|
|
||||||
PlayerState = PlayerState.Stopped;
|
PlayerState = PlayerState.Stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,6 +586,10 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
_opticalDiscs[CurrentDisc] = null;
|
_opticalDiscs[CurrentDisc] = null;
|
||||||
LoadTrackList();
|
LoadTrackList();
|
||||||
|
|
||||||
|
// Force a refresh of the state information
|
||||||
|
OpticalDiscStateChanged(this, null);
|
||||||
|
SoundOutputStateChanged(this, null);
|
||||||
|
|
||||||
// Only de-initialize the player if all discs are ejected
|
// Only de-initialize the player if all discs are ejected
|
||||||
if(_opticalDiscs.All(d => d == null || !d.Initialized))
|
if(_opticalDiscs.All(d => d == null || !d.Initialized))
|
||||||
{
|
{
|
||||||
@@ -608,13 +617,13 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
/// Move to the next playable track
|
/// Move to the next playable track
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>TODO: This should follow the track playback order</remarks>
|
/// <remarks>TODO: This should follow the track playback order</remarks>
|
||||||
public void NextTrack() => SelectTrack(CurrentTrackNumber + 1);
|
public void NextTrack() => SelectRelativeTrack(_currentTrackInOrder + 1);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Move to the previous playable track
|
/// Move to the previous playable track
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>TODO: This should follow the track playback order</remarks>
|
/// <remarks>TODO: This should follow the track playback order</remarks>
|
||||||
public void PreviousTrack() => SelectTrack(CurrentTrackNumber - 1);
|
public void PreviousTrack() => SelectRelativeTrack(_currentTrackInOrder - 1);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Move to the next index
|
/// Move to the next index
|
||||||
@@ -695,6 +704,7 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
_currentSectorReadPosition += count;
|
_currentSectorReadPosition += count;
|
||||||
if(_currentSectorReadPosition >= _opticalDiscs[CurrentDisc].BytesPerSector)
|
if(_currentSectorReadPosition >= _opticalDiscs[CurrentDisc].BytesPerSector)
|
||||||
{
|
{
|
||||||
|
int previousTrack = CurrentTrackNumber;
|
||||||
ulong newSectorValue = _opticalDiscs[CurrentDisc].CurrentSector + (ulong)(_currentSectorReadPosition / _opticalDiscs[CurrentDisc].BytesPerSector);
|
ulong newSectorValue = _opticalDiscs[CurrentDisc].CurrentSector + (ulong)(_currentSectorReadPosition / _opticalDiscs[CurrentDisc].BytesPerSector);
|
||||||
if(newSectorValue >= _opticalDiscs[CurrentDisc].TotalSectors)
|
if(newSectorValue >= _opticalDiscs[CurrentDisc].TotalSectors)
|
||||||
{
|
{
|
||||||
@@ -718,6 +728,10 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
_opticalDiscs[CurrentDisc].SetCurrentSector(newSectorValue);
|
_opticalDiscs[CurrentDisc].SetCurrentSector(newSectorValue);
|
||||||
_currentSectorReadPosition %= _opticalDiscs[CurrentDisc].BytesPerSector;
|
_currentSectorReadPosition %= _opticalDiscs[CurrentDisc].BytesPerSector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we are supposed to change tracks, get the next one from the list
|
||||||
|
if(CurrentTrackNumber != previousTrack)
|
||||||
|
NextTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@@ -727,7 +741,6 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
/// Select a disc by number
|
/// Select a disc by number
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="discNumber">Disc number to attempt to load</param>
|
/// <param name="discNumber">Disc number to attempt to load</param>
|
||||||
/// <remarks>TODO: This needs to reset the pointer in the track playback order</remarks>
|
|
||||||
public void SelectDisc(int discNumber)
|
public void SelectDisc(int discNumber)
|
||||||
{
|
{
|
||||||
PlayerState wasPlaying = PlayerState;
|
PlayerState wasPlaying = PlayerState;
|
||||||
@@ -740,6 +753,7 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
if (_opticalDiscs[CurrentDisc] != null && _opticalDiscs[CurrentDisc].Initialized)
|
if (_opticalDiscs[CurrentDisc] != null && _opticalDiscs[CurrentDisc].Initialized)
|
||||||
{
|
{
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
|
SelectTrack(1);
|
||||||
OpticalDiscStateChanged(this, null);
|
OpticalDiscStateChanged(this, null);
|
||||||
SoundOutputStateChanged(this, null);
|
SoundOutputStateChanged(this, null);
|
||||||
|
|
||||||
@@ -824,159 +838,12 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
Play();
|
Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Select a track by number
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="trackNumber">Track number to attempt to load</param>
|
|
||||||
/// <returns>True if the track was changed, false otherwise</returns>
|
|
||||||
public bool SelectTrack(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;
|
|
||||||
|
|
||||||
// Take care of disc switching first
|
|
||||||
if(DiscHandling == DiscHandling.MultiDisc)
|
|
||||||
{
|
|
||||||
if(trackNumber > (int)compactDisc.Tracks.Max(t => t.TrackSequence))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
NextDisc();
|
|
||||||
}
|
|
||||||
while(_opticalDiscs[CurrentDisc] == null || !_opticalDiscs[CurrentDisc].Initialized);
|
|
||||||
|
|
||||||
if(wasPlaying == PlayerState.Playing)
|
|
||||||
Play();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if((trackNumber < 1 && !LoadHiddenTracks) || (trackNumber < (int)compactDisc.Tracks.Min(t => t.TrackSequence)))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
PreviousDisc();
|
|
||||||
}
|
|
||||||
while(_opticalDiscs[CurrentDisc] == null || !_opticalDiscs[CurrentDisc].Initialized);
|
|
||||||
|
|
||||||
SelectTrack(-1);
|
|
||||||
if(wasPlaying == PlayerState.Playing)
|
|
||||||
Play();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
if(DiscHandling == DiscHandling.MultiDisc)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
NextDisc();
|
|
||||||
}
|
|
||||||
while(_opticalDiscs[CurrentDisc] == null || !_opticalDiscs[CurrentDisc].Initialized);
|
|
||||||
}
|
|
||||||
|
|
||||||
trackNumber = 1;
|
|
||||||
}
|
|
||||||
else if(trackNumber < 1)
|
|
||||||
{
|
|
||||||
if(DiscHandling == DiscHandling.MultiDisc)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
PreviousDisc();
|
|
||||||
}
|
|
||||||
while(_opticalDiscs[CurrentDisc] == null || !_opticalDiscs[CurrentDisc].Initialized);
|
|
||||||
trackNumber = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
trackNumber = _opticalDiscs[CurrentDisc].TotalTracks - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_opticalDiscs[CurrentDisc].LoadTrack(trackNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(wasPlaying == PlayerState.Playing)
|
|
||||||
Play();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Select a track by number within a disc
|
/// Select a track by number within a disc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="trackNumber">Track number to attempt to load</param>
|
/// <param name="trackNumber">Track number to attempt to load</param>
|
||||||
/// <returns>True if the track was changed, false otherwise</returns>
|
/// <returns>True if the track was changed, false otherwise</returns>
|
||||||
public bool SelectTrackWithinDisc(int trackNumber)
|
public bool SelectTrack(int trackNumber)
|
||||||
{
|
{
|
||||||
if(_opticalDiscs[CurrentDisc] == null || !_opticalDiscs[CurrentDisc].Initialized)
|
if(_opticalDiscs[CurrentDisc] == null || !_opticalDiscs[CurrentDisc].Initialized)
|
||||||
return false;
|
return false;
|
||||||
@@ -1064,38 +931,6 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Select a track in the relative track list by number
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="relativeTrackNumber">Relative track number to attempt to load</param>
|
|
||||||
public void SelectRelativeTrack(int relativeTrackNumber)
|
|
||||||
{
|
|
||||||
if(_trackPlaybackOrder == null || _trackPlaybackOrder.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PlayerState wasPlaying = PlayerState;
|
|
||||||
if(wasPlaying == PlayerState.Playing)
|
|
||||||
Pause();
|
|
||||||
|
|
||||||
if(relativeTrackNumber < 0)
|
|
||||||
relativeTrackNumber = _trackPlaybackOrder.Count - 1;
|
|
||||||
else if(relativeTrackNumber >= _trackPlaybackOrder.Count)
|
|
||||||
relativeTrackNumber = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
_currentTrackInOrder = relativeTrackNumber;
|
|
||||||
KeyValuePair<int, int> discTrackPair = _trackPlaybackOrder[relativeTrackNumber];
|
|
||||||
SelectDisc(discTrackPair.Key);
|
|
||||||
if(SelectTrackWithinDisc(discTrackPair.Value))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while(true);
|
|
||||||
|
|
||||||
if(wasPlaying == PlayerState.Playing)
|
|
||||||
Play();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determine the number of real and zero sectors to read
|
/// Determine the number of real and zero sectors to read
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1175,6 +1010,44 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
return audioDataSegment;
|
return audioDataSegment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Select a track in the relative track list by number
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="relativeTrackNumber">Relative track number to attempt to load</param>
|
||||||
|
private void SelectRelativeTrack(int relativeTrackNumber)
|
||||||
|
{
|
||||||
|
if(_trackPlaybackOrder == null || _trackPlaybackOrder.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlayerState wasPlaying = PlayerState;
|
||||||
|
if(wasPlaying == PlayerState.Playing)
|
||||||
|
Pause();
|
||||||
|
|
||||||
|
if(relativeTrackNumber < 0)
|
||||||
|
relativeTrackNumber = _trackPlaybackOrder.Count - 1;
|
||||||
|
else if(relativeTrackNumber >= _trackPlaybackOrder.Count)
|
||||||
|
relativeTrackNumber = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
_currentTrackInOrder = relativeTrackNumber;
|
||||||
|
KeyValuePair<int, int> discTrackPair = _trackPlaybackOrder[relativeTrackNumber];
|
||||||
|
SelectDisc(discTrackPair.Key);
|
||||||
|
if(SelectTrack(discTrackPair.Value))
|
||||||
|
break;
|
||||||
|
|
||||||
|
relativeTrackNumber++;
|
||||||
|
if(relativeTrackNumber < 0)
|
||||||
|
relativeTrackNumber = _trackPlaybackOrder.Count - 1;
|
||||||
|
else if(relativeTrackNumber >= _trackPlaybackOrder.Count)
|
||||||
|
relativeTrackNumber = 0;
|
||||||
|
}
|
||||||
|
while(true);
|
||||||
|
|
||||||
|
if(wasPlaying == PlayerState.Playing)
|
||||||
|
Play();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Volume
|
#region Volume
|
||||||
@@ -1358,17 +1231,8 @@ namespace RedBookPlayer.Models.Hardware
|
|||||||
case RepeatMode.Single:
|
case RepeatMode.Single:
|
||||||
_opticalDiscs[CurrentDisc].LoadTrack(CurrentTrackNumber);
|
_opticalDiscs[CurrentDisc].LoadTrack(CurrentTrackNumber);
|
||||||
break;
|
break;
|
||||||
case RepeatMode.All when DiscHandling == DiscHandling.SingleDisc:
|
case RepeatMode.All:
|
||||||
SelectTrack(1);
|
SelectRelativeTrack(0);
|
||||||
break;
|
|
||||||
case RepeatMode.All when DiscHandling == DiscHandling.MultiDisc:
|
|
||||||
do
|
|
||||||
{
|
|
||||||
NextDisc();
|
|
||||||
}
|
|
||||||
while(_opticalDiscs[CurrentDisc] == null || !_opticalDiscs[CurrentDisc].Initialized);
|
|
||||||
|
|
||||||
SelectTrack(1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user