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:
Grigory Chudov
2013-05-07 00:13:50 -04:00
parent d54c133024
commit 110f6b19f4
7 changed files with 60 additions and 39 deletions

View File

@@ -408,12 +408,12 @@ namespace CUERipper
cueSheet.CTDB.Submit(
(int)cueSheet.ArVerify.WorstConfidence() + 1,
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.Title,
cueSheet.TOC.Barcode);
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)
if (entry.hasErrors && entry.canRecover)
@@ -421,7 +421,7 @@ namespace CUERipper
}
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() + ".", Properties.Resources.DoneRipping, MessageBoxButtons.OK, MessageBoxIcon.Information);
});

View File

@@ -816,7 +816,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABy
CQAAAk1TRnQBSQFMAgEBBAEAAcQBAgHEAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
CQAAAk1TRnQBSQFMAgEBBAEAAcwBAgHMAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
@@ -966,7 +966,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAY
EgAAAk1TRnQBSQFMAgEBCwEAAcQBAgHEAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
EgAAAk1TRnQBSQFMAgEBCwEAAcwBAgHMAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA

View File

@@ -2239,7 +2239,7 @@ namespace CUETools.Processor
uint sec_end = Math.Min(sec_start + 74, tr_start + len - 1);
bool fError = false;
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;
if (fError)
{
@@ -2250,7 +2250,7 @@ namespace CUETools.Processor
uint jsec_end = Math.Min(jsec_start + 74, tr_start + len - 1);
bool jfError = false;
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;
if (!jfError)
{
@@ -2429,10 +2429,10 @@ namespace CUETools.Processor
if (prefix != "") prefix += ", ";
prefix += "CTDB: " + CTDB.Status;
}
if (_isCD && _ripper.ErrorsCount > 0)
if (_isCD && _ripper.FailedSectors.PopulationCount() > 0)
{
if (prefix != "") prefix += ", ";
prefix += "ripper found " + _ripper.ErrorsCount + " suspicious sectors";
prefix += "ripper found " + _ripper.FailedSectors.PopulationCount() + " suspicious sectors";
}
if (prefix == "")
prefix += "done";

View File

@@ -2,6 +2,7 @@
using System.IO;
using CUETools.AccurateRip;
using CUETools.CDImage;
using CUETools.Ripper;
using System.Globalization;
namespace CUETools.Processor
@@ -85,11 +86,9 @@ namespace CUETools.Processor
private static double GetRangeQuality(CUESheet sheet, uint start, uint length)
{
int errCount = 0;
for (uint iSector = start; iSector < start + length; iSector++)
if (sheet.CDRipper.Errors[(int)iSector - (int)sheet.TOC[sheet.TOC.FirstAudio][0].Start])
errCount++;
return 100 * (1.0 - Math.Log(errCount / 5.0 + 1) / Math.Log(length / 5.0 + 1));
int failedSectorsCount = sheet.CDRipper.FailedSectors.PopulationCount((int)start - (int)sheet.TOC[sheet.TOC.FirstAudio][0].Start, (int)length);
int retrySectorsCount = sheet.CDRipper.RetrySectors.PopulationCount((int)start - (int)sheet.TOC[sheet.TOC.FirstAudio][0].Start, (int)length);
return 100 * (1.0 - Math.Log(failedSectorsCount / 5.0 + retrySectorsCount / 100.0 + 1) / Math.Log(length / 5.0 + length / 100.0 + 1));
}
public static string GetExactAudioCopyLog(CUESheet sheet)

View File

@@ -254,7 +254,7 @@ namespace CUETools.ConsoleRipper
Console.Write("\r \r");
Console.WriteLine("Results : {0:0.00}x; {1:d5} errors; {2:d2}:{3:d2}:{4:d2}",
audioSource.Length / totalElapsed.TotalSeconds / audioSource.PCM.SampleRate,
audioSource.ErrorsCount,
audioSource.FailedSectors.PopulationCount(),
totalElapsed.Hours, totalElapsed.Minutes, totalElapsed.Seconds
);
audioDest.Close();
@@ -267,7 +267,7 @@ namespace CUETools.ConsoleRipper
bool wereErrors = false;
for (int iTrack = 1; iTrack <= audioSource.TOC.AudioTracks; iTrack++)
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)
{

View File

@@ -60,8 +60,7 @@ namespace CUETools.Ripper.SCSI
public long[,,] UserData;
public byte[,] C2Count;
public long[] byte2long;
BitArray _errors;
int _errorsCount;
BitArray m_failedSectors, m_retrySctors;
int _crcErrorsCount = 0;
AudioBuffer currentData = new AudioBuffer(AudioPCMConfig.RedBook, MSECTORS * 588);
short[] _valueScore = new short[256];
@@ -86,19 +85,19 @@ namespace CUETools.Ripper.SCSI
}
}
public BitArray Errors
public BitArray FailedSectors
{
get
{
return _errors;
return m_failedSectors;
}
}
public int ErrorsCount
public BitArray RetrySectors
{
get
{
return _errorsCount;
return m_retrySctors;
}
}
@@ -967,7 +966,7 @@ namespace CUETools.Ripper.SCSI
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++)
{
@@ -1005,11 +1004,8 @@ namespace CUETools.Ripper.SCSI
//_currentErrorsCount += newerr;
_currentErrorsCount += newerr - errtmp[pos];
errtmp[pos] = newerr;
if (markErrors)
{
_errors[sector + iSector] |= fError;
_errorsCount += fError ? 1 : 0;
}
if (markErrors != null)
markErrors[sector + iSector] |= fError;
}
}
@@ -1075,7 +1071,7 @@ namespace CUETools.Ripper.SCSI
//TimeSpan delay1 = DateTime.Now - LastFetch;
//DateTime LastFetched = DateTime.Now;
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;
//if (sector == _currentStart)
//System.Console.WriteLine("\n{0},{1}", delay1.TotalMilliseconds, delay2.TotalMilliseconds);
@@ -1194,10 +1190,10 @@ namespace CUETools.Ripper.SCSI
if (_toc == null || _toc.AudioLength <= 0)
throw new ReadCDException(Resource1.NoAudio);
_crcErrorsCount = 0;
_errorsCount = 0;
_currentStart = -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;
}
}

View File

@@ -21,8 +21,8 @@ namespace CUETools.Ripper
string RipperVersion { get; }
string CurrentReadCommand { get; }
int CorrectionQuality { get; set; }
int ErrorsCount { get; }
BitArray Errors { get; }
BitArray FailedSectors { get; }
BitArray RetrySectors { get; }
event EventHandler<ReadProgressArgs> ReadProgress;
}
@@ -62,4 +62,30 @@ namespace CUETools.Ripper
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() { }
}
}