From 6c2ce26146112cddb19e5ef8ca6d5a91230e2c37 Mon Sep 17 00:00:00 2001 From: chudov Date: Tue, 10 Jan 2012 23:52:26 +0000 Subject: [PATCH] CTDB2.0: ignore pregap --- CUETools.AccurateRip/AccurateRip.cs | 24 +++++------ CUETools.AccurateRip/CDRepair.cs | 42 ++++++++----------- CUETools.CTDB/CUEToolsDB.cs | 19 +++++---- .../CUETools.TestParity/CDRepairDecodeTest.cs | 29 +++++++++++-- 4 files changed, 67 insertions(+), 47 deletions(-) diff --git a/CUETools.AccurateRip/AccurateRip.cs b/CUETools.AccurateRip/AccurateRip.cs index bce758c..02856ab 100644 --- a/CUETools.AccurateRip/AccurateRip.cs +++ b/CUETools.AccurateRip/AccurateRip.cs @@ -406,10 +406,10 @@ namespace CUETools.AccurateRip uint crc; if (iTrack == 0) { - int discLen = (int)_toc.AudioLength * 588; + int discLen = ((int)_toc.AudioLength - (int)TOC.Pregap) * 588; int chunkLen = discLen - prefixSamples - suffixSamples; return 0xffffffff ^ Crc32.Combine( - 0xffffffff ^ _CRC32[0, prefixSamples], + 0xffffffff ^ _CRC32[1, prefixSamples], _CRC32[_toc.AudioTracks, 2 * maxOffset - suffixSamples], chunkLen * 4); } @@ -491,7 +491,8 @@ namespace CUETools.AccurateRip /// public unsafe void CalculateCRCs(uint* t, ushort* wr, ushort* pte, uint* pSampleBuff, int count, int offs) { - int currentStride = ((int)_sampleCount * 2) / stride; + int currentSample = Math.Max(0, (int)_sampleCount - 588 * (int)this.TOC.Pregap); + int currentStride = (currentSample * 2) / stride; bool doPar = currentStride >= 1 && currentStride <= stridecount && calcParity; SyndromeCalc syndromeCalc = doPar ? maxNpar == 8 ? (SyndromeCalc)SyndromeCalc8 : (SyndromeCalc)SyndromeCalc16 : (SyndromeCalc)SyndromeCalcDummy; @@ -603,17 +604,15 @@ namespace CUETools.AccurateRip // Process no more than there is in the buffer, no more than there is in this track, and no more than up to a sector boundary. int copyCount = Math.Min(Math.Min(sampleBuffer.Length - pos, (int)_samplesRemTrack), 588 - (int)_sampleCount % 588); uint* samples = ((uint*)pSampleBuff) + pos; - int currentPart = ((int)_sampleCount * 2) % stride; + int currentSample = (int)_sampleCount - 588 * (int)this.TOC.Pregap; + int currentPart = currentSample < 0 ? 0 : (currentSample * 2) % stride; //ushort* synptr = synptr1 + npar * currentPart; ushort* wr = ((ushort*)bpar) + maxNpar * currentPart; - int currentStride = ((int)_sampleCount * 2) / stride; - for (int i = 0; i < Math.Min(leadin.Length - (int)_sampleCount * 2, copyCount * 2); i++) - leadin[_sampleCount * 2 + i] = ((ushort*)samples)[i]; + for (int i = Math.Max(0, - currentSample * 2); i < Math.Min(leadin.Length - currentSample * 2, copyCount * 2); i++) + leadin[currentSample * 2 + i] = ((ushort*)samples)[i]; for (int i = Math.Max(0, (int)(_finalSampleCount - _sampleCount) * 2 - leadout.Length); i < copyCount * 2; i++) - //if (currentStride >= stridecount && leadout != null) - //for (int i = 0; i < copyCount * 2; i++) { int remaining = (int)(_finalSampleCount - _sampleCount) * 2 - i - 1; leadout[remaining] = ((ushort*)samples)[i]; @@ -672,7 +671,7 @@ namespace CUETools.AccurateRip { for (int i = 0; i < leadin.Length; i++) { - int currentOffset = i / 2; + int currentOffset = i / 2 + 588 * (int)this.TOC.Pregap; if (currentOffset >= start && currentOffset < end) this.leadin[i] = part.leadin[i]; } @@ -745,8 +744,9 @@ namespace CUETools.AccurateRip { var newSyndrome1 = this.GetSyndrome(); var newSyndrome2 = part.GetSyndrome(); - var i1 = Math.Max(0, start * 2 - stride); - var i2 = Math.Min(2 * (int)_finalSampleCount - laststride - stride, end * 2 - stride); + int firstSample = 588 * (int)TOC.Pregap; + var i1 = Math.Max(0, (start - firstSample) * 2 - stride); + var i2 = Math.Min(2 * ((int)_finalSampleCount - firstSample) - laststride - stride, (end - firstSample) * 2 - stride); var diff = i2 / stride - i1 / stride; var i1s = i1 % stride; var i2s = i2 % stride; diff --git a/CUETools.AccurateRip/CDRepair.cs b/CUETools.AccurateRip/CDRepair.cs index 180c67d..1cc8589 100644 --- a/CUETools.AccurateRip/CDRepair.cs +++ b/CUETools.AccurateRip/CDRepair.cs @@ -12,26 +12,28 @@ namespace CUETools.AccurateRip public class CDRepair { protected int sampleCount; + protected int pregap; protected int finalSampleCount; internal Galois galois; internal int stride; internal int laststride; internal int stridecount; - public CDRepair(int finalSampleCount, int stride) - { + public CDRepair(int pregap, int finalSampleCount, int stride) + { this.stride = stride; - this.finalSampleCount = finalSampleCount; - sampleCount = 0; - galois = Galois16.instance; - laststride = stride + (finalSampleCount * 2) % stride; - stridecount = (finalSampleCount * 2) / stride - 2; // minus one for leadin and one for leadout - if ((finalSampleCount * 2 + stride - 1) / stride + AccurateRipVerify.maxNpar > galois.Max) + this.pregap = pregap; + this.finalSampleCount = finalSampleCount; + this.sampleCount = 0; + this.galois = Galois16.instance; + this.laststride = this.stride + ((this.finalSampleCount - this.pregap) * 2) % this.stride; + this.stridecount = ((this.finalSampleCount - this.pregap) * 2) / this.stride - 2; // minus one for leadin and one for leadout + if (((this.finalSampleCount - this.pregap) * 2 + this.stride - 1) / this.stride + AccurateRipVerify.maxNpar > galois.Max) throw new Exception("invalid stride"); } public CDRepair(CDRepair src) - : this(src.finalSampleCount, src.stride) + : this(src.pregap, src.finalSampleCount, src.stride) { } @@ -55,15 +57,7 @@ namespace CUETools.AccurateRip { return stride; } - } - - public int LastStride - { - get - { - return laststride; - } - } + } } public class CDRepairEncode : CDRepair @@ -71,7 +65,7 @@ namespace CUETools.AccurateRip protected AccurateRipVerify ar; public CDRepairEncode(AccurateRipVerify ar, int stride) - : base ((int)ar.FinalSampleCount, stride) + : base ((int)ar.TOC.Pregap * 588, (int)ar.FinalSampleCount, stride) { this.ar = ar; ar.InitCDRepair(stride, laststride, stridecount, true); @@ -216,9 +210,9 @@ namespace CUETools.AccurateRip for (int i = 0; i < errcount; i++) { int pos = galois.toPos(stridecount, _errpos[i]) * stride + part2; - int erroffi = stride + pos - actualOffset * 2; + int erroffi = stride + pos + pregap * 2 - actualOffset * 2; ushort diff = (ushort)this.galois.doForney(errcount, _errpos[i], _sigma, _omega); - if (erroffi < 0 || erroffi >= finalSampleCount * 2) + if (erroffi < pregap * 2 || erroffi >= finalSampleCount * 2) { fix.canRecover = false; return fix; @@ -301,7 +295,7 @@ namespace CUETools.AccurateRip public int GetAffectedSectorsCount(int min, int max) { - min = Math.Max(2 * min, stride - 2 * ActualOffset); + min = Math.Max(2 * min, 2 * pregap + stride - 2 * ActualOffset); max = Math.Min(2 * max, 2 * finalSampleCount - laststride - 2 * ActualOffset); int count = 0; for (int i = 0; i < correctableErrors; i++) @@ -312,7 +306,7 @@ namespace CUETools.AccurateRip public string GetAffectedSectors(int min, int max) { - min = Math.Max(2 * min, stride - 2 * ActualOffset); + min = Math.Max(2 * min, 2 * pregap + stride - 2 * ActualOffset); max = Math.Min(2 * max, 2 * finalSampleCount - laststride - 2 * ActualOffset); StringBuilder sb = new StringBuilder(); for (int i = 0; i < correctableErrors; i++) @@ -340,7 +334,7 @@ namespace CUETools.AccurateRip if ((sampleBuffer.ByteLength & 1) != 0) throw new Exception("never happens"); - int firstPos = Math.Max(0, stride - sampleCount * 2 - ActualOffset * 2); + int firstPos = Math.Max(0, stride + (pregap - sampleCount) * 2 - ActualOffset * 2); int lastPos = Math.Min(sampleBuffer.ByteLength >> 1, (finalSampleCount - sampleCount) * 2 - laststride - ActualOffset * 2); fixed (byte* bytes = sampleBuffer.Bytes) diff --git a/CUETools.CTDB/CUEToolsDB.cs b/CUETools.CTDB/CUEToolsDB.cs index d14545c..62b5d01 100644 --- a/CUETools.CTDB/CUEToolsDB.cs +++ b/CUETools.CTDB/CUEToolsDB.cs @@ -359,7 +359,7 @@ namespace CUETools.CTDB return; foreach (DBEntry entry in entries) { - if (entry.toc.Pregap != toc.Pregap || entry.toc.AudioLength != toc.AudioLength || entry.stride != verify.Stride) + if (entry.toc.AudioLength - entry.toc.Pregap != toc.AudioLength - toc.Pregap || entry.stride != verify.Stride) { entry.hasErrors = true; entry.canRecover = false; @@ -479,11 +479,16 @@ namespace CUETools.CTDB string confFormat = (this.Total < 10) ? "{0:0}/{1:0}" : (this.Total < 100) ? "{0:00}/{1:00}" : "{0:000}/{1:000}"; string conf = string.Format(confFormat, entry.conf, this.Total); - string dataTrackInfo = !entry.toc[entry.toc.TrackCount].IsAudio ? string.Format("CD-Extra data track length {0}", entry.toc[entry.toc.TrackCount].LengthMSF) : - !entry.toc[1].IsAudio ? string.Format("Playstation type data track length {0}", entry.toc[entry.toc.FirstAudio].StartMSF) : "Has no data track"; + string dataTrackInfo = !entry.toc[entry.toc.TrackCount].IsAudio && this.toc[entry.toc.TrackCount].IsAudio ? + string.Format("CD-Extra data track length {0}", entry.toc[entry.toc.TrackCount].LengthMSF) : + !entry.toc[1].IsAudio && this.toc[1].IsAudio ? + string.Format("Playstation type data track length {0}", entry.toc[entry.toc.FirstAudio].StartMSF) : + (entry.toc[1].IsAudio && !this.toc[1].IsAudio) || (entry.toc[entry.toc.TrackCount].IsAudio && !this.toc[entry.toc.TrackCount].IsAudio) ? + "Has no data track" : ""; + if (entry.toc.Pregap != this.toc.Pregap) + dataTrackInfo = dataTrackInfo + (dataTrackInfo == "" ? "" : ", ") + string.Format("Has pregap length {0}", CDImageLayout.TimeToString(entry.toc.Pregap)); string status = - entry.toc.Pregap != this.TOC.Pregap ? string.Format("Has pregap length {0}", CDImageLayout.TimeToString(entry.toc.Pregap)) : - entry.toc.AudioLength != this.TOC.AudioLength ? string.Format("Has audio length {0}", CDImageLayout.TimeToString(entry.toc.AudioLength)) : + entry.toc.AudioLength - entry.toc.Pregap != this.TOC.AudioLength - this.TOC.Pregap ? string.Format("Has audio length {0}", CDImageLayout.TimeToString(entry.toc.AudioLength)) : ((entry.toc.TrackOffsets != this.TOC.TrackOffsets) ? dataTrackInfo + ", " : "") + ((!entry.hasErrors) ? "Accurately ripped" : //((!entry.hasErrors) ? string.Format("Accurately ripped, offset {0}", -entry.offset) : @@ -606,13 +611,13 @@ namespace CUETools.CTDB { DBEntry popular = null; foreach (DBEntry entry in entries) - if (entry.toc.Pregap == toc.Pregap && (!entry.hasErrors || entry.canRecover)) + if (!entry.hasErrors || entry.canRecover) if (popular == null || entry.conf > popular.conf) popular = entry; if (popular != null) res = popular.Status; foreach (DBEntry entry in entries) - if (entry != popular && entry.toc.Pregap == toc.Pregap && (!entry.hasErrors || entry.canRecover)) + if (entry != popular && (!entry.hasErrors || entry.canRecover)) res += ", or " + entry.Status; if (res == null) res = "could not be verified"; diff --git a/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs b/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs index 512bebb..4cb1d65 100644 --- a/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs +++ b/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs @@ -245,7 +245,27 @@ namespace CUETools.TestParity } } - [TestMethod] + /// + ///Verifying rip that has pregap + /// + [TestMethod()] + public void CDRepairDecodeModifiedWithPregapTest() + { + var generator2 = new TestImageGenerator("32 9833", seed, offset, errors); + var decode = generator2.CreateCDRepairEncode(stride); + int actualOffset; + bool hasErrors; + Assert.IsTrue(decode.FindOffset(encode.AR.GetSyndrome(), encode.CRC, out actualOffset, out hasErrors)); + Assert.IsTrue(hasErrors, "doesn't have errors"); + Assert.AreEqual(offset, actualOffset, "wrong offset"); + CDRepairFix fix = decode.VerifyParity(encode.AR.GetSyndrome(), encode.CRC, actualOffset); + Assert.IsTrue(fix.HasErrors, "doesn't have errors"); + Assert.IsTrue(fix.CanRecover, "cannot recover"); + generator2.Write(fix); + Assert.AreEqual(encode.CRC, fix.CRC); + } + + [TestMethod] public void GFMiscTest() { var g16 = Galois16.instance; @@ -288,7 +308,6 @@ namespace CUETools.TestParity ///A test for CRC parralelism /// [TestMethod()] - //[Ignore] public void CDRepairSplitTest() { var seed = 723722; @@ -309,7 +328,8 @@ namespace CUETools.TestParity ///A test for CRC parralelism speed /// [TestMethod()] - public unsafe void CDRepairSplitSpeedTest() + [Ignore] + public unsafe void CDRepairSplitSpeedTest() { var seed = 723722; var split = 20 * 588; @@ -323,7 +343,8 @@ namespace CUETools.TestParity ///A test for Syndrome2Parity speed /// [TestMethod()] - public unsafe void CDRepairSyndrome2ParitySpeedTest() + [Ignore] + public unsafe void CDRepairSyndrome2ParitySpeedTest() { var syndrome = encode.AR.GetSyndrome(); byte[] parityCopy = ParityToSyndrome.Syndrome2Parity(syndrome);