mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
Preparing for next version of CTDB
This commit is contained in:
@@ -5,154 +5,17 @@ using System.IO;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Xml.Serialization;
|
|
||||||
using CUETools.Parity;
|
using CUETools.Parity;
|
||||||
using CUETools.CDImage;
|
using CUETools.CDImage;
|
||||||
using CUETools.Codecs;
|
using CUETools.Codecs;
|
||||||
|
|
||||||
namespace CUETools.AccurateRip
|
namespace CUETools.AccurateRip
|
||||||
{
|
{
|
||||||
[Serializable]
|
|
||||||
public class OffsetSafeCRCRecord
|
|
||||||
{
|
|
||||||
private uint[] val;
|
|
||||||
|
|
||||||
public OffsetSafeCRCRecord()
|
|
||||||
{
|
|
||||||
this.val = new uint[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
public OffsetSafeCRCRecord(AccurateRipVerify ar)
|
|
||||||
: this(new uint[64 + 64])
|
|
||||||
{
|
|
||||||
int offset = 64 * 64;
|
|
||||||
for (int i = 0; i < 64; i++)
|
|
||||||
this.val[i] = ar.CTDBCRC(0, (i + 1) * 64, offset, 2 * offset);
|
|
||||||
for (int i = 0; i < 64; i++)
|
|
||||||
this.val[i + 64] = ar.CTDBCRC(0, 63 - i, offset, 2 * offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OffsetSafeCRCRecord(uint[] val)
|
|
||||||
{
|
|
||||||
this.val = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
[XmlIgnore]
|
|
||||||
public uint[] Value
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe string Base64
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
byte[] res = new byte[val.Length * 4];
|
|
||||||
fixed (byte* pres = &res[0])
|
|
||||||
fixed (uint* psrc = &val[0])
|
|
||||||
AudioSamples.MemCpy(pres, (byte*)psrc, res.Length);
|
|
||||||
var b64 = new char[res.Length * 2 + 4];
|
|
||||||
int b64len = Convert.ToBase64CharArray(res, 0, res.Length, b64, 0);
|
|
||||||
StringBuilder sb = new StringBuilder(b64len + b64len / 4 + 1);
|
|
||||||
for (int i = 0; i < b64len; i += 64)
|
|
||||||
{
|
|
||||||
sb.Append(b64, i, Math.Min(64, b64len - i));
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == null)
|
|
||||||
throw new ArgumentNullException();
|
|
||||||
byte[] bytes = Convert.FromBase64String(value);
|
|
||||||
if (bytes.Length % 4 != 0)
|
|
||||||
throw new InvalidDataException();
|
|
||||||
val = new uint[bytes.Length / 4];
|
|
||||||
fixed (byte* pb = &bytes[0])
|
|
||||||
fixed (uint* pv = &val[0])
|
|
||||||
AudioSamples.MemCpy((byte*)pv, pb, bytes.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
return obj is OffsetSafeCRCRecord && this == (OffsetSafeCRCRecord)obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return (int)val[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator ==(OffsetSafeCRCRecord x, OffsetSafeCRCRecord y)
|
|
||||||
{
|
|
||||||
if (x as object == null || y as object == null) return x as object == null && y as object == null;
|
|
||||||
if (x.Value.Length != y.Value.Length) return false;
|
|
||||||
for (int i = 0; i < x.Value.Length; i++)
|
|
||||||
if (x.Value[i] != y.Value[i])
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(OffsetSafeCRCRecord x, OffsetSafeCRCRecord y)
|
|
||||||
{
|
|
||||||
return !(x == y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DifferByOffset(OffsetSafeCRCRecord rec)
|
|
||||||
{
|
|
||||||
int offset;
|
|
||||||
return FindOffset(rec, out offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool FindOffset(OffsetSafeCRCRecord rec, out int offset)
|
|
||||||
{
|
|
||||||
if (this.Value.Length != 128 || rec.Value.Length != 128)
|
|
||||||
{
|
|
||||||
offset = 0;
|
|
||||||
return false;
|
|
||||||
//throw new InvalidDataException("Unsupported OffsetSafeCRCRecord");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 64; i++)
|
|
||||||
{
|
|
||||||
if (rec.Value[0] == Value[i])
|
|
||||||
{
|
|
||||||
offset = i * 64;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (Value[0] == rec.Value[i])
|
|
||||||
{
|
|
||||||
offset = -i * 64;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (int j = 0; j < 64; j++)
|
|
||||||
{
|
|
||||||
if (rec.Value[i] == Value[64 + j])
|
|
||||||
{
|
|
||||||
offset = i * 64 + j + 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (Value[i] == rec.Value[64 + j])
|
|
||||||
{
|
|
||||||
offset = -i * 64 - j - 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
offset = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AccurateRipVerify : IAudioDest
|
public class AccurateRipVerify : IAudioDest
|
||||||
{
|
{
|
||||||
public AccurateRipVerify(CDImageLayout toc, IWebProxy proxy)
|
const int maxNpar = 8;
|
||||||
|
|
||||||
|
public AccurateRipVerify(CDImageLayout toc, IWebProxy proxy)
|
||||||
{
|
{
|
||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
_accDisks = new List<AccDisk>();
|
_accDisks = new List<AccDisk>();
|
||||||
@@ -451,62 +314,37 @@ namespace CUETools.AccurateRip
|
|||||||
_CRCLOG[iTrack] = value;
|
_CRCLOG[iTrack] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe ushort[,] GetSyndrome()
|
public unsafe byte[] GetParity(int npar = maxNpar)
|
||||||
|
{
|
||||||
|
if (npar == maxNpar)
|
||||||
|
return this.parity;
|
||||||
|
|
||||||
|
var synShort = this.GetSyndrome(npar);
|
||||||
|
return ParityToSyndrome.Syndrome2Parity(synShort);
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe ushort[,] GetSyndrome(int npar = maxNpar)
|
||||||
{
|
{
|
||||||
if (!calcParity)
|
if (!calcParity)
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
var syndrome = new ushort[stride, npar];
|
return ParityToSyndrome.Parity2Syndrome(stride, npar, maxNpar, parity);
|
||||||
fixed (byte* pbpar = parity)
|
|
||||||
fixed (ushort* psyn0 = syndrome, plog = Galois16.instance.LogTbl, pexp = Galois16.instance.ExpTbl)
|
|
||||||
{
|
|
||||||
ushort* ppar = (ushort*)pbpar;
|
|
||||||
for (int y = 0; y < stride; y++)
|
|
||||||
{
|
|
||||||
ushort* syn = psyn0 + y * npar;
|
|
||||||
for (int x1 = 0; x1 < npar; x1++)
|
|
||||||
{
|
|
||||||
ushort lo = ppar[y * npar + x1];
|
|
||||||
if (lo != 0)
|
|
||||||
{
|
|
||||||
var llo = plog[lo] + 0xffff;
|
|
||||||
for (int x = 0; x < npar; x++)
|
|
||||||
syn[x] ^= pexp[llo - (1 + x1) * x];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return syndrome;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe ushort[,] Syndrome
|
private byte[] parity;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (syndrome == null)
|
|
||||||
syndrome = GetSyndrome();
|
|
||||||
return syndrome;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ushort[,] syndrome;
|
|
||||||
internal byte[] parity;
|
|
||||||
internal ushort[, ,] encodeTable;
|
internal ushort[, ,] encodeTable;
|
||||||
private int maxOffset;
|
private int maxOffset;
|
||||||
internal ushort[] leadin;
|
internal ushort[] leadin;
|
||||||
internal ushort[] leadout;
|
internal ushort[] leadout;
|
||||||
private int stride = 1, laststride = 1, stridecount = 1, npar = 1;
|
private int stride = 1, laststride = 1, stridecount = 1;
|
||||||
private bool calcParity = false;
|
private bool calcParity = false;
|
||||||
|
|
||||||
internal void InitCDRepair(int stride, int laststride, int stridecount, int npar, bool calcParity)
|
internal void InitCDRepair(int stride, int laststride, int stridecount, bool calcParity)
|
||||||
{
|
{
|
||||||
if (npar != 8)
|
|
||||||
throw new ArgumentOutOfRangeException("npar");
|
|
||||||
if (stride % 2 != 0 || laststride % 2 != 0)
|
if (stride % 2 != 0 || laststride % 2 != 0)
|
||||||
throw new ArgumentOutOfRangeException("stride");
|
throw new ArgumentOutOfRangeException("stride");
|
||||||
this.stride = stride;
|
this.stride = stride;
|
||||||
this.laststride = laststride;
|
this.laststride = laststride;
|
||||||
this.stridecount = stridecount;
|
this.stridecount = stridecount;
|
||||||
this.npar = npar;
|
|
||||||
this.calcParity = calcParity;
|
this.calcParity = calcParity;
|
||||||
Init(_toc);
|
Init(_toc);
|
||||||
}
|
}
|
||||||
@@ -572,20 +410,37 @@ namespace CUETools.AccurateRip
|
|||||||
// ((ulong*)wr)[1] = (((ulong*)(wr))[1] >> 16) ^ ((ulong*)ptiblo0)[1] ^ ((ulong*)ptiblo1)[1];
|
// ((ulong*)wr)[1] = (((ulong*)(wr))[1] >> 16) ^ ((ulong*)ptiblo0)[1] ^ ((ulong*)ptiblo1)[1];
|
||||||
//}
|
//}
|
||||||
|
|
||||||
private unsafe static void CalcPar8(ushort* pt, ushort* wr, uint lo, uint hi)
|
private unsafe static void CalcPar(ushort* pt, ushort* wr, uint lo, uint hi)
|
||||||
{
|
{
|
||||||
|
// pt = &encodeTable
|
||||||
#if !sdfs
|
#if !sdfs
|
||||||
uint wrlo = wr[0] ^ lo;
|
uint wrlo = wr[0] ^ lo;
|
||||||
uint wrhi = wr[8] ^ hi;
|
uint wrhi = wr[maxNpar] ^ hi;
|
||||||
ushort* ptiblo0 = pt + (wrlo & 255) * 16;
|
ushort* ptiblo0 = pt + (wrlo & 255) * maxNpar * 2;
|
||||||
ushort* ptiblo1 = pt + (wrlo >> 8) * 16 + 8;
|
ushort* ptiblo1 = pt + (wrlo >> 8) * maxNpar * 2 + maxNpar;
|
||||||
ushort* ptibhi0 = pt + (wrhi & 255) * 16;
|
ushort* ptibhi0 = pt + (wrhi & 255) * maxNpar * 2;
|
||||||
ushort* ptibhi1 = pt + (wrhi >> 8) * 16 + 8;
|
ushort* ptibhi1 = pt + (wrhi >> 8) * maxNpar * 2 + maxNpar;
|
||||||
wr[8] = 0;
|
wr[maxNpar] = 0;
|
||||||
((ulong*)wr)[0] = ((ulong*)(wr + 1))[0] ^ ((ulong*)ptiblo0)[0] ^ ((ulong*)ptiblo1)[0];
|
if (maxNpar == 16)
|
||||||
((ulong*)wr)[1] = ((ulong*)(wr + 1))[1] ^ ((ulong*)ptiblo0)[1] ^ ((ulong*)ptiblo1)[1];
|
{
|
||||||
((ulong*)wr)[2] = ((ulong*)(wr + 1))[2] ^ ((ulong*)ptibhi0)[0] ^ ((ulong*)ptibhi1)[0];
|
((ulong*)wr)[0] = ((ulong*)(wr + 1))[0] ^ ((ulong*)ptiblo0)[0] ^ ((ulong*)ptiblo1)[0];
|
||||||
((ulong*)wr)[3] = (((ulong*)(wr))[3] >> 16) ^ ((ulong*)ptibhi0)[1] ^ ((ulong*)ptibhi1)[1];
|
((ulong*)wr)[1] = ((ulong*)(wr + 1))[1] ^ ((ulong*)ptiblo0)[1] ^ ((ulong*)ptiblo1)[1];
|
||||||
|
((ulong*)wr)[2] = ((ulong*)(wr + 1))[2] ^ ((ulong*)ptiblo0)[2] ^ ((ulong*)ptiblo1)[2];
|
||||||
|
((ulong*)wr)[3] = ((ulong*)(wr + 1))[3] ^ ((ulong*)ptiblo0)[3] ^ ((ulong*)ptiblo1)[3];
|
||||||
|
((ulong*)wr)[4] = ((ulong*)(wr + 1))[4] ^ ((ulong*)ptibhi0)[0] ^ ((ulong*)ptibhi1)[0];
|
||||||
|
((ulong*)wr)[5] = ((ulong*)(wr + 1))[5] ^ ((ulong*)ptibhi0)[1] ^ ((ulong*)ptibhi1)[1];
|
||||||
|
((ulong*)wr)[6] = ((ulong*)(wr + 1))[6] ^ ((ulong*)ptibhi0)[2] ^ ((ulong*)ptibhi1)[2];
|
||||||
|
((ulong*)wr)[7] = (((ulong*)(wr))[7] >> 16) ^ ((ulong*)ptibhi0)[3] ^ ((ulong*)ptibhi1)[3];
|
||||||
|
}
|
||||||
|
else if (maxNpar == 8)
|
||||||
|
{
|
||||||
|
((ulong*)wr)[0] = ((ulong*)(wr + 1))[0] ^ ((ulong*)ptiblo0)[0] ^ ((ulong*)ptiblo1)[0];
|
||||||
|
((ulong*)wr)[1] = ((ulong*)(wr + 1))[1] ^ ((ulong*)ptiblo0)[1] ^ ((ulong*)ptiblo1)[1];
|
||||||
|
((ulong*)wr)[2] = ((ulong*)(wr + 1))[2] ^ ((ulong*)ptibhi0)[0] ^ ((ulong*)ptibhi1)[0];
|
||||||
|
((ulong*)wr)[3] = (((ulong*)(wr))[3] >> 16) ^ ((ulong*)ptibhi0)[1] ^ ((ulong*)ptibhi1)[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new InvalidOperationException();
|
||||||
#else
|
#else
|
||||||
const int npar = 8;
|
const int npar = 8;
|
||||||
|
|
||||||
@@ -665,7 +520,7 @@ namespace CUETools.AccurateRip
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint hi = sample >> 16;
|
uint hi = sample >> 16;
|
||||||
if (doPar) CalcPar8(pte, wr + i * 16, lo, hi);
|
if (doPar) CalcPar(pte, wr + i * maxNpar * 2, lo, hi);
|
||||||
//if (doPar) CalcPar8(pte, wr + i * 16, lo);
|
//if (doPar) CalcPar8(pte, wr + i * 16, lo);
|
||||||
//uint hi = sample >> 16;
|
//uint hi = sample >> 16;
|
||||||
|
|
||||||
@@ -738,7 +593,7 @@ namespace CUETools.AccurateRip
|
|||||||
uint* samples = ((uint*)pSampleBuff) + pos;
|
uint* samples = ((uint*)pSampleBuff) + pos;
|
||||||
int currentPart = ((int)_sampleCount * 2) % stride;
|
int currentPart = ((int)_sampleCount * 2) % stride;
|
||||||
//ushort* synptr = synptr1 + npar * currentPart;
|
//ushort* synptr = synptr1 + npar * currentPart;
|
||||||
ushort* wr = ((ushort*)bpar) + npar * currentPart;
|
ushort* wr = ((ushort*)bpar) + maxNpar * currentPart;
|
||||||
int currentStride = ((int)_sampleCount * 2) / stride;
|
int currentStride = ((int)_sampleCount * 2) / stride;
|
||||||
|
|
||||||
for (int i = 0; i < Math.Min(leadin.Length - (int)_sampleCount * 2, copyCount * 2); i++)
|
for (int i = 0; i < Math.Min(leadin.Length - (int)_sampleCount * 2, copyCount * 2); i++)
|
||||||
@@ -887,18 +742,13 @@ namespace CUETools.AccurateRip
|
|||||||
var imax = Math.Max(i1s, i2s);
|
var imax = Math.Max(i1s, i2s);
|
||||||
var diff1 = diff + (imin < i2s ? 1 : 0) - (imin < i1s ? 1 : 0);
|
var diff1 = diff + (imin < i2s ? 1 : 0) - (imin < i1s ? 1 : 0);
|
||||||
for (int i = 0; i < stride; i++)
|
for (int i = 0; i < stride; i++)
|
||||||
for (int j = 0; j < npar; j++)
|
for (int j = 0; j < maxNpar; j++)
|
||||||
{
|
{
|
||||||
var d1 = j * (i >= imin && i < imax ? diff1 : diff);
|
var d1 = j * (i >= imin && i < imax ? diff1 : diff);
|
||||||
newSyndrome1[i, j] = (ushort)(newSyndrome2[i, j] ^ Galois16.instance.mulExp(newSyndrome1[i, j], (d1 & 0xffff) + (d1 >> 16)));
|
newSyndrome1[i, j] = (ushort)(newSyndrome2[i, j] ^ Galois16.instance.mulExp(newSyndrome1[i, j], (d1 & 0xffff) + (d1 >> 16)));
|
||||||
}
|
}
|
||||||
fixed (byte* p = this.parity)
|
|
||||||
fixed (ushort* syn = newSyndrome1)
|
ParityToSyndrome.Syndrome2Parity(newSyndrome1, this.parity);
|
||||||
{
|
|
||||||
ushort* p1 = (ushort*)p;
|
|
||||||
for (int i = 0; i < stride; i++)
|
|
||||||
Galois16.instance.Syndrome2Parity(syn + i * npar, p1 + i * npar, npar);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,10 +774,12 @@ namespace CUETools.AccurateRip
|
|||||||
_CRCV2 = new uint[_toc.AudioTracks + 1, 3 * maxOffset];
|
_CRCV2 = new uint[_toc.AudioTracks + 1, 3 * maxOffset];
|
||||||
|
|
||||||
_Peak = new int[_toc.AudioTracks + 1];
|
_Peak = new int[_toc.AudioTracks + 1];
|
||||||
syndrome = null;
|
parity = null;
|
||||||
parity = calcParity ? new byte[stride * npar * 2] : null;
|
if (calcParity)
|
||||||
if (calcParity && npar == 8)
|
{
|
||||||
encodeTable = Galois16.instance.makeEncodeTable(npar);
|
parity = new byte[stride * maxNpar * 2];
|
||||||
|
encodeTable = Galois16.instance.makeEncodeTable(maxNpar);
|
||||||
|
}
|
||||||
|
|
||||||
int leadin_len = Math.Max(4096 * 4, calcParity ? stride * 2 : 0);
|
int leadin_len = Math.Max(4096 * 4, calcParity ? stride * 2 : 0);
|
||||||
int leadout_len = Math.Max(4096 * 4, calcParity ? stride + laststride : 0);
|
int leadout_len = Math.Max(4096 * 4, calcParity ? stride + laststride : 0);
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ namespace CUETools.AccurateRip
|
|||||||
: base ((int)ar.FinalSampleCount, stride, npar)
|
: base ((int)ar.FinalSampleCount, stride, npar)
|
||||||
{
|
{
|
||||||
this.ar = ar;
|
this.ar = ar;
|
||||||
ar.InitCDRepair(stride, laststride, stridecount, npar, true);
|
ar.InitCDRepair(stride, laststride, stridecount, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//private unsafe void ProcessStride(int currentStride, int currentPart, int count, ushort* data)
|
//private unsafe void ProcessStride(int currentStride, int currentPart, int count, ushort* data)
|
||||||
@@ -315,7 +315,7 @@ namespace CUETools.AccurateRip
|
|||||||
int* _errpos = stackalloc int[npar];
|
int* _errpos = stackalloc int[npar];
|
||||||
int* syn = stackalloc int[npar];
|
int* syn = stackalloc int[npar];
|
||||||
bool foundOffset = false;
|
bool foundOffset = false;
|
||||||
var arSyndrome = ar.Syndrome;
|
var arSyndrome = ar.GetSyndrome(npar);
|
||||||
|
|
||||||
for (int allowed_errors = 0; allowed_errors < npar / 2 && !foundOffset; allowed_errors++)
|
for (int allowed_errors = 0; allowed_errors < npar / 2 && !foundOffset; allowed_errors++)
|
||||||
{
|
{
|
||||||
@@ -392,7 +392,7 @@ namespace CUETools.AccurateRip
|
|||||||
{
|
{
|
||||||
int* syn = stackalloc int[npar];
|
int* syn = stackalloc int[npar];
|
||||||
int offset = fix.actualOffset;
|
int offset = fix.actualOffset;
|
||||||
var arSyndrome = ar.Syndrome;
|
var arSyndrome = ar.GetSyndrome(npar);
|
||||||
|
|
||||||
for (int part = 0; part < stride; part++)
|
for (int part = 0; part < stride; part++)
|
||||||
{
|
{
|
||||||
@@ -473,7 +473,7 @@ namespace CUETools.AccurateRip
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ar.Syndrome;
|
return this.ar.GetSyndrome(this.npar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,7 +481,7 @@ namespace CUETools.AccurateRip
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ar.parity;
|
return this.ar.GetParity(this.npar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AccurateRip.cs" />
|
<Compile Include="AccurateRip.cs" />
|
||||||
<Compile Include="CDRepair.cs" />
|
<Compile Include="CDRepair.cs" />
|
||||||
|
<Compile Include="OffsetSafeCRCRecord.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
147
CUETools.AccurateRip/OffsetSafeCRCRecord.cs
Normal file
147
CUETools.AccurateRip/OffsetSafeCRCRecord.cs
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using CUETools.Codecs;
|
||||||
|
|
||||||
|
namespace CUETools.AccurateRip
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class OffsetSafeCRCRecord
|
||||||
|
{
|
||||||
|
private uint[] val;
|
||||||
|
|
||||||
|
public OffsetSafeCRCRecord()
|
||||||
|
{
|
||||||
|
this.val = new uint[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffsetSafeCRCRecord(AccurateRipVerify ar)
|
||||||
|
: this(new uint[64 + 64])
|
||||||
|
{
|
||||||
|
int offset = 64 * 64;
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
this.val[i] = ar.CTDBCRC(0, (i + 1) * 64, offset, 2 * offset);
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
this.val[i + 64] = ar.CTDBCRC(0, 63 - i, offset, 2 * offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffsetSafeCRCRecord(uint[] val)
|
||||||
|
{
|
||||||
|
this.val = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public uint[] Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe string Base64
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
byte[] res = new byte[val.Length * 4];
|
||||||
|
fixed (byte* pres = &res[0])
|
||||||
|
fixed (uint* psrc = &val[0])
|
||||||
|
AudioSamples.MemCpy(pres, (byte*)psrc, res.Length);
|
||||||
|
var b64 = new char[res.Length * 2 + 4];
|
||||||
|
int b64len = Convert.ToBase64CharArray(res, 0, res.Length, b64, 0);
|
||||||
|
StringBuilder sb = new StringBuilder(b64len + b64len / 4 + 1);
|
||||||
|
for (int i = 0; i < b64len; i += 64)
|
||||||
|
{
|
||||||
|
sb.Append(b64, i, Math.Min(64, b64len - i));
|
||||||
|
sb.AppendLine();
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
byte[] bytes = Convert.FromBase64String(value);
|
||||||
|
if (bytes.Length % 4 != 0)
|
||||||
|
throw new InvalidDataException();
|
||||||
|
val = new uint[bytes.Length / 4];
|
||||||
|
fixed (byte* pb = &bytes[0])
|
||||||
|
fixed (uint* pv = &val[0])
|
||||||
|
AudioSamples.MemCpy((byte*)pv, pb, bytes.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return obj is OffsetSafeCRCRecord && this == (OffsetSafeCRCRecord)obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return (int)val[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(OffsetSafeCRCRecord x, OffsetSafeCRCRecord y)
|
||||||
|
{
|
||||||
|
if (x as object == null || y as object == null) return x as object == null && y as object == null;
|
||||||
|
if (x.Value.Length != y.Value.Length) return false;
|
||||||
|
for (int i = 0; i < x.Value.Length; i++)
|
||||||
|
if (x.Value[i] != y.Value[i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(OffsetSafeCRCRecord x, OffsetSafeCRCRecord y)
|
||||||
|
{
|
||||||
|
return !(x == y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DifferByOffset(OffsetSafeCRCRecord rec)
|
||||||
|
{
|
||||||
|
int offset;
|
||||||
|
return FindOffset(rec, out offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FindOffset(OffsetSafeCRCRecord rec, out int offset)
|
||||||
|
{
|
||||||
|
if (this.Value.Length != 128 || rec.Value.Length != 128)
|
||||||
|
{
|
||||||
|
offset = 0;
|
||||||
|
return false;
|
||||||
|
//throw new InvalidDataException("Unsupported OffsetSafeCRCRecord");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
if (rec.Value[0] == Value[i])
|
||||||
|
{
|
||||||
|
offset = i * 64;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Value[0] == rec.Value[i])
|
||||||
|
{
|
||||||
|
offset = -i * 64;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < 64; j++)
|
||||||
|
{
|
||||||
|
if (rec.Value[i] == Value[64 + j])
|
||||||
|
{
|
||||||
|
offset = i * 64 + j + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Value[i] == rec.Value[64 + j])
|
||||||
|
{
|
||||||
|
offset = -i * 64 - j - 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using CUETools.Codecs;
|
using CUETools.Codecs;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace CUETools.Codecs.LAME
|
namespace CUETools.Codecs.LAME
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Galois.cs" />
|
<Compile Include="Galois.cs" />
|
||||||
|
<Compile Include="Parity2Syndrome.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="RsDecode.cs" />
|
<Compile Include="RsDecode.cs" />
|
||||||
<Compile Include="RsEncode.cs" />
|
<Compile Include="RsEncode.cs" />
|
||||||
|
|||||||
Binary file not shown.
159
CUETools.Parity/Parity2Syndrome.cs
Normal file
159
CUETools.Parity/Parity2Syndrome.cs
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CUETools.Parity
|
||||||
|
{
|
||||||
|
public class ParityToSyndrome
|
||||||
|
{
|
||||||
|
private int[] erasures_pos;
|
||||||
|
private int[] erasure_loc_pol;
|
||||||
|
private int[] erasure_diff;
|
||||||
|
private int npar;
|
||||||
|
const int w = 16;
|
||||||
|
const int max = (1 << w) - 1;
|
||||||
|
|
||||||
|
public ParityToSyndrome(int npar)
|
||||||
|
{
|
||||||
|
this.npar = npar;
|
||||||
|
this.InitTables();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitTables()
|
||||||
|
{
|
||||||
|
var num_erasures = this.npar;
|
||||||
|
|
||||||
|
// Compute the erasure locator polynomial:
|
||||||
|
erasures_pos = new int[num_erasures];
|
||||||
|
for (int x = 0; x < num_erasures; x++)
|
||||||
|
erasures_pos[x] = x;
|
||||||
|
|
||||||
|
//%Compute the erasure-locator polynomial
|
||||||
|
// Optimized version
|
||||||
|
var erasure_loc_pol_exp = new int[num_erasures + 1];
|
||||||
|
erasure_loc_pol_exp[0] = 1;
|
||||||
|
for (int i = 0; i < num_erasures; i++)
|
||||||
|
for (int x = num_erasures; x > 0; x--)
|
||||||
|
erasure_loc_pol_exp[x] ^= Galois16.instance.mulExp(erasure_loc_pol_exp[x - 1], erasures_pos[i]);
|
||||||
|
erasure_loc_pol = Galois16.instance.toLog(erasure_loc_pol_exp);
|
||||||
|
erasure_diff = Galois16.instance.gfdiff(erasure_loc_pol);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe byte[] Syndrome2Parity(ushort[,] syndrome, byte[] parity = null)
|
||||||
|
{
|
||||||
|
var stride = syndrome.GetLength(0);
|
||||||
|
var npar = syndrome.GetLength(1);
|
||||||
|
var converter = new ParityToSyndrome(npar);
|
||||||
|
if (parity == null)
|
||||||
|
parity = new byte[npar * stride * 2];
|
||||||
|
fixed (byte* bpar = parity)
|
||||||
|
fixed (ushort* syn = syndrome)
|
||||||
|
{
|
||||||
|
ushort* par = (ushort*)bpar;
|
||||||
|
for (int i = 0; i < stride; i++)
|
||||||
|
converter.Syndrome2Parity(syn + i * npar, par + i * npar);
|
||||||
|
}
|
||||||
|
return parity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe ushort[,] Parity2Syndrome(int stride, int npar, int npar2, byte[] parity)
|
||||||
|
{
|
||||||
|
if (npar > npar2)
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
var syndrome = new ushort[stride, npar];
|
||||||
|
fixed (byte* pbpar = parity)
|
||||||
|
fixed (ushort* psyn = syndrome, plog = Galois16.instance.LogTbl, pexp = Galois16.instance.ExpTbl)
|
||||||
|
{
|
||||||
|
ushort* ppar = (ushort*)pbpar;
|
||||||
|
for (int y = 0; y < stride; y++)
|
||||||
|
{
|
||||||
|
ushort* syn = psyn + y * npar;
|
||||||
|
ushort* par = ppar + y * npar2;
|
||||||
|
for (int x1 = 0; x1 < npar2; x1++)
|
||||||
|
{
|
||||||
|
ushort lo = par[x1];
|
||||||
|
if (lo != 0)
|
||||||
|
{
|
||||||
|
var llo = plog[lo] + 0xffff;
|
||||||
|
for (int x = 0; x < npar; x++)
|
||||||
|
syn[x] ^= pexp[llo - (1 + x1) * x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return syndrome;
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe void Syndrome2Parity(ushort* syndrome, ushort* parity)
|
||||||
|
{
|
||||||
|
// Advance syndrome by npar zeroes (for npar 'erased' parity symbols)
|
||||||
|
var S_pol = new int[npar + 1];
|
||||||
|
S_pol[0] = -1;
|
||||||
|
for (int i = 0; i < npar; i++)
|
||||||
|
{
|
||||||
|
if (syndrome[i] == 0)
|
||||||
|
S_pol[i + 1] = -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var exp = Galois16.instance.LogTbl[syndrome[i]] + npar * i;
|
||||||
|
S_pol[i + 1] = (exp & max) + (exp >> w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var mod_syn = Galois16.instance.gfconv(erasure_loc_pol, S_pol, npar + 1);
|
||||||
|
|
||||||
|
//%Calculate remaining errors (non-erasures)
|
||||||
|
//
|
||||||
|
//S_M = [];
|
||||||
|
//for i = 1:h - num_erasures
|
||||||
|
// S_M(i) = mod_syn(i + num_erasures + 1);
|
||||||
|
//end
|
||||||
|
//flag = 0;
|
||||||
|
//if isempty(S_M) == 1
|
||||||
|
// flag = 0;
|
||||||
|
//else
|
||||||
|
// for i = 1:length(S_M)
|
||||||
|
// if (S_M(i) ~= -Inf)
|
||||||
|
// flag = 1; %Other errors occured in conjunction with erasures
|
||||||
|
// end
|
||||||
|
// end
|
||||||
|
//end
|
||||||
|
//%Find error-location polynomial sigma (Berlekamp's iterative algorithm -
|
||||||
|
//if (flag == 1)
|
||||||
|
//{
|
||||||
|
// ...
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// sigma = 0;
|
||||||
|
// comp_error_locs = [];
|
||||||
|
//}
|
||||||
|
|
||||||
|
#if kjsljdf
|
||||||
|
var sigma = new int[1] { 0 };
|
||||||
|
var omega = gfconv(sigma, gfadd(mod_syn, 0), npar + 1);
|
||||||
|
var tsi = gfconv(sigma, erasure_loc_pol);
|
||||||
|
var tsi_diff = gfdiff(tsi);
|
||||||
|
//var e_e_places = [erasures_pos comp_error_locs];
|
||||||
|
#else
|
||||||
|
var omega = mod_syn;
|
||||||
|
var tsi_diff = erasure_diff;
|
||||||
|
var e_e_places = erasures_pos;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//%Calculate the error magnitudes
|
||||||
|
//%Substitute the inverse into sigma_diff
|
||||||
|
//var ERR = new int[e_e_places.Length];
|
||||||
|
for (int ii = 0; ii < e_e_places.Length; ii++)
|
||||||
|
{
|
||||||
|
var point = max - e_e_places[ii];
|
||||||
|
var ERR_DEN = Galois16.instance.gfsubstitute(tsi_diff, point, tsi_diff.Length);
|
||||||
|
var ERR_NUM = Galois16.instance.gfsubstitute(omega, point, omega.Length);
|
||||||
|
// Additional +ii because we use slightly different syndrome
|
||||||
|
var pow = ERR_NUM + e_e_places[ii] + ii + max - ERR_DEN;
|
||||||
|
|
||||||
|
//ERR[ii] = ERR_NUM == -1 ? 0 : expTbl[(pow & max) + (pow >> w)];
|
||||||
|
parity[npar - 1 - ii] = ERR_NUM == -1 ? (ushort)0 : Galois16.instance.ExpTbl[(pow & max) + (pow >> w)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -97,7 +97,30 @@ namespace CUETools.TestCodecs
|
|||||||
CollectionAssert.AreEqual(File.ReadAllBytes("alac.m4a"), File.ReadAllBytes("alacwriter0.m4a"), "alacwriter0.m4a doesn't match.");
|
CollectionAssert.AreEqual(File.ReadAllBytes("alac.m4a"), File.ReadAllBytes("alacwriter0.m4a"), "alacwriter0.m4a doesn't match.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
[TestMethod()]
|
||||||
|
public void SeekTest()
|
||||||
|
{
|
||||||
|
var r = new ALACReader("alac.m4a", null);
|
||||||
|
var buff1 = new AudioBuffer(r, 16536);
|
||||||
|
var buff2 = new AudioBuffer(r, 16536);
|
||||||
|
Assert.AreEqual(0, r.Position);
|
||||||
|
r.Read(buff1, 7);
|
||||||
|
Assert.AreEqual(7, r.Position);
|
||||||
|
r.Position = 0;
|
||||||
|
Assert.AreEqual(0, r.Position);
|
||||||
|
r.Read(buff2, 7);
|
||||||
|
Assert.AreEqual(7, r.Position);
|
||||||
|
AudioBufferTest.AreEqual(buff1, buff2);
|
||||||
|
r.Read(buff1, 7);
|
||||||
|
Assert.AreEqual(7 + 7, r.Position);
|
||||||
|
r.Position = 7;
|
||||||
|
Assert.AreEqual(7, r.Position);
|
||||||
|
r.Read(buff2, 7);
|
||||||
|
Assert.AreEqual(7 + 7, r.Position);
|
||||||
|
AudioBufferTest.AreEqual(buff1, buff2);
|
||||||
|
r.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,12 +92,14 @@ namespace CUETools.TestParity
|
|||||||
[TestMethod()]
|
[TestMethod()]
|
||||||
public void CDRepairEncodeWriteTest()
|
public void CDRepairEncodeWriteTest()
|
||||||
{
|
{
|
||||||
Assert.AreEqual<string>("jvR9QJ1cSWpqbyP0I0tBrBkQRjCDTDDQkttZGj14ROvsXyg+AnnxVKxL7gwLZbrQmTw5ZPps1Q3744g94qaOOQ==",
|
Assert.AreEqual<string>("jvR9QJ1cSWpqbyP0I0tBrBkQRjCDTDDQkttZGj14ROvsXyg+AnnxVKxL7gwLZbrQmTw5ZPps1Q3744g94qaOOQ==",
|
||||||
Convert.ToBase64String(encode.Parity, 0, 64));
|
Convert.ToBase64String(encode.AR.GetParity(8), 0, 64));
|
||||||
Assert.AreEqual<uint>(377539636, encode.CRC);
|
//Assert.AreEqual<string>("gwln1GxlYWH/Jn74PreMLv4aFF2glkScSWVFlxMBx94v5D3/3wPx+2guRLquED0s9tOFikPLiSnAv0Xq8aIQ6Q==",
|
||||||
|
// Convert.ToBase64String(encode.AR.GetParity(16), 0, 64));
|
||||||
|
Assert.AreEqual<uint>(377539636, encode.CRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///Verifying rip that is accurate
|
///Verifying rip that is accurate
|
||||||
///</summary>
|
///</summary>
|
||||||
[TestMethod()]
|
[TestMethod()]
|
||||||
@@ -262,6 +264,7 @@ namespace CUETools.TestParity
|
|||||||
///A test for CRC parralelism
|
///A test for CRC parralelism
|
||||||
///</summary>
|
///</summary>
|
||||||
[TestMethod()]
|
[TestMethod()]
|
||||||
|
//[Ignore]
|
||||||
public void CDRepairSplitTest()
|
public void CDRepairSplitTest()
|
||||||
{
|
{
|
||||||
var seed = 723722;
|
var seed = 723722;
|
||||||
@@ -272,10 +275,9 @@ namespace CUETools.TestParity
|
|||||||
var ar1 = new TestImageGenerator("13 68 99 136", seed, 0, 0, 0, split).CreateCDRepairEncode(stride, npar);
|
var ar1 = new TestImageGenerator("13 68 99 136", seed, 0, 0, 0, split).CreateCDRepairEncode(stride, npar);
|
||||||
var ar2 = new TestImageGenerator("13 68 99 136", seed, 0, 0, split, (int)ar0.FinalSampleCount).CreateCDRepairEncode(stride, npar);
|
var ar2 = new TestImageGenerator("13 68 99 136", seed, 0, 0, split, (int)ar0.FinalSampleCount).CreateCDRepairEncode(stride, npar);
|
||||||
ar1.AR.Combine(ar2.AR, split, (int)ar0.FinalSampleCount);
|
ar1.AR.Combine(ar2.AR, split, (int)ar0.FinalSampleCount);
|
||||||
var offsets = new int[] { 0, -1, 1, -2, 2, -3, 3, -4, 4, -11, 11, -256, 256, -588, 588, 1 - 588 * 5, 588 * 5 - 1 };
|
string message = "split = " + CDImageLayout.TimeToString((uint)split / 588) + "." + (split % 588).ToString();
|
||||||
string message = "split = " + CDImageLayout.TimeToString((uint)split / 588) + "." + (split % 588).ToString();
|
|
||||||
Assert.AreEqual(ar0.CRC, ar1.CRC, "CRC was not set correctly, " + message);
|
Assert.AreEqual(ar0.CRC, ar1.CRC, "CRC was not set correctly, " + message);
|
||||||
CollectionAssert.AreEqual(ar0.Parity, ar1.Parity, "Parity was not set correctly, " + message);
|
CollectionAssert.AreEqual(ar0.Parity, ar1.Parity, "Parity was not set correctly, " + message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,32 +302,18 @@ namespace CUETools.TestParity
|
|||||||
public unsafe void CDRepairSyndrome2ParitySpeedTest()
|
public unsafe void CDRepairSyndrome2ParitySpeedTest()
|
||||||
{
|
{
|
||||||
byte[] parityCopy = new byte[encode.Parity.Length];
|
byte[] parityCopy = new byte[encode.Parity.Length];
|
||||||
|
var syndrome = encode.Syndrome;
|
||||||
for (int t = 0; t < 100; t++)
|
for (int t = 0; t < 100; t++)
|
||||||
{
|
ParityToSyndrome.Syndrome2Parity(syndrome, parityCopy);
|
||||||
fixed (byte* p = encode.Parity, p1 = parityCopy)
|
|
||||||
fixed (ushort* syn = encode.Syndrome)
|
|
||||||
{
|
|
||||||
ushort* p2 = (ushort*)p1;
|
|
||||||
for (int i = 0; i < stride; i++)
|
|
||||||
Galois16.instance.Syndrome2Parity(syn + i * npar, p2 + i * npar, npar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CollectionAssert.AreEqual(encode.Parity, parityCopy);
|
CollectionAssert.AreEqual(encode.Parity, parityCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public unsafe void CDRepairEncodeSynParTest()
|
public unsafe void CDRepairEncodeSynParTest()
|
||||||
{
|
{
|
||||||
byte[] parityCopy = new byte[encode.Parity.Length];
|
var parityCopy = ParityToSyndrome.Syndrome2Parity(encode.Syndrome);
|
||||||
fixed(byte * p = encode.Parity, p1 = parityCopy)
|
CollectionAssert.AreEqual(encode.Parity, parityCopy);
|
||||||
fixed (ushort *syn = encode.Syndrome)
|
}
|
||||||
{
|
|
||||||
ushort* p2 = (ushort*)p1;
|
|
||||||
for (int i = 0; i < stride; i++)
|
|
||||||
Galois16.instance.Syndrome2Parity(syn + i * npar, p2 + i * npar, npar);
|
|
||||||
}
|
|
||||||
CollectionAssert.AreEqual(encode.Parity, parityCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void CDRepairEncodeSpeedTest()
|
public void CDRepairEncodeSpeedTest()
|
||||||
@@ -350,7 +338,7 @@ namespace CUETools.TestParity
|
|||||||
///Verifying rip that has errors
|
///Verifying rip that has errors
|
||||||
///</summary>
|
///</summary>
|
||||||
[TestMethod()]
|
[TestMethod()]
|
||||||
//[Ignore]
|
[Ignore]
|
||||||
public void CDRepairVerifyParitySpeedTest()
|
public void CDRepairVerifyParitySpeedTest()
|
||||||
{
|
{
|
||||||
var generator1 = new TestImageGenerator("0 98011", seed, 32 * 588, 0);
|
var generator1 = new TestImageGenerator("0 98011", seed, 32 * 588, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user