Use subchannel, if available, to set ISRC.

This commit is contained in:
2020-05-05 20:26:18 +01:00
parent 06dfb76728
commit fb947e3d5c
6 changed files with 173 additions and 110 deletions

View File

@@ -31,6 +31,7 @@
// ****************************************************************************/ // ****************************************************************************/
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Extents; using Aaru.CommonTypes.Extents;
@@ -83,7 +84,8 @@ namespace Aaru.Core.Devices.Dumping
ref double minSpeed, out bool newTrim, bool nextData, int offsetBytes, bool read6, bool read10, ref double minSpeed, out bool newTrim, bool nextData, int offsetBytes, bool read6, bool read10,
bool read12, bool read16, bool readcd, int sectorsForOffset, uint subSize, bool read12, bool read16, bool readcd, int sectorsForOffset, uint subSize,
MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration, MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration,
Track[] tracks, SubchannelLog subLog, MmcSubchannel desiredSubchannel) Track[] tracks, SubchannelLog subLog, MmcSubchannel desiredSubchannel,
Dictionary<byte, string> isrcs)
{ {
ulong sectorSpeedStart = 0; // Used to calculate correct speed ulong sectorSpeedStart = 0; // Used to calculate correct speed
DateTime timeSpeedStart = DateTime.UtcNow; // Time of start for speed calculation DateTime timeSpeedStart = DateTime.UtcNow; // Time of start for speed calculation
@@ -385,15 +387,8 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i + r, 1); _outputPlugin.WriteSectorsLong(data, i + r, 1);
if(desiredSubchannel != MmcSubchannel.None) WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i + r, 1, subLog,
{ isrcs, (byte)track.TrackSequence);
if(supportedSubchannel == MmcSubchannel.Q16)
sub = Subchannel.ConvertQToRaw(sub);
_outputPlugin.WriteSectorsTag(sub, i + r, 1, SectorTagType.CdSectorSubchannel);
}
subLog?.WriteEntry(sub, supportedSubchannel == MmcSubchannel.Raw, (long)(i + r), 1);
} }
else else
{ {
@@ -506,15 +501,8 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i, blocksToRead); _outputPlugin.WriteSectorsLong(data, i, blocksToRead);
if(desiredSubchannel != MmcSubchannel.None) WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, blocksToRead, subLog,
{ isrcs, (byte)track.TrackSequence);
if(supportedSubchannel == MmcSubchannel.Q16)
sub = Subchannel.ConvertQToRaw(sub);
_outputPlugin.WriteSectorsTag(sub, i, blocksToRead, SectorTagType.CdSectorSubchannel);
}
subLog?.WriteEntry(sub, supportedSubchannel == MmcSubchannel.Raw, (long)i, blocksToRead);
} }
else else
{ {

View File

@@ -64,55 +64,56 @@ namespace Aaru.Core.Devices.Dumping
/// <summary>Dumps a compact disc</summary> /// <summary>Dumps a compact disc</summary>
void CompactDisc() void CompactDisc()
{ {
ExtentsULong audioExtents; // Extents with audio sectors ExtentsULong audioExtents; // Extents with audio sectors
ulong blocks; // Total number of positive sectors ulong blocks; // Total number of positive sectors
uint blockSize; // Size of the read sector in bytes uint blockSize; // Size of the read sector in bytes
CdOffset cdOffset; // Read offset from database CdOffset cdOffset; // Read offset from database
byte[] cmdBuf; // Data buffer byte[] cmdBuf; // Data buffer
DumpHardwareType currentTry = null; // Current dump hardware try DumpHardwareType currentTry = null; // Current dump hardware try
double currentSpeed = 0; // Current read speed double currentSpeed = 0; // Current read speed
int? discOffset = null; // Disc write offset int? discOffset = null; // Disc write offset
DateTime dumpStart = DateTime.UtcNow; // Time of dump start DateTime dumpStart = DateTime.UtcNow; // Time of dump start
DateTime end; // Time of operation end DateTime end; // Time of operation end
ExtentsULong extents = null; // Extents ExtentsULong extents = null; // Extents
bool hiddenData; // Hidden track is data bool hiddenData; // Hidden track is data
IbgLog ibgLog; // IMGBurn log IbgLog ibgLog; // IMGBurn log
double imageWriteDuration = 0; // Duration of image write double imageWriteDuration = 0; // Duration of image write
long lastSector; // Last sector number long lastSector; // Last sector number
var leadOutExtents = new ExtentsULong(); // Lead-out extents var leadOutExtents = new ExtentsULong(); // Lead-out extents
Dictionary<int, long> leadOutStarts = new Dictionary<int, long>(); // Lead-out starts Dictionary<int, long> leadOutStarts = new Dictionary<int, long>(); // Lead-out starts
double maxSpeed = double.MinValue; // Maximum speed double maxSpeed = double.MinValue; // Maximum speed
MhddLog mhddLog; // MHDD log MhddLog mhddLog; // MHDD log
double minSpeed = double.MaxValue; // Minimum speed double minSpeed = double.MaxValue; // Minimum speed
bool newTrim; // Is trim a new one? bool newTrim; // Is trim a new one?
int offsetBytes = 0; // Read offset int offsetBytes = 0; // Read offset
bool read6 = false; // Device supports READ(6) bool read6 = false; // Device supports READ(6)
bool read10 = false; // Device supports READ(10) bool read10 = false; // Device supports READ(10)
bool read12 = false; // Device supports READ(12) bool read12 = false; // Device supports READ(12)
bool read16 = false; // Device supports READ(16) bool read16 = false; // Device supports READ(16)
bool readcd; // Device supports READ CD bool readcd; // Device supports READ CD
bool ret; // Image writing return status bool ret; // Image writing return status
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
int sectorsForOffset = 0; // Sectors needed to fix offset int sectorsForOffset = 0; // Sectors needed to fix offset
bool sense = true; // Sense indicator bool sense = true; // Sense indicator
int sessions; // Number of sessions in disc int sessions; // Number of sessions in disc
DateTime start; // Start of operation DateTime start; // Start of operation
SubchannelLog subLog = null; // Subchannel log SubchannelLog subLog = null; // Subchannel log
uint subSize; // Subchannel size in bytes uint subSize; // Subchannel size in bytes
TrackSubchannelType subType; // Track subchannel type TrackSubchannelType subType; // Track subchannel type
bool supportsLongSectors = true; // Supports reading EDC and ECC bool supportsLongSectors = true; // Supports reading EDC and ECC
bool supportsPqSubchannel; // Supports reading PQ subchannel bool supportsPqSubchannel; // Supports reading PQ subchannel
bool supportsRwSubchannel; // Supports reading RW subchannel bool supportsRwSubchannel; // Supports reading RW subchannel
byte[] tmpBuf; // Temporary buffer byte[] tmpBuf; // Temporary buffer
FullTOC.CDFullTOC? toc; // Full CD TOC FullTOC.CDFullTOC? toc; // Full CD TOC
double totalDuration = 0; // Total commands duration double totalDuration = 0; // Total commands duration
Dictionary<byte, byte> trackFlags = new Dictionary<byte, byte>(); // Track flags Dictionary<byte, byte> trackFlags = new Dictionary<byte, byte>(); // Track flags
Track[] tracks; // Tracks in disc Track[] tracks; // Tracks in disc
int firstTrackLastSession; // Number of first track in last session int firstTrackLastSession; // Number of first track in last session
bool hiddenTrack; // Disc has a hidden track before track 1 bool hiddenTrack; // Disc has a hidden track before track 1
MmcSubchannel supportedSubchannel; // Drive's maximum supported subchannel MmcSubchannel supportedSubchannel; // Drive's maximum supported subchannel
MmcSubchannel desiredSubchannel; // User requested subchannel MmcSubchannel desiredSubchannel; // User requested subchannel
bool bcdSubchannel = false; // Subchannel positioning is in BCD bool bcdSubchannel = false; // Subchannel positioning is in BCD
Dictionary<byte, string> isrcs = new Dictionary<byte, string>();
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); // Media tags Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); // Media tags
@@ -834,23 +835,18 @@ namespace Aaru.Core.Devices.Dumping
} }
// Set ISRCs // Set ISRCs
// TODO: Use subchannels if(supportedSubchannel == MmcSubchannel.None)
foreach(Track trk in tracks) foreach(Track trk in tracks)
{ {
sense = _dev.ReadIsrc((byte)trk.TrackSequence, out string isrc, out _, out _, _dev.Timeout, out _); sense = _dev.ReadIsrc((byte)trk.TrackSequence, out string isrc, out _, out _, _dev.Timeout, out _);
if(sense || if(sense ||
isrc == null || isrc == null ||
isrc == "000000000000") isrc == "000000000000")
continue; continue;
if(!_outputPlugin.WriteSectorTag(Encoding.ASCII.GetBytes(isrc), trk.TrackStartSector, isrcs[(byte)trk.TrackSequence] = isrc;
SectorTagType.CdTrackIsrc)) }
continue;
UpdateStatus?.Invoke($"Setting ISRC for track {trk.TrackSequence} to {isrc}");
_dumpLog.WriteLine("Setting ISRC for track {0} to {1}", trk.TrackSequence, isrc);
}
if(_resume.NextBlock > 0) if(_resume.NextBlock > 0)
{ {
@@ -1019,13 +1015,13 @@ namespace Aaru.Core.Devices.Dumping
ref imageWriteDuration, lastSector, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed, ref imageWriteDuration, lastSector, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed,
out newTrim, tracks[0].TrackType != TrackType.Audio, offsetBytes, read6, read10, read12, read16, out newTrim, tracks[0].TrackType != TrackType.Audio, offsetBytes, read6, read10, read12, read16,
readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors, ref totalDuration, readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors, ref totalDuration,
tracks, subLog, desiredSubchannel); tracks, subLog, desiredSubchannel, isrcs);
// TODO: Enable when underlying images support lead-outs // TODO: Enable when underlying images support lead-outs
/* /*
DumpCdLeadOuts(blocks, blockSize, ref currentSpeed, currentTry, extents, ibgLog, ref imageWriteDuration, DumpCdLeadOuts(blocks, blockSize, ref currentSpeed, currentTry, extents, ibgLog, ref imageWriteDuration,
leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed, read6, read10, read12, read16, readcd, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed, read6, read10, read12, read16, readcd,
supportedSubchannel, subSize, ref totalDuration, subLog, desiredSubchannel); supportedSubchannel, subSize, ref totalDuration, subLog, desiredSubchannel, isrcs);
*/ */
end = DateTime.UtcNow; end = DateTime.UtcNow;
@@ -1052,10 +1048,10 @@ namespace Aaru.Core.Devices.Dumping
TrimCdUserData(audioExtents, blockSize, currentTry, extents, newTrim, offsetBytes, read6, read10, read12, TrimCdUserData(audioExtents, blockSize, currentTry, extents, newTrim, offsetBytes, read6, read10, read12,
read16, readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors, read16, readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors,
ref totalDuration, subLog, desiredSubchannel); ref totalDuration, subLog, desiredSubchannel, tracks, isrcs);
RetryCdUserData(audioExtents, blockSize, currentTry, extents, offsetBytes, readcd, sectorsForOffset, RetryCdUserData(audioExtents, blockSize, currentTry, extents, offsetBytes, readcd, sectorsForOffset,
subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel); subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel, tracks, isrcs);
// Write media tags to image // Write media tags to image
if(!_aborted) if(!_aborted)
@@ -1102,6 +1098,19 @@ namespace Aaru.Core.Devices.Dumping
if(_preSidecar != null) if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar); _outputPlugin.SetCicmMetadata(_preSidecar);
foreach(KeyValuePair<byte, string> isrc in isrcs)
{
// TODO: Track tags
Track track = tracks.First(t => t.TrackSequence == isrc.Key);
if(!_outputPlugin.WriteSectorTag(Encoding.ASCII.GetBytes(isrc.Value), track.TrackStartSector,
SectorTagType.CdTrackIsrc))
continue;
UpdateStatus?.Invoke($"Setting ISRC for track {isrc.Key} to {isrc.Value}");
_dumpLog.WriteLine("Setting ISRC for track {0} to {1}", isrc.Key, isrc.Value);
}
_dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;

View File

@@ -32,12 +32,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Aaru.CommonTypes.Enums; using System.Linq;
using Aaru.CommonTypes.Extents; using Aaru.CommonTypes.Extents;
using Aaru.CommonTypes.Structs;
using Aaru.CommonTypes.Structs.Devices.SCSI; using Aaru.CommonTypes.Structs.Devices.SCSI;
using Aaru.Console; using Aaru.Console;
using Aaru.Core.Logging; using Aaru.Core.Logging;
using Aaru.Decoders.CD;
using Aaru.Decoders.SCSI; using Aaru.Decoders.SCSI;
using Aaru.Devices; using Aaru.Devices;
using Schemas; using Schemas;
@@ -53,7 +53,7 @@ namespace Aaru.Core.Devices.Dumping
void RetryCdUserData(ExtentsULong audioExtents, uint blockSize, DumpHardwareType currentTry, void RetryCdUserData(ExtentsULong audioExtents, uint blockSize, DumpHardwareType currentTry,
ExtentsULong extents, int offsetBytes, bool readcd, int sectorsForOffset, uint subSize, ExtentsULong extents, int offsetBytes, bool readcd, int sectorsForOffset, uint subSize,
MmcSubchannel supportedSubchannel, ref double totalDuration, SubchannelLog subLog, MmcSubchannel supportedSubchannel, ref double totalDuration, SubchannelLog subLog,
MmcSubchannel desiredSubchannel) MmcSubchannel desiredSubchannel, Track[] tracks, Dictionary<byte, string> isrcs)
{ {
bool sense = true; // Sense indicator bool sense = true; // Sense indicator
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
@@ -207,6 +207,9 @@ namespace Aaru.Core.Devices.Dumping
forward ? "forward" : "reverse", forward ? "forward" : "reverse",
runningPersistent ? "recovering partial data, " : "")); runningPersistent ? "recovering partial data, " : ""));
Track track = tracks.OrderBy(t => t.TrackStartSector).
LastOrDefault(t => badSector >= t.TrackStartSector);
byte sectorsToReRead = 1; byte sectorsToReRead = 1;
uint badSectorToReRead = (uint)badSector; uint badSectorToReRead = (uint)badSector;
@@ -281,15 +284,8 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
_outputPlugin.WriteSectorLong(data, badSector); _outputPlugin.WriteSectorLong(data, badSector);
if(desiredSubchannel != MmcSubchannel.None) WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, isrcs,
{ (byte)track.TrackSequence);
if(supportedSubchannel == MmcSubchannel.Q16)
sub = Subchannel.ConvertQToRaw(sub);
_outputPlugin.WriteSectorTag(sub, badSector, SectorTagType.CdSectorSubchannel);
}
subLog?.WriteEntry(sub, supportedSubchannel == MmcSubchannel.Raw, (long)badSector, 1);
} }
else else
{ {
@@ -364,6 +360,9 @@ namespace Aaru.Core.Devices.Dumping
PulseProgress?.Invoke($"Trying to get partial data for sector {badSector}"); PulseProgress?.Invoke($"Trying to get partial data for sector {badSector}");
Track track = tracks.OrderBy(t => t.TrackStartSector).
LastOrDefault(t => badSector >= t.TrackStartSector);
if(readcd) if(readcd)
{ {
sense = _dev.ReadCd(out cmdBuf, out senseBuf, (uint)badSector, blockSize, 1, sense = _dev.ReadCd(out cmdBuf, out senseBuf, (uint)badSector, blockSize, 1,
@@ -387,15 +386,8 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
_outputPlugin.WriteSectorLong(data, badSector); _outputPlugin.WriteSectorLong(data, badSector);
if(desiredSubchannel != MmcSubchannel.None) WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog,
{ isrcs, (byte)track.TrackSequence);
if(supportedSubchannel == MmcSubchannel.Q16)
sub = Subchannel.ConvertQToRaw(sub);
_outputPlugin.WriteSectorTag(sub, badSector, SectorTagType.CdSectorSubchannel);
}
subLog?.WriteEntry(sub, supportedSubchannel == MmcSubchannel.Raw, (long)badSector, 1);
} }
else else
{ {

View File

@@ -31,6 +31,7 @@
// ****************************************************************************/ // ****************************************************************************/
using System; using System;
using System.Collections.Generic;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Extents; using Aaru.CommonTypes.Extents;
using Aaru.Core.Logging; using Aaru.Core.Logging;
@@ -225,7 +226,7 @@ namespace Aaru.Core.Devices.Dumping
ExtentsULong leadOutExtents, ref double maxSpeed, MhddLog mhddLog, ref double minSpeed, ExtentsULong leadOutExtents, ref double maxSpeed, MhddLog mhddLog, ref double minSpeed,
bool read6, bool read10, bool read12, bool read16, bool readcd, bool read6, bool read10, bool read12, bool read16, bool readcd,
MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration, MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration,
SubchannelLog subLog, MmcSubchannel desiredSubchannel) SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs)
{ {
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
@@ -308,6 +309,9 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i, _maximumReadable); _outputPlugin.WriteSectorsLong(data, i, _maximumReadable);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, _maximumReadable,
subLog, isrcs, 0xAA);
if(desiredSubchannel != MmcSubchannel.None) if(desiredSubchannel != MmcSubchannel.None)
{ {
if(supportedSubchannel == MmcSubchannel.Q16) if(supportedSubchannel == MmcSubchannel.Q16)

View File

@@ -30,7 +30,12 @@
// Copyright © 2011-2020 Natalia Portillo // Copyright © 2011-2020 Natalia Portillo
// ****************************************************************************/ // ****************************************************************************/
using System;
using System.Collections.Generic;
using Aaru.Checksums;
using Aaru.CommonTypes.Enums;
using Aaru.Core.Logging; using Aaru.Core.Logging;
using Aaru.Decoders.CD;
using Aaru.Devices; using Aaru.Devices;
// ReSharper disable JoinDeclarationAndInitializer // ReSharper disable JoinDeclarationAndInitializer
@@ -60,5 +65,60 @@ namespace Aaru.Core.Devices.Dumping
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16,
dev.Timeout, out _); dev.Timeout, out _);
} }
void WriteSubchannelToImage(MmcSubchannel supportedSubchannel, MmcSubchannel desiredSubchannel, byte[] sub,
ulong sectorAddress, uint length, SubchannelLog subLog,
Dictionary<byte, string> isrcs, byte currentTrack)
{
if(supportedSubchannel == MmcSubchannel.Q16)
sub = Subchannel.ConvertQToRaw(sub);
if(desiredSubchannel != MmcSubchannel.None)
_outputPlugin.WriteSectorsTag(sub, sectorAddress, 1, SectorTagType.CdSectorSubchannel);
subLog?.WriteEntry(sub, supportedSubchannel == MmcSubchannel.Raw, (long)sectorAddress, 1);
byte[] deSub = Subchannel.Deinterleave(sub);
// Check subchannel
for(int subPos = 0; subPos < deSub.Length; subPos += 96)
{
// ISRC
if((deSub[subPos + 12] & 0x3) == 3)
{
byte[] q = new byte[12];
Array.Copy(deSub, subPos + 12, q, 0, 12);
string isrc = Subchannel.DecodeIsrc(q);
if(isrc == null ||
isrc == "000000000000")
continue;
if(!isrcs.ContainsKey(currentTrack))
{
_dumpLog?.WriteLine($"Found new ISRC {isrc} for track {currentTrack}.");
UpdateStatus?.Invoke($"Found new ISRC {isrc} for track {currentTrack}.");
}
else if(isrcs[currentTrack] != isrc)
{
CRC16CCITTContext.Data(q, 10, out byte[] crc);
if(crc[0] != q[10] ||
crc[1] != q[11])
{
continue;
}
_dumpLog?.
WriteLine($"ISRC for track {currentTrack} changed from {isrcs[currentTrack]} to {isrc}.");
UpdateStatus?.
Invoke($"ISRC for track {currentTrack} changed from {isrcs[currentTrack]} to {isrc}.");
}
isrcs[currentTrack] = isrc;
}
}
}
} }
} }

View File

@@ -31,8 +31,11 @@
// ****************************************************************************/ // ****************************************************************************/
using System; using System;
using System.Collections.Generic;
using System.Linq;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Extents; using Aaru.CommonTypes.Extents;
using Aaru.CommonTypes.Structs;
using Aaru.Core.Logging; using Aaru.Core.Logging;
using Aaru.Decoders.CD; using Aaru.Decoders.CD;
using Aaru.Devices; using Aaru.Devices;
@@ -50,7 +53,8 @@ namespace Aaru.Core.Devices.Dumping
ExtentsULong extents, bool newTrim, int offsetBytes, bool read6, bool read10, bool read12, ExtentsULong extents, bool newTrim, int offsetBytes, bool read6, bool read10, bool read12,
bool read16, bool readcd, int sectorsForOffset, uint subSize, bool read16, bool readcd, int sectorsForOffset, uint subSize,
MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration, MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration,
SubchannelLog subLog, MmcSubchannel desiredSubchannel) SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks,
Dictionary<byte, string> isrcs)
{ {
DateTime start; DateTime start;
DateTime end; DateTime end;
@@ -110,6 +114,9 @@ namespace Aaru.Core.Devices.Dumping
PulseProgress?.Invoke($"Trimming sector {badSector}"); PulseProgress?.Invoke($"Trimming sector {badSector}");
Track track = tracks.OrderBy(t => t.TrackStartSector).
LastOrDefault(t => badSector >= t.TrackStartSector);
byte sectorsToTrim = 1; byte sectorsToTrim = 1;
uint badSectorToRead = (uint)badSector; uint badSectorToRead = (uint)badSector;
@@ -180,6 +187,9 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
_outputPlugin.WriteSectorLong(data, badSector); _outputPlugin.WriteSectorLong(data, badSector);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, isrcs,
(byte)track.TrackSequence);
if(desiredSubchannel != MmcSubchannel.None) if(desiredSubchannel != MmcSubchannel.None)
{ {
if(supportedSubchannel == MmcSubchannel.Q16) if(supportedSubchannel == MmcSubchannel.Q16)