diff --git a/DiscImageChef.Core/Devices/Dumping/ATA.cs b/DiscImageChef.Core/Devices/Dumping/ATA.cs index e6b07423d..f158abe2c 100644 --- a/DiscImageChef.Core/Devices/Dumping/ATA.cs +++ b/DiscImageChef.Core/Devices/Dumping/ATA.cs @@ -100,7 +100,8 @@ namespace DiscImageChef.Core.Devices.Dumping bool sense; const ushort ATA_PROFILE = 0x0001; const uint TIMEOUT = 5; - + double imageWriteDuration = 0; + dumpLog.WriteLine("Requesting ATA IDENTIFY DEVICE."); sense = dev.AtaIdentify(out byte[] cmdBuf, out _); if(!sense && Identify.Decode(cmdBuf).HasValue) @@ -262,7 +263,9 @@ namespace DiscImageChef.Core.Devices.Dumping { mhddLog.Write(i, duration); ibgLog.Write(i, currentSpeed * 1024); + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(cmdBuf, i, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; extents.Add(i, blocksToRead, true); } else @@ -272,7 +275,9 @@ namespace DiscImageChef.Core.Devices.Dumping mhddLog.Write(i, duration < 500 ? 65535 : duration); ibgLog.Write(i, 0); + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(new byte[blockSize * blocksToRead], i, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i); } @@ -292,6 +297,8 @@ namespace DiscImageChef.Core.Devices.Dumping (end - start).TotalSeconds); dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); + dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.", + (double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration); #region Error handling if(resume.BadBlocks.Count > 0 && !aborted) @@ -381,8 +388,10 @@ namespace DiscImageChef.Core.Devices.Dumping { mhddLog.Write(currentBlock, duration); ibgLog.Write(currentBlock, currentSpeed * 1024); + DateTime writeStart = DateTime.Now; outputPlugin.WriteSector(cmdBuf, (ulong)((cy * heads + hd) * sectors + (sc - 1))); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; extents.Add(currentBlock); dumpLog.WriteLine("Error reading cylinder {0} head {1} sector {2}.", cy, hd, sc); @@ -393,8 +402,10 @@ namespace DiscImageChef.Core.Devices.Dumping mhddLog.Write(currentBlock, duration < 500 ? 65535 : duration); ibgLog.Write(currentBlock, 0); + DateTime writeStart = DateTime.Now; outputPlugin.WriteSector(new byte[blockSize], (ulong)((cy * heads + hd) * sectors + (sc - 1))); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; } double newSpeed = @@ -416,6 +427,8 @@ namespace DiscImageChef.Core.Devices.Dumping (end - start).TotalSeconds); dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); + dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.", + (double)blockSize * (double)(blocks + 1) / 1024 / (imageWriteDuration / 1000)); } foreach(ulong bad in resume.BadBlocks) dumpLog.WriteLine("Sector {0} could not be read.", bad); @@ -423,7 +436,10 @@ namespace DiscImageChef.Core.Devices.Dumping if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar); dumpLog.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file."); + DateTime closeStart = DateTime.Now; outputPlugin.Close(); + DateTime closeEnd = DateTime.Now; + dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); if(aborted) { @@ -578,9 +594,8 @@ namespace DiscImageChef.Core.Devices.Dumping DicConsole.WriteLine(); - DicConsole - .WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming).", - (end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000); + DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", + (end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000, imageWriteDuration, (closeEnd -closeStart).TotalSeconds); DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", (double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); diff --git a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs index b3a2bdfe5..e6eb152fa 100644 --- a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs +++ b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs @@ -660,6 +660,8 @@ namespace DiscImageChef.Core.Devices.Dumping if(resume.NextBlock > 0) dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock); + double imageWriteDuration = 0; + // Start reading start = DateTime.UtcNow; for(int t = 0; t < tracks.Length; t++) @@ -701,6 +703,7 @@ namespace DiscImageChef.Core.Devices.Dumping mhddLog.Write(i, cmdDuration); ibgLog.Write(i, currentSpeed * 1024); extents.Add(i, blocksToRead, true); + DateTime writeStart = DateTime.Now; if(supportedSubchannel != MmcSubchannel.None) { byte[] data = new byte[SECTOR_SIZE * blocksToRead]; @@ -718,6 +721,8 @@ namespace DiscImageChef.Core.Devices.Dumping outputPlugin.WriteSectorsTag(sub, i, blocksToRead, SectorTagType.CdSectorSubchannel); } else outputPlugin.WriteSectorsLong(readBuffer, i, blocksToRead); + + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; } else { @@ -725,6 +730,7 @@ namespace DiscImageChef.Core.Devices.Dumping if(stopOnError) return; // TODO: Return more cleanly // Write empty data + DateTime writeStart = DateTime.Now; if(supportedSubchannel != MmcSubchannel.None) { outputPlugin.WriteSectorsLong(new byte[SECTOR_SIZE * blocksToRead], i, blocksToRead); @@ -732,6 +738,7 @@ namespace DiscImageChef.Core.Devices.Dumping SectorTagType.CdSectorSubchannel); } else outputPlugin.WriteSectorsLong(new byte[blockSize * blocksToRead], i, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b); @@ -759,6 +766,8 @@ namespace DiscImageChef.Core.Devices.Dumping (end - start).TotalSeconds); dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); + dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.", + (double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration); #region Compact Disc Error handling if(resume.BadBlocks.Count > 0 && !aborted) @@ -896,7 +905,10 @@ namespace DiscImageChef.Core.Devices.Dumping if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar); dumpLog.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file."); + DateTime closeStart = DateTime.Now; outputPlugin.Close(); + DateTime closeEnd = DateTime.Now; + dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); if(aborted) { @@ -950,8 +962,8 @@ namespace DiscImageChef.Core.Devices.Dumping DicConsole.WriteLine(); - DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming).", - (end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000); + DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", + (end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000, imageWriteDuration, (closeEnd-closeStart).TotalSeconds); DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", (double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); diff --git a/DiscImageChef.Core/Devices/Dumping/SBC.cs b/DiscImageChef.Core/Devices/Dumping/SBC.cs index 0d2c3f39f..4ed73c895 100644 --- a/DiscImageChef.Core/Devices/Dumping/SBC.cs +++ b/DiscImageChef.Core/Devices/Dumping/SBC.cs @@ -288,7 +288,8 @@ namespace DiscImageChef.Core.Devices.Dumping } start = DateTime.UtcNow; - + double imageWriteDuration = 0; + if(opticalDisc) outputPlugin.SetTracks(new List { @@ -374,7 +375,9 @@ namespace DiscImageChef.Core.Devices.Dumping { mhddLog.Write(i, cmdDuration); ibgLog.Write(i, currentSpeed * 1024); + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(readBuffer, i, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; extents.Add(i, blocksToRead, true); } else @@ -383,7 +386,9 @@ namespace DiscImageChef.Core.Devices.Dumping if(stopOnError) return; // TODO: Return more cleanly // Write empty data + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(new byte[blockSize * blocksToRead], i, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b); @@ -409,6 +414,8 @@ namespace DiscImageChef.Core.Devices.Dumping (end - start).TotalSeconds); dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); + dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.", + (double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration); #region Error handling if(resume.BadBlocks.Count > 0 && !aborted) @@ -654,7 +661,10 @@ namespace DiscImageChef.Core.Devices.Dumping if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar); dumpLog.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file."); + DateTime closeStart = DateTime.Now; outputPlugin.Close(); + DateTime closeEnd = DateTime.Now; + dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); if(aborted) { @@ -872,9 +882,8 @@ namespace DiscImageChef.Core.Devices.Dumping } DicConsole.WriteLine(); - - DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming).", - (end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000); + DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", + (end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000, imageWriteDuration, (closeEnd -closeStart).TotalSeconds); DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", (double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); diff --git a/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs b/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs index 1941d8397..8e26e7c82 100644 --- a/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs +++ b/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs @@ -282,6 +282,8 @@ namespace DiscImageChef.Core.Devices.Dumping if(resume.NextBlock > 0) dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock); start = DateTime.UtcNow; + double imageWriteDuration = 0; + for(ulong i = resume.NextBlock; i < blocks; i += blocksToRead) { if(aborted) @@ -307,7 +309,9 @@ namespace DiscImageChef.Core.Devices.Dumping { mhddLog.Write(i, duration); ibgLog.Write(i, currentSpeed * 1024); + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(cmdBuf, i, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; extents.Add(i, blocksToRead, true); } else @@ -317,7 +321,9 @@ namespace DiscImageChef.Core.Devices.Dumping mhddLog.Write(i, duration < 500 ? 65535 : duration); ibgLog.Write(i, 0); + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(new byte[blockSize * blocksToRead], i, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i); } @@ -337,6 +343,8 @@ namespace DiscImageChef.Core.Devices.Dumping (end - start).TotalSeconds); dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); + dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.", + (double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration); #region Error handling if(resume.BadBlocks.Count > 0 && !aborted) @@ -395,7 +403,10 @@ namespace DiscImageChef.Core.Devices.Dumping if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar); dumpLog.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file."); + DateTime closeStart = DateTime.Now; outputPlugin.Close(); + DateTime closeEnd = DateTime.Now; + dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); if(aborted) { @@ -586,8 +597,8 @@ namespace DiscImageChef.Core.Devices.Dumping DicConsole.WriteLine(); - DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming).", - (end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000); + DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", + (end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000, imageWriteDuration, (closeEnd -closeStart).TotalSeconds); DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", (double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); diff --git a/DiscImageChef.Core/Devices/Dumping/XGD.cs b/DiscImageChef.Core/Devices/Dumping/XGD.cs index 43e1c1907..7c1651d29 100644 --- a/DiscImageChef.Core/Devices/Dumping/XGD.cs +++ b/DiscImageChef.Core/Devices/Dumping/XGD.cs @@ -347,7 +347,8 @@ namespace DiscImageChef.Core.Devices.Dumping } start = DateTime.UtcNow; - + double imageWriteDuration = 0; + double cmdDuration = 0; uint saveBlocksToRead = blocksToRead; DumpHardwareType currentTry = null; @@ -425,7 +426,9 @@ namespace DiscImageChef.Core.Devices.Dumping { mhddLog.Write(i, cmdDuration); ibgLog.Write(i, currentSpeed * 1024); + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(readBuffer, i, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; extents.Add(i, blocksToRead, true); } else @@ -434,7 +437,9 @@ namespace DiscImageChef.Core.Devices.Dumping if(stopOnError) return; // TODO: Return more cleanly // Write empty data + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(new byte[BLOCK_SIZE * blocksToRead], i, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b); @@ -473,7 +478,9 @@ namespace DiscImageChef.Core.Devices.Dumping mhddLog.Write(i, cmdDuration); ibgLog.Write(i, currentSpeed * 1024); // Write empty data + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(new byte[BLOCK_SIZE * blocksToRead], i, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; blocksToRead = saveBlocksToRead; extents.Add(i, blocksToRead, true); currentSector = i + 1; @@ -502,7 +509,9 @@ namespace DiscImageChef.Core.Devices.Dumping mhddLog.Write(middle + currentSector, cmdDuration); ibgLog.Write(middle + currentSector, currentSpeed * 1024); // Write empty data + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(new byte[BLOCK_SIZE * blocksToRead], middle + currentSector, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; extents.Add(currentSector, blocksToRead, true); currentSector += blocksToRead; @@ -556,7 +565,9 @@ namespace DiscImageChef.Core.Devices.Dumping { mhddLog.Write(currentSector, cmdDuration); ibgLog.Write(currentSector, currentSpeed * 1024); + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(readBuffer, currentSector, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; extents.Add(currentSector, blocksToRead, true); } else @@ -565,7 +576,9 @@ namespace DiscImageChef.Core.Devices.Dumping if(stopOnError) return; // TODO: Return more cleanly // Write empty data + DateTime writeStart = DateTime.Now; outputPlugin.WriteSectors(new byte[BLOCK_SIZE * blocksToRead], currentSector, blocksToRead); + imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; // TODO: Handle errors in video partition //errored += blocksToRead; @@ -613,6 +626,8 @@ namespace DiscImageChef.Core.Devices.Dumping (end - start).TotalSeconds); dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", (double)BLOCK_SIZE * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); + dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.", + (double)BLOCK_SIZE * (double)(blocks + 1) / 1024 / imageWriteDuration); #region Error handling if(resume.BadBlocks.Count > 0 && !aborted) @@ -779,7 +794,10 @@ namespace DiscImageChef.Core.Devices.Dumping if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar); dumpLog.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file."); + DateTime closeStart = DateTime.Now; outputPlugin.Close(); + DateTime closeEnd = DateTime.Now; + dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); if(aborted) { @@ -841,6 +859,16 @@ namespace DiscImageChef.Core.Devices.Dumping if(outputPlugin.SupportedMediaTags.Contains(tag.Key)) Mmc.AddMediaTagToSidecar(outputPath, tag, ref sidecar); + DicConsole.WriteLine(); + DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", + (end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000, imageWriteDuration, (closeEnd -closeStart).TotalSeconds); + DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", + (double)BLOCK_SIZE * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); + DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); + DicConsole.WriteLine("Slowest speed burst: {0:F3} MiB/sec.", minSpeed); + DicConsole.WriteLine("{0} sectors could not be read.", resume.BadBlocks.Count); + DicConsole.WriteLine(); + if(!aborted) { DicConsole.WriteLine("Writing metadata sidecar");