示例#1
0
		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);
		}
示例#2
0
        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;
		}
示例#3
0
        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);
        }