Add option to fix subchannel position on dump.

This commit is contained in:
2020-06-13 17:27:30 +01:00
parent 5786b12130
commit db97549306
4 changed files with 113 additions and 34 deletions

View File

@@ -75,13 +75,80 @@ namespace Aaru.Core.Devices.Dumping
if(supportedSubchannel == MmcSubchannel.Q16)
sub = Subchannel.ConvertQToRaw(sub);
if(desiredSubchannel != MmcSubchannel.None)
if(!_fixSubchannelPosition &&
desiredSubchannel != MmcSubchannel.None)
_outputPlugin.WriteSectorsTag(sub, sectorAddress, length, SectorTagType.CdSectorSubchannel);
subLog?.WriteEntry(sub, supportedSubchannel == MmcSubchannel.Raw, (long)sectorAddress, length);
byte[] deSub = Subchannel.Deinterleave(sub);
bool indexesChanged = CheckIndexesFromSubchannel(deSub, isrcs, currentTrack, ref mcn, tracks);
int prePos = int.MinValue;
// Check subchannel
for(int subPos = 0; subPos < deSub.Length; subPos += 96)
{
byte[] q = new byte[12];
Array.Copy(deSub, subPos + 12, q, 0, 12);
CRC16CCITTContext.Data(q, 10, out byte[] crc);
bool crcOk = crc[0] == q[10] && crc[1] == q[11];
if(!_fixSubchannelPosition ||
desiredSubchannel == MmcSubchannel.None)
continue;
// TODO: Check CRC OK
int aPos = int.MinValue;
byte aframe = (byte)(((q[9] / 16) * 10) + (q[9] & 0x0F));
if((q[0] & 0x3) == 1)
{
byte amin = (byte)(((q[7] / 16) * 10) + (q[7] & 0x0F));
byte asec = (byte)(((q[8] / 16) * 10) + (q[8] & 0x0F));
aPos = ((amin * 60 * 75) + (asec * 75) + aframe) - 150;
}
else
{
ulong expectedSectorAddress = sectorAddress + (ulong)(subPos / 96) + 150;
byte smin = (byte)(expectedSectorAddress / 60 / 75);
expectedSectorAddress -= (ulong)(smin * 60 * 75);
byte ssec = (byte)(expectedSectorAddress / 75);
expectedSectorAddress -= (ulong)(smin * 75);
byte sframe = (byte)(expectedSectorAddress - ((ulong)ssec * 75));
aPos = ((smin * 60 * 75) + (ssec * 75) + aframe) - 150;
// Next second
if(aPos < prePos)
aPos += 75;
}
// TODO: Negative sectors
if(aPos < 0)
continue;
prePos = aPos;
byte[] posSub = new byte[96];
Array.Copy(deSub, subPos, posSub, 0, 96);
posSub = Subchannel.Interleave(posSub);
if(!_fixSubchannelPosition &&
desiredSubchannel != MmcSubchannel.None)
_outputPlugin.WriteSectorTag(posSub, (ulong)aPos, SectorTagType.CdSectorSubchannel);
}
return indexesChanged;
}
bool CheckIndexesFromSubchannel(byte[] deSub, Dictionary<byte, string> isrcs, byte currentTrack, ref string mcn,
Track[] tracks)
{
// Check subchannel
for(int subPos = 0; subPos < deSub.Length; subPos += 96)
{

View File

@@ -69,6 +69,7 @@ namespace Aaru.Core.Devices.Dumping
readonly string _outputPrefix;
readonly bool _persistent;
readonly CICMMetadataType _preSidecar;
readonly bool _private;
readonly ushort _retryPasses;
readonly bool _stopOnError;
readonly DumpSubchannel _subchannel;
@@ -78,8 +79,8 @@ namespace Aaru.Core.Devices.Dumping
Database.Models.Device _dbDev; // Device database entry
bool _dumpFirstTrackPregap;
bool _fixOffset;
readonly bool _fixSubchannelPosition;
uint _maximumReadable; // Maximum number of sectors drive can read at once
readonly bool _private;
Resume _resume;
Sidecar _sidecarClass;
uint _skip;
@@ -112,36 +113,38 @@ namespace Aaru.Core.Devices.Dumping
bool force, bool dumpRaw, bool persistent, bool stopOnError, Resume resume, DumpLog dumpLog,
Encoding encoding, string outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
CICMMetadataType preSidecar, uint skip, bool metadata, bool trim, bool dumpFirstTrackPregap,
bool fixOffset, bool debug, DumpSubchannel subchannel, int speed, bool @private)
bool fixOffset, bool debug, DumpSubchannel subchannel, int speed, bool @private,
bool fixSubchannelPosition)
{
_doResume = doResume;
_dev = dev;
_devicePath = devicePath;
_outputPlugin = outputPlugin;
_retryPasses = retryPasses;
_force = force;
_dumpRaw = dumpRaw;
_persistent = persistent;
_stopOnError = stopOnError;
_resume = resume;
_dumpLog = dumpLog;
_encoding = encoding;
_outputPrefix = outputPrefix;
_outputPath = outputPath;
_formatOptions = formatOptions;
_preSidecar = preSidecar;
_skip = skip;
_metadata = metadata;
_trim = trim;
_dumpFirstTrackPregap = dumpFirstTrackPregap;
_aborted = false;
_fixOffset = fixOffset;
_debug = debug;
_maximumReadable = 64;
_subchannel = subchannel;
_speedMultiplier = -1;
_speed = speed;
_private = @private;
_doResume = doResume;
_dev = dev;
_devicePath = devicePath;
_outputPlugin = outputPlugin;
_retryPasses = retryPasses;
_force = force;
_dumpRaw = dumpRaw;
_persistent = persistent;
_stopOnError = stopOnError;
_resume = resume;
_dumpLog = dumpLog;
_encoding = encoding;
_outputPrefix = outputPrefix;
_outputPath = outputPath;
_formatOptions = formatOptions;
_preSidecar = preSidecar;
_skip = skip;
_metadata = metadata;
_trim = trim;
_dumpFirstTrackPregap = dumpFirstTrackPregap;
_aborted = false;
_fixOffset = fixOffset;
_debug = debug;
_maximumReadable = 64;
_subchannel = subchannel;
_speedMultiplier = -1;
_speed = speed;
_private = @private;
_fixSubchannelPosition = fixSubchannelPosition;
}
/// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary>