Use subchannel, if available, to set MCN.

This commit is contained in:
2020-05-05 21:08:41 +01:00
parent 7220e2c263
commit 9e72a69ba9
6 changed files with 79 additions and 44 deletions

View File

@@ -85,7 +85,7 @@ namespace Aaru.Core.Devices.Dumping
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) Dictionary<byte, string> isrcs, ref string mcn)
{ {
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
@@ -388,7 +388,7 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i + r, 1); _outputPlugin.WriteSectorsLong(data, i + r, 1);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i + r, 1, subLog, WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i + r, 1, subLog,
isrcs, (byte)track.TrackSequence); isrcs, (byte)track.TrackSequence, ref mcn);
} }
else else
{ {
@@ -502,7 +502,7 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i, blocksToRead); _outputPlugin.WriteSectorsLong(data, i, blocksToRead);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, blocksToRead, subLog, WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, blocksToRead, subLog,
isrcs, (byte)track.TrackSequence); isrcs, (byte)track.TrackSequence, ref mcn);
} }
else else
{ {

View File

@@ -114,6 +114,7 @@ namespace Aaru.Core.Devices.Dumping
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<byte, string> isrcs = new Dictionary<byte, string>();
string mcn = null;
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); // Media tags Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); // Media tags
@@ -822,16 +823,19 @@ namespace Aaru.Core.Devices.Dumping
} }
// Set MCN // Set MCN
// TODO: Use subchannels if(supportedSubchannel == MmcSubchannel.None)
sense = _dev.ReadMcn(out string mcn, out _, out _, _dev.Timeout, out _); {
sense = _dev.ReadMcn(out mcn, out _, out _, _dev.Timeout, out _);
if(!sense && if(!sense &&
mcn != null && mcn != null &&
mcn != "0000000000000" && mcn != "0000000000000")
_outputPlugin.WriteMediaTag(Encoding.ASCII.GetBytes(mcn), MediaTagType.CD_MCN))
{ {
UpdateStatus?.Invoke($"Setting disc Media Catalogue Number to {mcn}"); UpdateStatus?.Invoke($"Found Media Catalogue Number: {mcn}");
_dumpLog.WriteLine("Setting disc Media Catalogue Number to {0}", mcn); _dumpLog.WriteLine("Found Media Catalogue Number: {0}", mcn);
}
else
mcn = null;
} }
// Set ISRCs // Set ISRCs
@@ -846,6 +850,9 @@ namespace Aaru.Core.Devices.Dumping
continue; continue;
isrcs[(byte)trk.TrackSequence] = isrc; isrcs[(byte)trk.TrackSequence] = isrc;
UpdateStatus?.Invoke($"Found ISRC for track {trk.TrackSequence}: {mcn}");
_dumpLog.WriteLine($"Found ISRC for track {trk.TrackSequence}: {mcn}");
} }
if(_resume.NextBlock > 0) if(_resume.NextBlock > 0)
@@ -1015,13 +1022,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, isrcs); tracks, subLog, desiredSubchannel, isrcs, ref mcn);
// 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, isrcs); supportedSubchannel, subSize, ref totalDuration, subLog, desiredSubchannel, isrcs, ref mcn);
*/ */
end = DateTime.UtcNow; end = DateTime.UtcNow;
@@ -1048,10 +1055,11 @@ 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, tracks, isrcs); ref totalDuration, subLog, desiredSubchannel, tracks, isrcs, ref mcn);
RetryCdUserData(audioExtents, blockSize, currentTry, extents, offsetBytes, readcd, sectorsForOffset, RetryCdUserData(audioExtents, blockSize, currentTry, extents, offsetBytes, readcd, sectorsForOffset,
subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel, tracks, isrcs); subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel, tracks, isrcs,
ref mcn);
// Write media tags to image // Write media tags to image
if(!_aborted) if(!_aborted)
@@ -1111,6 +1119,13 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Setting ISRC for track {0} to {1}", isrc.Key, isrc.Value); _dumpLog.WriteLine("Setting ISRC for track {0} to {1}", isrc.Key, isrc.Value);
} }
if(mcn != null &&
_outputPlugin.WriteMediaTag(Encoding.ASCII.GetBytes(mcn), MediaTagType.CD_MCN))
{
UpdateStatus?.Invoke($"Setting disc Media Catalogue Number to {mcn}");
_dumpLog.WriteLine("Setting disc Media Catalogue Number to {0}", mcn);
}
_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

@@ -53,7 +53,8 @@ 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, Track[] tracks, Dictionary<byte, string> isrcs) MmcSubchannel desiredSubchannel, Track[] tracks, Dictionary<byte, string> isrcs,
ref string mcn)
{ {
bool sense = true; // Sense indicator bool sense = true; // Sense indicator
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
@@ -285,7 +286,7 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorLong(data, badSector); _outputPlugin.WriteSectorLong(data, badSector);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, isrcs, WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, isrcs,
(byte)track.TrackSequence); (byte)track.TrackSequence, ref mcn);
} }
else else
{ {
@@ -387,7 +388,7 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorLong(data, badSector); _outputPlugin.WriteSectorLong(data, badSector);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog,
isrcs, (byte)track.TrackSequence); isrcs, (byte)track.TrackSequence, ref mcn);
} }
else else
{ {

View File

@@ -35,7 +35,6 @@ 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;
using Aaru.Decoders.CD;
using Aaru.Devices; using Aaru.Devices;
using Schemas; using Schemas;
@@ -72,7 +71,8 @@ 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) SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs,
ref string mcn)
{ {
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
@@ -154,10 +154,9 @@ namespace Aaru.Core.Devices.Dumping
} }
_outputPlugin.WriteSectorsLong(data, i, _maximumReadable); _outputPlugin.WriteSectorsLong(data, i, _maximumReadable);
_outputPlugin.WriteSectorsTag(sub, i, _maximumReadable, SectorTagType.CdSectorSubchannel);
subLog?.WriteEntry(sub, supportedSubchannel == MmcSubchannel.Raw, (long)i, WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, _maximumReadable,
_maximumReadable); subLog, isrcs, 0xAA, ref mcn);
} }
else else
_outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable); _outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable);
@@ -226,7 +225,8 @@ 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, Dictionary<byte, string> isrcs) SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs,
ref string mcn)
{ {
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
@@ -310,19 +310,7 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i, _maximumReadable); _outputPlugin.WriteSectorsLong(data, i, _maximumReadable);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, _maximumReadable, WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, _maximumReadable,
subLog, isrcs, 0xAA); subLog, isrcs, 0xAA, ref mcn);
if(desiredSubchannel != MmcSubchannel.None)
{
if(supportedSubchannel == MmcSubchannel.Q16)
sub = Subchannel.ConvertQToRaw(sub);
_outputPlugin.WriteSectorsTag(sub, i, _maximumReadable,
SectorTagType.CdSectorSubchannel);
}
subLog?.WriteEntry(sub, supportedSubchannel == MmcSubchannel.Raw, (long)i,
_maximumReadable);
} }
else else
_outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable); _outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable);

View File

@@ -68,7 +68,7 @@ namespace Aaru.Core.Devices.Dumping
void WriteSubchannelToImage(MmcSubchannel supportedSubchannel, MmcSubchannel desiredSubchannel, byte[] sub, void WriteSubchannelToImage(MmcSubchannel supportedSubchannel, MmcSubchannel desiredSubchannel, byte[] sub,
ulong sectorAddress, uint length, SubchannelLog subLog, ulong sectorAddress, uint length, SubchannelLog subLog,
Dictionary<byte, string> isrcs, byte currentTrack) Dictionary<byte, string> isrcs, byte currentTrack, ref string mcn)
{ {
if(supportedSubchannel == MmcSubchannel.Q16) if(supportedSubchannel == MmcSubchannel.Q16)
sub = Subchannel.ConvertQToRaw(sub); sub = Subchannel.ConvertQToRaw(sub);
@@ -82,12 +82,13 @@ namespace Aaru.Core.Devices.Dumping
// Check subchannel // Check subchannel
for(int subPos = 0; subPos < deSub.Length; subPos += 96) for(int subPos = 0; subPos < deSub.Length; subPos += 96)
{
// ISRC
if((deSub[subPos + 12] & 0x3) == 3)
{ {
byte[] q = new byte[12]; byte[] q = new byte[12];
Array.Copy(deSub, subPos + 12, q, 0, 12); Array.Copy(deSub, subPos + 12, q, 0, 12);
// ISRC
if((q[0] & 0x3) == 3)
{
string isrc = Subchannel.DecodeIsrc(q); string isrc = Subchannel.DecodeIsrc(q);
if(isrc == null || if(isrc == null ||
@@ -118,6 +119,36 @@ namespace Aaru.Core.Devices.Dumping
isrcs[currentTrack] = isrc; isrcs[currentTrack] = isrc;
} }
else if((q[0] & 0x3) == 2)
{
string newMcn = Subchannel.DecodeMcn(q);
if(newMcn == null ||
newMcn == "0000000000000")
continue;
if(mcn is null)
{
_dumpLog?.WriteLine($"Found new MCN {newMcn}.");
UpdateStatus?.Invoke($"Found new MCN {newMcn}.");
}
else if(mcn != newMcn)
{
CRC16CCITTContext.Data(q, 10, out byte[] crc);
if(crc[0] != q[10] ||
crc[1] != q[11])
{
continue;
}
_dumpLog?.WriteLine($"MCN changed from {mcn} to {newMcn}.");
UpdateStatus?.Invoke($"MCN changed from {mcn} to {newMcn}.");
}
mcn = newMcn;
}
} }
} }
} }

View File

@@ -54,7 +54,7 @@ namespace Aaru.Core.Devices.Dumping
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, Track[] tracks, SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks,
Dictionary<byte, string> isrcs) Dictionary<byte, string> isrcs, ref string mcn)
{ {
DateTime start; DateTime start;
DateTime end; DateTime end;
@@ -188,7 +188,7 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorLong(data, badSector); _outputPlugin.WriteSectorLong(data, badSector);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, isrcs, WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, isrcs,
(byte)track.TrackSequence); (byte)track.TrackSequence, ref mcn);
if(desiredSubchannel != MmcSubchannel.None) if(desiredSubchannel != MmcSubchannel.None)
{ {