From 60edd5777173089b6203a0cde4591220fff3aec3 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Mon, 28 Jun 2021 21:08:16 -0700 Subject: [PATCH] Use IOpticalMediaImage, check 4CH, better subchannel usage --- RedBookPlayer/PlayableDisc.cs | 124 ++++++++++++++++++++++++------- RedBookPlayer/PlayerView.xaml | 2 + RedBookPlayer/PlayerView.xaml.cs | 8 +- RedBookPlayer/PlayerViewModel.cs | 7 ++ 4 files changed, 110 insertions(+), 31 deletions(-) diff --git a/RedBookPlayer/PlayableDisc.cs b/RedBookPlayer/PlayableDisc.cs index 36c0e17..9f22e8e 100644 --- a/RedBookPlayer/PlayableDisc.cs +++ b/RedBookPlayer/PlayableDisc.cs @@ -2,8 +2,8 @@ using System; using System.Collections.Generic; using System.Linq; using Aaru.CommonTypes.Enums; +using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Structs; -using Aaru.DiscImages; using Aaru.Helpers; using static Aaru.Decoders.CD.FullTOC; @@ -44,32 +44,16 @@ namespace RedBookPlayer // Cache the current track for easy access Track track = _image.Tracks[CurrentTrackNumber]; - // Set new track-specific data - byte[] flagsData = _image.ReadSectorTag(track.TrackSequence, SectorTagType.CdTrackFlags); - ApplyDeEmphasis = ((CdFlags)flagsData[0]).HasFlag(CdFlags.PreEmphasis); + // Set track flags from subchannel data, if possible + SetTrackFlags(track); - try - { - byte[] subchannel = _image.ReadSectorTag(track.TrackStartSector, SectorTagType.CdSectorSubchannel); - - if(!ApplyDeEmphasis) - ApplyDeEmphasis = (subchannel[3] & 0b01000000) != 0; - - CopyAllowed = (subchannel[2] & 0b01000000) != 0; - TrackType = (subchannel[1] & 0b01000000) != 0 ? Aaru.CommonTypes.Enums.TrackType.Data : Aaru.CommonTypes.Enums.TrackType.Audio; - } - catch(ArgumentException) - { - TrackType = track.TrackType; - } - - TrackHasEmphasis = ApplyDeEmphasis; + ApplyDeEmphasis = TrackHasEmphasis; TotalIndexes = track.Indexes.Keys.Max(); CurrentTrackIndex = track.Indexes.Keys.Min(); // If we're not playing data tracks, skip - if(!App.Settings.PlayDataTracks && TrackType != Aaru.CommonTypes.Enums.TrackType.Audio) + if(!App.Settings.PlayDataTracks && TrackType != TrackType.Audio) { if(increment) NextTrack(); @@ -157,19 +141,24 @@ namespace RedBookPlayer public bool TrackHasEmphasis { get; private set; } = false; /// - /// Indicates if de-emphasis should be applied + /// Represents the PRE flag /// public bool ApplyDeEmphasis { get; private set; } = false; /// - /// Represents the copy allowed flag + /// Represents the DCP flag /// public bool CopyAllowed { get; private set; } = false; /// /// Represents the track type /// - public TrackType? TrackType { get; private set; } + public TrackType TrackType { get; private set; } + + /// + /// Represents the 4CH flag + /// + public bool QuadChannel { get; private set; } = false; /// /// Represents the sector starting the section @@ -208,7 +197,7 @@ namespace RedBookPlayer /// /// Currently loaded disc image /// - private AaruFormat _image; + private IOpticalMediaImage _image; /// /// Current track number @@ -237,7 +226,7 @@ namespace RedBookPlayer /// /// Aaruformat image to load /// True if playback should begin immediately, false otherwise - public void Init(AaruFormat image, bool autoPlay = false) + public void Init(IOpticalMediaImage image, bool autoPlay = false) { // If the image is null, we can't do anything if(image == null) @@ -657,6 +646,89 @@ namespace RedBookPlayer CurrentSector = (ulong)(firstSector >= 0 ? firstSector : _image.Tracks[track].Indexes[1]); } + /// + /// Set default track flags for the current track + /// + /// Track object to read from + private void SetDefaultTrackFlags(Track track) + { + QuadChannel = false; + TrackType = track.TrackType; + CopyAllowed = false; + TrackHasEmphasis = false; + } + + /// + /// Set track flags from the current track + /// + /// Track object to read from + private void SetTrackFlags(Track track) + { + try + { + ulong currentSector = track.TrackStartSector; + for (int i = 0; i < 16; i++) + { + // Try to read the subchannel + byte[] subBuf = _image.ReadSectorTag(track.TrackStartSector, SectorTagType.CdSectorSubchannel); + if(subBuf == null || subBuf.Length < 4) + return; + + // Check the expected track, if possible + int adr = subBuf[0] & 0x0F; + if(adr == 1) + { + if(subBuf[1] > track.TrackSequence) + { + currentSector--; + continue; + } + else if(subBuf[1] < track.TrackSequence) + { + currentSector++; + continue; + } + } + + // Set the track flags from subchannel data + int control = (subBuf[0] & 0xF0) / 16; + switch((control & 0xC) / 4) + { + case 0: + QuadChannel = false; + TrackType = TrackType.Audio; + TrackHasEmphasis = (control & 0x01) == 1; + break; + case 1: + QuadChannel = false; + TrackType = TrackType.Data; + TrackHasEmphasis = false; + break; + case 2: + QuadChannel = true; + TrackType = TrackType.Audio; + TrackHasEmphasis = (control & 0x01) == 1; + break; + default: + QuadChannel = false; + TrackType = track.TrackType; + TrackHasEmphasis = false; + break; + } + + CopyAllowed = (control & 0x02) > 0; + return; + } + + // If we didn't find subchannel data, assume defaults + SetDefaultTrackFlags(track); + } + catch(Exception) + { + SetDefaultTrackFlags(track); + } + } + #endregion } } diff --git a/RedBookPlayer/PlayerView.xaml b/RedBookPlayer/PlayerView.xaml index 7b0f528..2213eba 100644 --- a/RedBookPlayer/PlayerView.xaml +++ b/RedBookPlayer/PlayerView.xaml @@ -94,6 +94,8 @@ EMPHASIS COPY COPY + 4CH + 4CH HIDDEN HIDDEN diff --git a/RedBookPlayer/PlayerView.xaml.cs b/RedBookPlayer/PlayerView.xaml.cs index f5ac532..095e332 100644 --- a/RedBookPlayer/PlayerView.xaml.cs +++ b/RedBookPlayer/PlayerView.xaml.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading.Tasks; using System.Timers; using Aaru.CommonTypes.Enums; +using Aaru.CommonTypes.Interfaces; using Aaru.DiscImages; using Aaru.Filters; using Avalonia; @@ -199,16 +200,12 @@ namespace RedBookPlayer /// /// Aaruformat image file /// True if the image is playble, false otherwise - private bool IsPlayableImage(AaruFormat image) + private bool IsPlayableImage(IOpticalMediaImage image) { // Invalid images can't be played if (image == null) return false; - // Tape images are not supported - if (image.IsTape) - return false; - // Determine based on media type // TODO: Can we be more granular with sub types? (string type, string _) = Aaru.CommonTypes.Metadata.MediaType.MediaTypeToString(image.Info.MediaType); @@ -278,6 +275,7 @@ namespace RedBookPlayer dataContext.ApplyDeEmphasis = PlayableDisc.ApplyDeEmphasis; dataContext.TrackHasEmphasis = PlayableDisc.TrackHasEmphasis; dataContext.CopyAllowed = PlayableDisc.CopyAllowed; + dataContext.QuadChannel = PlayableDisc.QuadChannel; dataContext.IsAudioTrack = PlayableDisc.TrackType == TrackType.Audio; dataContext.IsDataTrack = PlayableDisc.TrackType != TrackType.Audio; } diff --git a/RedBookPlayer/PlayerViewModel.cs b/RedBookPlayer/PlayerViewModel.cs index a44dcc4..17e058f 100644 --- a/RedBookPlayer/PlayerViewModel.cs +++ b/RedBookPlayer/PlayerViewModel.cs @@ -32,6 +32,13 @@ namespace RedBookPlayer set => this.RaiseAndSetIfChanged(ref _copyAllowed, value); } + private bool _quadChannel; + public bool QuadChannel + { + get => _quadChannel; + set => this.RaiseAndSetIfChanged(ref _quadChannel, value); + } + private bool _isAudioTrack; public bool IsAudioTrack {