diff --git a/RedBookPlayer.Common/Discs/CompactDisc.cs b/RedBookPlayer.Common/Discs/CompactDisc.cs index 4a4591f..3338839 100644 --- a/RedBookPlayer.Common/Discs/CompactDisc.cs +++ b/RedBookPlayer.Common/Discs/CompactDisc.cs @@ -25,6 +25,10 @@ namespace RedBookPlayer.Common.Discs if(_image == null) return; + // Data tracks only and flag disabled means we can't do anything + if(_image.Tracks.All(t => t.TrackType != TrackType.Audio) && !_loadDataTracks) + return; + // Cache the value and the current track number int cachedValue = value; int cachedTrackNumber; @@ -58,6 +62,8 @@ namespace RedBookPlayer.Common.Discs // Cache the current track for easy access Track track = GetTrack(cachedTrackNumber); + if(track == null) + return; // Set track flags from subchannel data, if possible SetTrackFlags(track); @@ -74,10 +80,26 @@ namespace RedBookPlayer.Common.Discs } while(cachedValue != _currentTrackNumber); - this.RaiseAndSetIfChanged(ref _currentTrackNumber, cachedTrackNumber); + // If we looped around, ensure it reloads + if(cachedValue == _currentTrackNumber) + { + this.RaiseAndSetIfChanged(ref _currentTrackNumber, -1); - TotalIndexes = GetTrack(_currentTrackNumber).Indexes.Keys.Max(); - CurrentTrackIndex = GetTrack(_currentTrackNumber).Indexes.Keys.Min(); + Track track = GetTrack(cachedValue); + if(track == null) + return; + + SetTrackFlags(track); + } + + this.RaiseAndSetIfChanged(ref _currentTrackNumber, cachedValue); + + Track cachedTrack = GetTrack(cachedValue); + if(cachedTrack == null) + return; + + TotalIndexes = cachedTrack.Indexes.Keys.Max(); + CurrentTrackIndex = cachedTrack.Indexes.Keys.Min(); } } @@ -93,6 +115,8 @@ namespace RedBookPlayer.Common.Discs // Cache the current track for easy access Track track = GetTrack(CurrentTrackNumber); + if(track == null) + return; // Ensure that the value is valid, wrapping around if necessary ushort fixedValue = value; @@ -121,10 +145,12 @@ namespace RedBookPlayer.Common.Discs // Cache the current track for easy access Track track = GetTrack(CurrentTrackNumber); + if(track == null) + return; this.RaiseAndSetIfChanged(ref _currentSector, value); - if((CurrentTrackNumber < _image.Tracks.Count - 1 && CurrentSector >= GetTrack(CurrentTrackNumber + 1).TrackStartSector) + if((CurrentTrackNumber < _image.Tracks.Count - 1 && CurrentSector >= (GetTrack(CurrentTrackNumber + 1)?.TrackStartSector ?? 0)) || (CurrentTrackNumber > 0 && CurrentSector < track.TrackStartSector)) { foreach(Track trackData in _image.Tracks.ToArray().Reverse()) @@ -151,7 +177,7 @@ namespace RedBookPlayer.Common.Discs } /// - public override int BytesPerSector => GetTrack(CurrentTrackNumber).TrackRawBytesPerSector; + public override int BytesPerSector => GetTrack(CurrentTrackNumber)?.TrackRawBytesPerSector ?? 0; /// /// Represents the 4CH flag @@ -309,6 +335,8 @@ namespace RedBookPlayer.Common.Discs // Cache the current track for easy access Track track = GetTrack(CurrentTrackNumber); + if(track == null) + return false; // If the index is greater than the highest index, change tracks if needed if(CurrentTrackIndex + 1 > track.Indexes.Keys.Max()) @@ -349,6 +377,8 @@ namespace RedBookPlayer.Common.Discs // Cache the current track for easy access Track track = GetTrack(CurrentTrackNumber); + if(track == null) + return false; // If the index is less than the lowest index, change tracks if needed if(CurrentTrackIndex - 1 < track.Indexes.Keys.Min()) @@ -410,7 +440,7 @@ namespace RedBookPlayer.Common.Discs if(_image == null) return; - TotalIndexes = GetTrack(CurrentTrackNumber).Indexes.Keys.Max(); + TotalIndexes = GetTrack(CurrentTrackNumber)?.Indexes.Keys.Max() ?? 0; } /// diff --git a/RedBookPlayer.Common/Hardware/SoundOutput.cs b/RedBookPlayer.Common/Hardware/SoundOutput.cs index 4207801..5d78791 100644 --- a/RedBookPlayer.Common/Hardware/SoundOutput.cs +++ b/RedBookPlayer.Common/Hardware/SoundOutput.cs @@ -153,6 +153,13 @@ namespace RedBookPlayer.Common.Hardware // Set the current volume _soundOut.Volume = (float)Volume / 100; + // If we have an unreadable track, just return + if (_opticalDisc.BytesPerSector <= 0) + { + Array.Clear(buffer, offset, count); + return count; + } + // Determine how many sectors we can read ulong sectorsToRead; ulong zeroSectorsAmount; diff --git a/RedBookPlayer.GUI/PlayerView.xaml.cs b/RedBookPlayer.GUI/PlayerView.xaml.cs index 6696fd0..b6019f7 100644 --- a/RedBookPlayer.GUI/PlayerView.xaml.cs +++ b/RedBookPlayer.GUI/PlayerView.xaml.cs @@ -94,12 +94,18 @@ namespace RedBookPlayer.GUI if(PlayerViewModel?.Initialized != true) return string.Empty.PadLeft(20, '-'); + int usableTrackNumber = PlayerViewModel.CurrentTrackNumber; + if(usableTrackNumber < 0) + usableTrackNumber = 0; + else if(usableTrackNumber > 99) + usableTrackNumber = 99; + // Otherwise, take the current time into account ulong sectorTime = GetCurrentSectorTime(); int[] numbers = new int[] { - PlayerViewModel.CurrentTrackNumber, + usableTrackNumber, PlayerViewModel.CurrentTrackIndex, (int)(sectorTime / (75 * 60)),