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,20 +408,20 @@ 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)
|
||||
canFix = true;
|
||||
}
|
||||
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);
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,21 +85,21 @@ namespace CUETools.Ripper.SCSI
|
||||
}
|
||||
}
|
||||
|
||||
public BitArray Errors
|
||||
public BitArray FailedSectors
|
||||
{
|
||||
get
|
||||
{
|
||||
return _errors;
|
||||
return m_failedSectors;
|
||||
}
|
||||
}
|
||||
|
||||
public int ErrorsCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _errorsCount;
|
||||
}
|
||||
}
|
||||
public BitArray RetrySectors
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_retrySctors;
|
||||
}
|
||||
}
|
||||
|
||||
public int Timeout
|
||||
{
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() { }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user