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,
|
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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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 _);
|
|
||||||
|
|
||||||
if(!sense &&
|
|
||||||
mcn != null &&
|
|
||||||
mcn != "0000000000000" &&
|
|
||||||
_outputPlugin.WriteMediaTag(Encoding.ASCII.GetBytes(mcn), MediaTagType.CD_MCN))
|
|
||||||
{
|
{
|
||||||
UpdateStatus?.Invoke($"Setting disc Media Catalogue Number to {mcn}");
|
sense = _dev.ReadMcn(out mcn, out _, out _, _dev.Timeout, out _);
|
||||||
_dumpLog.WriteLine("Setting disc Media Catalogue Number to {0}", mcn);
|
|
||||||
|
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
|
// 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;
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -83,11 +83,12 @@ 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)
|
||||||
{
|
{
|
||||||
|
byte[] q = new byte[12];
|
||||||
|
Array.Copy(deSub, subPos + 12, q, 0, 12);
|
||||||
|
|
||||||
// ISRC
|
// 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);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user