mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
CUERipper: More precise measurement of track quality. Quality will now be less
than 100% if retries were made, even if retries were successful.
This commit is contained in:
@@ -408,12 +408,12 @@ namespace CUERipper
|
|||||||
cueSheet.CTDB.Submit(
|
cueSheet.CTDB.Submit(
|
||||||
(int)cueSheet.ArVerify.WorstConfidence() + 1,
|
(int)cueSheet.ArVerify.WorstConfidence() + 1,
|
||||||
audioSource.CorrectionQuality == 0 ? 0 :
|
audioSource.CorrectionQuality == 0 ? 0 :
|
||||||
(int)(100 * (1.0 - Math.Log(audioSource.ErrorsCount + 1) / Math.Log(audioSource.TOC.AudioLength + 1))),
|
(int)(100 * (1.0 - Math.Log(audioSource.FailedSectors.PopulationCount() + 1) / Math.Log(audioSource.TOC.AudioLength + 1))),
|
||||||
cueSheet.Metadata.Artist,
|
cueSheet.Metadata.Artist,
|
||||||
cueSheet.Metadata.Title,
|
cueSheet.Metadata.Title,
|
||||||
cueSheet.TOC.Barcode);
|
cueSheet.TOC.Barcode);
|
||||||
bool canFix = false;
|
bool canFix = false;
|
||||||
if (cueSheet.CTDB.QueryExceptionStatus == WebExceptionStatus.Success && audioSource.ErrorsCount != 0)
|
if (cueSheet.CTDB.QueryExceptionStatus == WebExceptionStatus.Success && audioSource.FailedSectors.PopulationCount() != 0)
|
||||||
{
|
{
|
||||||
foreach (DBEntry entry in cueSheet.CTDB.Entries)
|
foreach (DBEntry entry in cueSheet.CTDB.Entries)
|
||||||
if (entry.hasErrors && entry.canRecover)
|
if (entry.hasErrors && entry.canRecover)
|
||||||
@@ -421,7 +421,7 @@ namespace CUERipper
|
|||||||
}
|
}
|
||||||
this.Invoke((MethodInvoker)delegate()
|
this.Invoke((MethodInvoker)delegate()
|
||||||
{
|
{
|
||||||
DialogResult dlgRes = audioSource.ErrorsCount != 0 ?
|
DialogResult dlgRes = audioSource.FailedSectors.PopulationCount() != 0 ?
|
||||||
MessageBox.Show(this, cueSheet.GenerateAccurateRipStatus() + (canFix ? "\n" + Properties.Resources.DoneRippingRepair : "") + ".", Properties.Resources.DoneRippingErrors, MessageBoxButtons.OK, MessageBoxIcon.Error) :
|
MessageBox.Show(this, cueSheet.GenerateAccurateRipStatus() + (canFix ? "\n" + Properties.Resources.DoneRippingRepair : "") + ".", Properties.Resources.DoneRippingErrors, MessageBoxButtons.OK, MessageBoxIcon.Error) :
|
||||||
MessageBox.Show(this, cueSheet.GenerateAccurateRipStatus() + ".", Properties.Resources.DoneRipping, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
MessageBox.Show(this, cueSheet.GenerateAccurateRipStatus() + ".", Properties.Resources.DoneRipping, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -816,7 +816,7 @@
|
|||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
|
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
|
||||||
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
|
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
|
||||||
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABy
|
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABy
|
||||||
CQAAAk1TRnQBSQFMAgEBBAEAAcQBAgHEAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
|
CQAAAk1TRnQBSQFMAgEBBAEAAcwBAgHMAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
|
||||||
AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
|
AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
|
||||||
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
|
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
|
||||||
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
|
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
|
||||||
@@ -966,7 +966,7 @@
|
|||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
|
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
|
||||||
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
|
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
|
||||||
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAY
|
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAY
|
||||||
EgAAAk1TRnQBSQFMAgEBCwEAAcQBAgHEAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
|
EgAAAk1TRnQBSQFMAgEBCwEAAcwBAgHMAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
|
||||||
AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
|
AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
|
||||||
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
|
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
|
||||||
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
|
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
|
||||||
|
|||||||
@@ -2239,7 +2239,7 @@ namespace CUETools.Processor
|
|||||||
uint sec_end = Math.Min(sec_start + 74, tr_start + len - 1);
|
uint sec_end = Math.Min(sec_start + 74, tr_start + len - 1);
|
||||||
bool fError = false;
|
bool fError = false;
|
||||||
for (uint iSector = sec_start; iSector <= sec_end; iSector++)
|
for (uint iSector = sec_start; iSector <= sec_end; iSector++)
|
||||||
if (_ripper.Errors[(int)iSector - (int)_toc[_toc.FirstAudio][0].Start])
|
if (_ripper.FailedSectors[(int)iSector - (int)_toc[_toc.FirstAudio][0].Start])
|
||||||
fError = true;
|
fError = true;
|
||||||
if (fError)
|
if (fError)
|
||||||
{
|
{
|
||||||
@@ -2250,7 +2250,7 @@ namespace CUETools.Processor
|
|||||||
uint jsec_end = Math.Min(jsec_start + 74, tr_start + len - 1);
|
uint jsec_end = Math.Min(jsec_start + 74, tr_start + len - 1);
|
||||||
bool jfError = false;
|
bool jfError = false;
|
||||||
for (uint jSector = jsec_start; jSector <= jsec_end; jSector++)
|
for (uint jSector = jsec_start; jSector <= jsec_end; jSector++)
|
||||||
if (_ripper.Errors[(int)jSector - (int)_toc[_toc.FirstAudio][0].Start])
|
if (_ripper.FailedSectors[(int)jSector - (int)_toc[_toc.FirstAudio][0].Start])
|
||||||
jfError = true;
|
jfError = true;
|
||||||
if (!jfError)
|
if (!jfError)
|
||||||
{
|
{
|
||||||
@@ -2429,10 +2429,10 @@ namespace CUETools.Processor
|
|||||||
if (prefix != "") prefix += ", ";
|
if (prefix != "") prefix += ", ";
|
||||||
prefix += "CTDB: " + CTDB.Status;
|
prefix += "CTDB: " + CTDB.Status;
|
||||||
}
|
}
|
||||||
if (_isCD && _ripper.ErrorsCount > 0)
|
if (_isCD && _ripper.FailedSectors.PopulationCount() > 0)
|
||||||
{
|
{
|
||||||
if (prefix != "") prefix += ", ";
|
if (prefix != "") prefix += ", ";
|
||||||
prefix += "ripper found " + _ripper.ErrorsCount + " suspicious sectors";
|
prefix += "ripper found " + _ripper.FailedSectors.PopulationCount() + " suspicious sectors";
|
||||||
}
|
}
|
||||||
if (prefix == "")
|
if (prefix == "")
|
||||||
prefix += "done";
|
prefix += "done";
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using CUETools.AccurateRip;
|
using CUETools.AccurateRip;
|
||||||
using CUETools.CDImage;
|
using CUETools.CDImage;
|
||||||
|
using CUETools.Ripper;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
namespace CUETools.Processor
|
namespace CUETools.Processor
|
||||||
@@ -85,11 +86,9 @@ namespace CUETools.Processor
|
|||||||
|
|
||||||
private static double GetRangeQuality(CUESheet sheet, uint start, uint length)
|
private static double GetRangeQuality(CUESheet sheet, uint start, uint length)
|
||||||
{
|
{
|
||||||
int errCount = 0;
|
int failedSectorsCount = sheet.CDRipper.FailedSectors.PopulationCount((int)start - (int)sheet.TOC[sheet.TOC.FirstAudio][0].Start, (int)length);
|
||||||
for (uint iSector = start; iSector < start + length; iSector++)
|
int retrySectorsCount = sheet.CDRipper.RetrySectors.PopulationCount((int)start - (int)sheet.TOC[sheet.TOC.FirstAudio][0].Start, (int)length);
|
||||||
if (sheet.CDRipper.Errors[(int)iSector - (int)sheet.TOC[sheet.TOC.FirstAudio][0].Start])
|
return 100 * (1.0 - Math.Log(failedSectorsCount / 5.0 + retrySectorsCount / 100.0 + 1) / Math.Log(length / 5.0 + length / 100.0 + 1));
|
||||||
errCount++;
|
|
||||||
return 100 * (1.0 - Math.Log(errCount / 5.0 + 1) / Math.Log(length / 5.0 + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetExactAudioCopyLog(CUESheet sheet)
|
public static string GetExactAudioCopyLog(CUESheet sheet)
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ namespace CUETools.ConsoleRipper
|
|||||||
Console.Write("\r \r");
|
Console.Write("\r \r");
|
||||||
Console.WriteLine("Results : {0:0.00}x; {1:d5} errors; {2:d2}:{3:d2}:{4:d2}",
|
Console.WriteLine("Results : {0:0.00}x; {1:d5} errors; {2:d2}:{3:d2}:{4:d2}",
|
||||||
audioSource.Length / totalElapsed.TotalSeconds / audioSource.PCM.SampleRate,
|
audioSource.Length / totalElapsed.TotalSeconds / audioSource.PCM.SampleRate,
|
||||||
audioSource.ErrorsCount,
|
audioSource.FailedSectors.PopulationCount(),
|
||||||
totalElapsed.Hours, totalElapsed.Minutes, totalElapsed.Seconds
|
totalElapsed.Hours, totalElapsed.Minutes, totalElapsed.Seconds
|
||||||
);
|
);
|
||||||
audioDest.Close();
|
audioDest.Close();
|
||||||
@@ -267,7 +267,7 @@ namespace CUETools.ConsoleRipper
|
|||||||
bool wereErrors = false;
|
bool wereErrors = false;
|
||||||
for (int iTrack = 1; iTrack <= audioSource.TOC.AudioTracks; iTrack++)
|
for (int iTrack = 1; iTrack <= audioSource.TOC.AudioTracks; iTrack++)
|
||||||
for (uint iSector = audioSource.TOC[iTrack].Start; iSector <= audioSource.TOC[iTrack].End; iSector ++)
|
for (uint iSector = audioSource.TOC[iTrack].Start; iSector <= audioSource.TOC[iTrack].End; iSector ++)
|
||||||
if (audioSource.Errors[(int)iSector])
|
if (audioSource.FailedSectors[(int)iSector])
|
||||||
{
|
{
|
||||||
if (!wereErrors)
|
if (!wereErrors)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,8 +60,7 @@ namespace CUETools.Ripper.SCSI
|
|||||||
public long[,,] UserData;
|
public long[,,] UserData;
|
||||||
public byte[,] C2Count;
|
public byte[,] C2Count;
|
||||||
public long[] byte2long;
|
public long[] byte2long;
|
||||||
BitArray _errors;
|
BitArray m_failedSectors, m_retrySctors;
|
||||||
int _errorsCount;
|
|
||||||
int _crcErrorsCount = 0;
|
int _crcErrorsCount = 0;
|
||||||
AudioBuffer currentData = new AudioBuffer(AudioPCMConfig.RedBook, MSECTORS * 588);
|
AudioBuffer currentData = new AudioBuffer(AudioPCMConfig.RedBook, MSECTORS * 588);
|
||||||
short[] _valueScore = new short[256];
|
short[] _valueScore = new short[256];
|
||||||
@@ -86,19 +85,19 @@ namespace CUETools.Ripper.SCSI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BitArray Errors
|
public BitArray FailedSectors
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _errors;
|
return m_failedSectors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ErrorsCount
|
public BitArray RetrySectors
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _errorsCount;
|
return m_retrySctors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,7 +966,7 @@ namespace CUETools.Ripper.SCSI
|
|||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void CorrectSectors(int pass, int sector, int Sectors2Read, bool markErrors)
|
private unsafe void CorrectSectors(int pass, int sector, int Sectors2Read, BitArray markErrors)
|
||||||
{
|
{
|
||||||
for (int iSector = 0; iSector < Sectors2Read; iSector++)
|
for (int iSector = 0; iSector < Sectors2Read; iSector++)
|
||||||
{
|
{
|
||||||
@@ -1005,11 +1004,8 @@ namespace CUETools.Ripper.SCSI
|
|||||||
//_currentErrorsCount += newerr;
|
//_currentErrorsCount += newerr;
|
||||||
_currentErrorsCount += newerr - errtmp[pos];
|
_currentErrorsCount += newerr - errtmp[pos];
|
||||||
errtmp[pos] = newerr;
|
errtmp[pos] = newerr;
|
||||||
if (markErrors)
|
if (markErrors != null)
|
||||||
{
|
markErrors[sector + iSector] |= fError;
|
||||||
_errors[sector + iSector] |= fError;
|
|
||||||
_errorsCount += fError ? 1 : 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1075,7 +1071,7 @@ namespace CUETools.Ripper.SCSI
|
|||||||
//TimeSpan delay1 = DateTime.Now - LastFetch;
|
//TimeSpan delay1 = DateTime.Now - LastFetch;
|
||||||
//DateTime LastFetched = DateTime.Now;
|
//DateTime LastFetched = DateTime.Now;
|
||||||
if (pass >= _correctionQuality)
|
if (pass >= _correctionQuality)
|
||||||
CorrectSectors(pass, sector, Sectors2Read, pass == max_scans - 1);
|
CorrectSectors(pass, sector, Sectors2Read, pass == max_scans - 1 ? m_failedSectors : pass == _correctionQuality ? m_retrySctors : null);
|
||||||
//TimeSpan delay2 = DateTime.Now - LastFetched;
|
//TimeSpan delay2 = DateTime.Now - LastFetched;
|
||||||
//if (sector == _currentStart)
|
//if (sector == _currentStart)
|
||||||
//System.Console.WriteLine("\n{0},{1}", delay1.TotalMilliseconds, delay2.TotalMilliseconds);
|
//System.Console.WriteLine("\n{0},{1}", delay1.TotalMilliseconds, delay2.TotalMilliseconds);
|
||||||
@@ -1194,10 +1190,10 @@ namespace CUETools.Ripper.SCSI
|
|||||||
if (_toc == null || _toc.AudioLength <= 0)
|
if (_toc == null || _toc.AudioLength <= 0)
|
||||||
throw new ReadCDException(Resource1.NoAudio);
|
throw new ReadCDException(Resource1.NoAudio);
|
||||||
_crcErrorsCount = 0;
|
_crcErrorsCount = 0;
|
||||||
_errorsCount = 0;
|
|
||||||
_currentStart = -1;
|
_currentStart = -1;
|
||||||
_currentEnd = -1;
|
_currentEnd = -1;
|
||||||
_errors = new BitArray((int)_toc.AudioLength); // !!!
|
m_failedSectors = new BitArray((int)_toc.AudioLength); // !!!
|
||||||
|
m_retrySctors = new BitArray((int)_toc.AudioLength);
|
||||||
_sampleOffset = (int)value + _driveOffset;
|
_sampleOffset = (int)value + _driveOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ namespace CUETools.Ripper
|
|||||||
string RipperVersion { get; }
|
string RipperVersion { get; }
|
||||||
string CurrentReadCommand { get; }
|
string CurrentReadCommand { get; }
|
||||||
int CorrectionQuality { get; set; }
|
int CorrectionQuality { get; set; }
|
||||||
int ErrorsCount { get; }
|
BitArray FailedSectors { get; }
|
||||||
BitArray Errors { get; }
|
BitArray RetrySectors { get; }
|
||||||
|
|
||||||
event EventHandler<ReadProgressArgs> ReadProgress;
|
event EventHandler<ReadProgressArgs> ReadProgress;
|
||||||
}
|
}
|
||||||
@@ -62,4 +62,30 @@ namespace CUETools.Ripper
|
|||||||
PassTime = passTime;
|
PassTime = passTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class BitArrayUtils
|
||||||
|
{
|
||||||
|
public static int PopulationCount(this BitArray bits, int start, int len)
|
||||||
|
{
|
||||||
|
int cnt = 0;
|
||||||
|
for (int i = start; i < start + len; i++)
|
||||||
|
if (bits[i])
|
||||||
|
cnt++;
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int PopulationCount(this BitArray bits)
|
||||||
|
{
|
||||||
|
return bits.PopulationCount(0, bits.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace System.Runtime.CompilerServices
|
||||||
|
{
|
||||||
|
[AttributeUsageAttribute(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||||
|
internal sealed class ExtensionAttribute : Attribute
|
||||||
|
{
|
||||||
|
public ExtensionAttribute() { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user