mirror of
https://github.com/aaru-dps/RedBookPlayer.git
synced 2025-12-16 19:24:41 +00:00
Use IOpticalMediaImage, check 4CH, better subchannel usage
This commit is contained in:
@@ -2,8 +2,8 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Aaru.CommonTypes.Enums;
|
using Aaru.CommonTypes.Enums;
|
||||||
|
using Aaru.CommonTypes.Interfaces;
|
||||||
using Aaru.CommonTypes.Structs;
|
using Aaru.CommonTypes.Structs;
|
||||||
using Aaru.DiscImages;
|
|
||||||
using Aaru.Helpers;
|
using Aaru.Helpers;
|
||||||
using static Aaru.Decoders.CD.FullTOC;
|
using static Aaru.Decoders.CD.FullTOC;
|
||||||
|
|
||||||
@@ -44,32 +44,16 @@ namespace RedBookPlayer
|
|||||||
// Cache the current track for easy access
|
// Cache the current track for easy access
|
||||||
Track track = _image.Tracks[CurrentTrackNumber];
|
Track track = _image.Tracks[CurrentTrackNumber];
|
||||||
|
|
||||||
// Set new track-specific data
|
// Set track flags from subchannel data, if possible
|
||||||
byte[] flagsData = _image.ReadSectorTag(track.TrackSequence, SectorTagType.CdTrackFlags);
|
SetTrackFlags(track);
|
||||||
ApplyDeEmphasis = ((CdFlags)flagsData[0]).HasFlag(CdFlags.PreEmphasis);
|
|
||||||
|
|
||||||
try
|
ApplyDeEmphasis = TrackHasEmphasis;
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
TotalIndexes = track.Indexes.Keys.Max();
|
TotalIndexes = track.Indexes.Keys.Max();
|
||||||
CurrentTrackIndex = track.Indexes.Keys.Min();
|
CurrentTrackIndex = track.Indexes.Keys.Min();
|
||||||
|
|
||||||
// If we're not playing data tracks, skip
|
// 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)
|
if(increment)
|
||||||
NextTrack();
|
NextTrack();
|
||||||
@@ -157,19 +141,24 @@ namespace RedBookPlayer
|
|||||||
public bool TrackHasEmphasis { get; private set; } = false;
|
public bool TrackHasEmphasis { get; private set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates if de-emphasis should be applied
|
/// Represents the PRE flag
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ApplyDeEmphasis { get; private set; } = false;
|
public bool ApplyDeEmphasis { get; private set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the copy allowed flag
|
/// Represents the DCP flag
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CopyAllowed { get; private set; } = false;
|
public bool CopyAllowed { get; private set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the track type
|
/// Represents the track type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TrackType? TrackType { get; private set; }
|
public TrackType TrackType { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the 4CH flag
|
||||||
|
/// </summary>
|
||||||
|
public bool QuadChannel { get; private set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the sector starting the section
|
/// Represents the sector starting the section
|
||||||
@@ -208,7 +197,7 @@ namespace RedBookPlayer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Currently loaded disc image
|
/// Currently loaded disc image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private AaruFormat _image;
|
private IOpticalMediaImage _image;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current track number
|
/// Current track number
|
||||||
@@ -237,7 +226,7 @@ namespace RedBookPlayer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="image">Aaruformat image to load</param>
|
/// <param name="image">Aaruformat image to load</param>
|
||||||
/// <param name="autoPlay">True if playback should begin immediately, false otherwise</param>
|
/// <param name="autoPlay">True if playback should begin immediately, false otherwise</param>
|
||||||
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 the image is null, we can't do anything
|
||||||
if(image == null)
|
if(image == null)
|
||||||
@@ -657,6 +646,89 @@ namespace RedBookPlayer
|
|||||||
CurrentSector = (ulong)(firstSector >= 0 ? firstSector : _image.Tracks[track].Indexes[1]);
|
CurrentSector = (ulong)(firstSector >= 0 ? firstSector : _image.Tracks[track].Indexes[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set default track flags for the current track
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="track">Track object to read from</param>
|
||||||
|
private void SetDefaultTrackFlags(Track track)
|
||||||
|
{
|
||||||
|
QuadChannel = false;
|
||||||
|
TrackType = track.TrackType;
|
||||||
|
CopyAllowed = false;
|
||||||
|
TrackHasEmphasis = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set track flags from the current track
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="track">Track object to read from</param>
|
||||||
|
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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,8 @@
|
|||||||
<TextBlock Margin="0,0,16,0" IsVisible="{Binding TrackHasEmphasis}">EMPHASIS</TextBlock>
|
<TextBlock Margin="0,0,16,0" IsVisible="{Binding TrackHasEmphasis}">EMPHASIS</TextBlock>
|
||||||
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding !CopyAllowed}">COPY</TextBlock>
|
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding !CopyAllowed}">COPY</TextBlock>
|
||||||
<TextBlock Margin="0,0,16,0" IsVisible="{Binding CopyAllowed}">COPY</TextBlock>
|
<TextBlock Margin="0,0,16,0" IsVisible="{Binding CopyAllowed}">COPY</TextBlock>
|
||||||
|
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding !QuadChannel}">4CH</TextBlock>
|
||||||
|
<TextBlock Margin="0,0,16,0" IsVisible="{Binding QuadChannel}">4CH</TextBlock>
|
||||||
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding !HiddenTrack}">HIDDEN</TextBlock>
|
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding !HiddenTrack}">HIDDEN</TextBlock>
|
||||||
<TextBlock Margin="0,0,16,0" IsVisible="{Binding HiddenTrack}">HIDDEN</TextBlock>
|
<TextBlock Margin="0,0,16,0" IsVisible="{Binding HiddenTrack}">HIDDEN</TextBlock>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using Aaru.CommonTypes.Enums;
|
using Aaru.CommonTypes.Enums;
|
||||||
|
using Aaru.CommonTypes.Interfaces;
|
||||||
using Aaru.DiscImages;
|
using Aaru.DiscImages;
|
||||||
using Aaru.Filters;
|
using Aaru.Filters;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
@@ -199,16 +200,12 @@ namespace RedBookPlayer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="image">Aaruformat image file</param>
|
/// <param name="image">Aaruformat image file</param>
|
||||||
/// <returns>True if the image is playble, false otherwise</returns>
|
/// <returns>True if the image is playble, false otherwise</returns>
|
||||||
private bool IsPlayableImage(AaruFormat image)
|
private bool IsPlayableImage(IOpticalMediaImage image)
|
||||||
{
|
{
|
||||||
// Invalid images can't be played
|
// Invalid images can't be played
|
||||||
if (image == null)
|
if (image == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Tape images are not supported
|
|
||||||
if (image.IsTape)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Determine based on media type
|
// Determine based on media type
|
||||||
// TODO: Can we be more granular with sub types?
|
// TODO: Can we be more granular with sub types?
|
||||||
(string type, string _) = Aaru.CommonTypes.Metadata.MediaType.MediaTypeToString(image.Info.MediaType);
|
(string type, string _) = Aaru.CommonTypes.Metadata.MediaType.MediaTypeToString(image.Info.MediaType);
|
||||||
@@ -278,6 +275,7 @@ namespace RedBookPlayer
|
|||||||
dataContext.ApplyDeEmphasis = PlayableDisc.ApplyDeEmphasis;
|
dataContext.ApplyDeEmphasis = PlayableDisc.ApplyDeEmphasis;
|
||||||
dataContext.TrackHasEmphasis = PlayableDisc.TrackHasEmphasis;
|
dataContext.TrackHasEmphasis = PlayableDisc.TrackHasEmphasis;
|
||||||
dataContext.CopyAllowed = PlayableDisc.CopyAllowed;
|
dataContext.CopyAllowed = PlayableDisc.CopyAllowed;
|
||||||
|
dataContext.QuadChannel = PlayableDisc.QuadChannel;
|
||||||
dataContext.IsAudioTrack = PlayableDisc.TrackType == TrackType.Audio;
|
dataContext.IsAudioTrack = PlayableDisc.TrackType == TrackType.Audio;
|
||||||
dataContext.IsDataTrack = PlayableDisc.TrackType != TrackType.Audio;
|
dataContext.IsDataTrack = PlayableDisc.TrackType != TrackType.Audio;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,13 @@ namespace RedBookPlayer
|
|||||||
set => this.RaiseAndSetIfChanged(ref _copyAllowed, value);
|
set => this.RaiseAndSetIfChanged(ref _copyAllowed, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _quadChannel;
|
||||||
|
public bool QuadChannel
|
||||||
|
{
|
||||||
|
get => _quadChannel;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _quadChannel, value);
|
||||||
|
}
|
||||||
|
|
||||||
private bool _isAudioTrack;
|
private bool _isAudioTrack;
|
||||||
public bool IsAudioTrack
|
public bool IsAudioTrack
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user