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

View File

@@ -114,6 +114,7 @@ namespace Aaru.Core.Devices.Dumping
MmcSubchannel desiredSubchannel; // User requested subchannel
bool bcdSubchannel = false; // Subchannel positioning is in BCD
Dictionary<byte, string> isrcs = new Dictionary<byte, string>();
string mcn = null;
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); // Media tags
@@ -822,16 +823,19 @@ namespace Aaru.Core.Devices.Dumping
}
// Set MCN
// TODO: Use subchannels
sense = _dev.ReadMcn(out string mcn, out _, out _, _dev.Timeout, out _);
if(supportedSubchannel == MmcSubchannel.None)
{
sense = _dev.ReadMcn(out mcn, out _, out _, _dev.Timeout, out _);
if(!sense &&
mcn != null &&
mcn != "0000000000000" &&
_outputPlugin.WriteMediaTag(Encoding.ASCII.GetBytes(mcn), MediaTagType.CD_MCN))
mcn != "0000000000000")
{
UpdateStatus?.Invoke($"Setting disc Media Catalogue Number to {mcn}");
_dumpLog.WriteLine("Setting disc Media Catalogue Number to {0}", mcn);
UpdateStatus?.Invoke($"Found Media Catalogue Number: {mcn}");
_dumpLog.WriteLine("Found Media Catalogue Number: {0}", mcn);
}
else
mcn = null;
}
// Set ISRCs
@@ -846,6 +850,9 @@ namespace Aaru.Core.Devices.Dumping
continue;
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)
@@ -1015,13 +1022,13 @@ namespace Aaru.Core.Devices.Dumping
ref imageWriteDuration, lastSector, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed,
out newTrim, tracks[0].TrackType != TrackType.Audio, offsetBytes, read6, read10, read12, read16,
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
/*
DumpCdLeadOuts(blocks, blockSize, ref currentSpeed, currentTry, extents, ibgLog, ref imageWriteDuration,
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;
@@ -1048,10 +1055,11 @@ namespace Aaru.Core.Devices.Dumping
TrimCdUserData(audioExtents, blockSize, currentTry, extents, newTrim, offsetBytes, read6, read10, read12,
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,
subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel, tracks, isrcs);
subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel, tracks, isrcs,
ref mcn);
// Write media tags to image
if(!_aborted)
@@ -1111,6 +1119,13 @@ namespace Aaru.Core.Devices.Dumping
_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.");
UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now;

View File

@@ -53,7 +53,8 @@ namespace Aaru.Core.Devices.Dumping
void RetryCdUserData(ExtentsULong audioExtents, uint blockSize, DumpHardwareType currentTry,
ExtentsULong extents, int offsetBytes, bool readcd, int sectorsForOffset, uint subSize,
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
byte[] cmdBuf = null; // Data buffer
@@ -285,7 +286,7 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorLong(data, badSector);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, isrcs,
(byte)track.TrackSequence);
(byte)track.TrackSequence, ref mcn);
}
else
{
@@ -387,7 +388,7 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorLong(data, badSector);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog,
isrcs, (byte)track.TrackSequence);
isrcs, (byte)track.TrackSequence, ref mcn);
}
else
{

View File

@@ -35,7 +35,6 @@ using System.Collections.Generic;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Extents;
using Aaru.Core.Logging;
using Aaru.Decoders.CD;
using Aaru.Devices;
using Schemas;
@@ -72,7 +71,8 @@ namespace Aaru.Core.Devices.Dumping
ExtentsULong leadOutExtents, ref double maxSpeed, MhddLog mhddLog, ref double minSpeed,
bool read6, bool read10, bool read12, bool read16, bool readcd,
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
const uint sectorSize = 2352; // Full sector size
@@ -154,10 +154,9 @@ namespace Aaru.Core.Devices.Dumping
}
_outputPlugin.WriteSectorsLong(data, i, _maximumReadable);
_outputPlugin.WriteSectorsTag(sub, i, _maximumReadable, SectorTagType.CdSectorSubchannel);
subLog?.WriteEntry(sub, supportedSubchannel == MmcSubchannel.Raw, (long)i,
_maximumReadable);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, _maximumReadable,
subLog, isrcs, 0xAA, ref mcn);
}
else
_outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable);
@@ -226,7 +225,8 @@ namespace Aaru.Core.Devices.Dumping
ExtentsULong leadOutExtents, ref double maxSpeed, MhddLog mhddLog, ref double minSpeed,
bool read6, bool read10, bool read12, bool read16, bool readcd,
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
const uint sectorSize = 2352; // Full sector size
@@ -310,19 +310,7 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i, _maximumReadable);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, _maximumReadable,
subLog, isrcs, 0xAA);
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);
subLog, isrcs, 0xAA, ref mcn);
}
else
_outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable);

View File

@@ -68,7 +68,7 @@ namespace Aaru.Core.Devices.Dumping
void WriteSubchannelToImage(MmcSubchannel supportedSubchannel, MmcSubchannel desiredSubchannel, byte[] sub,
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)
sub = Subchannel.ConvertQToRaw(sub);
@@ -82,12 +82,13 @@ namespace Aaru.Core.Devices.Dumping
// 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);
// ISRC
if((q[0] & 0x3) == 3)
{
string isrc = Subchannel.DecodeIsrc(q);
if(isrc == null ||
@@ -118,6 +119,36 @@ namespace Aaru.Core.Devices.Dumping
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,
MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration,
SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks,
Dictionary<byte, string> isrcs)
Dictionary<byte, string> isrcs, ref string mcn)
{
DateTime start;
DateTime end;
@@ -188,7 +188,7 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorLong(data, badSector);
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, isrcs,
(byte)track.TrackSequence);
(byte)track.TrackSequence, ref mcn);
if(desiredSubchannel != MmcSubchannel.None)
{