mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Use subchannel, if available, to set MCN.
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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(!sense &&
|
||||
mcn != null &&
|
||||
mcn != "0000000000000" &&
|
||||
_outputPlugin.WriteMediaTag(Encoding.ASCII.GetBytes(mcn), MediaTagType.CD_MCN))
|
||||
if(supportedSubchannel == MmcSubchannel.None)
|
||||
{
|
||||
UpdateStatus?.Invoke($"Setting disc Media Catalogue Number to {mcn}");
|
||||
_dumpLog.WriteLine("Setting disc Media Catalogue Number to {0}", mcn);
|
||||
sense = _dev.ReadMcn(out mcn, out _, out _, _dev.Timeout, out _);
|
||||
|
||||
if(!sense &&
|
||||
mcn != null &&
|
||||
mcn != "0000000000000")
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -83,11 +83,12 @@ namespace Aaru.Core.Devices.Dumping
|
||||
// Check subchannel
|
||||
for(int subPos = 0; subPos < deSub.Length; subPos += 96)
|
||||
{
|
||||
byte[] q = new byte[12];
|
||||
Array.Copy(deSub, subPos + 12, q, 0, 12);
|
||||
|
||||
// ISRC
|
||||
if((deSub[subPos + 12] & 0x3) == 3)
|
||||
if((q[0] & 0x3) == 3)
|
||||
{
|
||||
byte[] q = new byte[12];
|
||||
Array.Copy(deSub, subPos + 12, q, 0, 12);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user