public static void MyClassInitialize(TestContext testContext) { toc = new CDImageLayout(1, 1, 1, string.Format("0 {0}", (finalSampleCount / 588).ToString())); ar = new AccurateRipVerify(toc, null); ar2 = new AccurateRipVerify(toc, null); ar3 = new AccurateRipVerify(toc, null); new Random(2423).NextBytes(wav); new Random(2423).NextBytes(wav2); Random rnd = new Random(987); for (int i = 0; i < stride / 4; i++ ) wav2[(int)(rnd.NextDouble() * (wav2.Length - 1))] = (byte)(rnd.NextDouble() * 255); AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); CDRepairEncode encode = new CDRepairEncode(ar, stride, npar, false, true); buff.Prepare(wav, finalSampleCount); ar.Init(toc); ar.Write(buff); ar.Close(); parity = encode.Parity; crc = encode.CRC; decode = new CDRepairEncode(ar2, stride, npar, true, false); buff.Prepare(wav2, finalSampleCount); ar2.Init(toc); ar2.Write(buff); ar2.Close(); int actualOffset; bool hasErrors; decode.FindOffset(npar, parity, 0, crc, out actualOffset, out hasErrors); fix = decode.VerifyParity(parity, actualOffset); decode2 = new CDRepairEncode(ar3, stride, npar, true, false); ar3.Init(toc); buff.Prepare(new byte[offset * 4], offset); ar3.Write(buff); buff.Prepare(wav2, finalSampleCount - offset); ar3.Write(buff); ar3.Close(); decode2.FindOffset(npar, parity, 0, crc, out actualOffset, out hasErrors); fix2 = decode2.VerifyParity(parity, actualOffset); }
public unsafe CDRepairFix VerifyParity(ushort[,] syn2, uint crc, int actualOffset) { int npar2 = syn2.GetLength(1); int npar = Math.Min(AccurateRipVerify.maxNpar, npar2); var erroff = new int[stride * npar / 2]; var forney = new ushort[stride * npar / 2]; var syn1 = ar.GetSyndrome(npar, -1, -actualOffset); var rs = new RsDecode16(npar, this.galois); CDRepairFix fix = new CDRepairFix(this, npar); fix.actualOffset = actualOffset; fix.correctableErrors = 0; fix.hasErrors = false; fix.canRecover = true; fixed (ushort *psyn2 = syn2, psyn1 = syn1) { int sfLen = npar / 2 + 2; int ofLen = npar / 2 + 1; int efLen = npar / 2; int* _sigma = stackalloc int[npar / 2 + 2]; int* _omega = stackalloc int[npar / 2 + 1]; int* _errpos = stackalloc int[npar / 2]; int* syn = stackalloc int[npar]; int offset = fix.actualOffset; for (int part2 = 0; part2 < stride; part2++) { ushort* syn1part = psyn1 + part2 * npar; ushort* syn2part = psyn2 + part2 * npar; int err = 0; for (int i = 0; i < npar; i++) { var synI = syn1part[i] ^ syn2part[i]; syn[i] = synI; err |= synI; } if (err != 0) { int errcount = rs.calcSigmaMBM(_sigma, syn); fix.hasErrors = true; if (errcount <= 0 || errcount > efLen || !rs.chienSearch(_errpos, stridecount, errcount, _sigma)) { fix.canRecover = false; return fix; } galois.mulPoly(_omega, _sigma, syn, ofLen, sfLen, npar); for (int i = 0; i < errcount; i++) { int pos = galois.toPos(stridecount, _errpos[i]) * stride + part2; int erroffi = stride + pos + pregap * 2 - actualOffset * 2; ushort diff = (ushort)this.galois.doForney(errcount, _errpos[i], _sigma, _omega); if (erroffi < pregap * 2 || erroffi >= finalSampleCount * 2) { fix.canRecover = false; return fix; } crc ^= Crc32.Combine(Crc32.ComputeChecksum(Crc32.ComputeChecksum(0, (byte)diff), (byte)(diff >> 8)), 0, (stridecount * stride - pos - 1) * 2); erroff[fix.correctableErrors] = erroffi; forney[fix.correctableErrors] = diff; fix.correctableErrors++; } } } crc ^= ar.CTDBCRC(-actualOffset); if (crc != 0) { fix.canRecover = false; return fix; } } fix.erroffsorted = new int[fix.correctableErrors]; fix.forneysorted = new ushort[fix.correctableErrors]; for (int i = 0; i < fix.correctableErrors; i++) { fix.erroffsorted[i] = erroff[i]; fix.forneysorted[i] = forney[i]; } Array.Sort<int, ushort>(fix.erroffsorted, fix.forneysorted, 0, fix.correctableErrors); return fix; }
public unsafe CDRepairFix VerifyParity(ushort[,] syn2, uint crc, int actualOffset) { int npar2 = syn2.GetLength(1); int npar = Math.Min(AccurateRipVerify.maxNpar, npar2); var erroff = new int[stride * npar / 2]; var forney = new ushort[stride * npar / 2]; var syn1 = ar.GetSyndrome(npar, -1, -actualOffset); var rs = new RsDecode16(npar, this.galois); CDRepairFix fix = new CDRepairFix(this, npar); fix.actualOffset = actualOffset; fix.correctableErrors = 0; fix.hasErrors = false; fix.canRecover = true; fixed(ushort *psyn2 = syn2, psyn1 = syn1) { int sfLen = npar / 2 + 2; int ofLen = npar / 2 + 1; int efLen = npar / 2; int *_sigma = stackalloc int[npar / 2 + 2]; int *_omega = stackalloc int[npar / 2 + 1]; int *_errpos = stackalloc int[npar / 2]; int *syn = stackalloc int[npar]; int offset = fix.actualOffset; for (int part2 = 0; part2 < stride; part2++) { ushort *syn1part = psyn1 + part2 * npar; ushort *syn2part = psyn2 + part2 * npar; int err = 0; for (int i = 0; i < npar; i++) { var synI = syn1part[i] ^ syn2part[i]; syn[i] = synI; err |= synI; } if (err != 0) { int errcount = rs.calcSigmaMBM(_sigma, syn); fix.hasErrors = true; if (errcount <= 0 || errcount > efLen || !rs.chienSearch(_errpos, stridecount, errcount, _sigma)) { fix.canRecover = false; return(fix); } galois.mulPoly(_omega, _sigma, syn, ofLen, sfLen, npar); for (int i = 0; i < errcount; i++) { int pos = galois.toPos(stridecount, _errpos[i]) * stride + part2; int erroffi = stride + pos + pregap * 2 - actualOffset * 2; ushort diff = (ushort)this.galois.doForney(errcount, _errpos[i], _sigma, _omega); if (erroffi < pregap * 2 || erroffi >= finalSampleCount * 2) { fix.canRecover = false; return(fix); } crc ^= Crc32.Combine(Crc32.ComputeChecksum(Crc32.ComputeChecksum(0, (byte)diff), (byte)(diff >> 8)), 0, (stridecount * stride - pos - 1) * 2); erroff[fix.correctableErrors] = erroffi; forney[fix.correctableErrors] = diff; fix.correctableErrors++; } } } crc ^= ar.CTDBCRC(-actualOffset); if (crc != 0) { fix.canRecover = false; return(fix); } } fix.erroffsorted = new int[fix.correctableErrors]; fix.forneysorted = new ushort[fix.correctableErrors]; for (int i = 0; i < fix.correctableErrors; i++) { fix.erroffsorted[i] = erroff[i]; fix.forneysorted[i] = forney[i]; } Array.Sort <int, ushort>(fix.erroffsorted, fix.forneysorted, 0, fix.correctableErrors); return(fix); }