Preparing for next version of CTDB

This commit is contained in:
chudov
2011-10-25 01:16:11 +00:00
parent dd1e372947
commit da7ee90588
10 changed files with 411 additions and 240 deletions

View File

@@ -5,153 +5,16 @@ using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Xml.Serialization;
using CUETools.Parity;
using CUETools.CDImage;
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;
}
}
public class AccurateRipVerify : IAudioDest
{
const int maxNpar = 8;
public AccurateRipVerify(CDImageLayout toc, IWebProxy proxy)
{
this.proxy = proxy;
@@ -451,62 +314,37 @@ namespace CUETools.AccurateRip
_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)
throw new InvalidOperationException();
var syndrome = new ushort[stride, npar];
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;
return ParityToSyndrome.Parity2Syndrome(stride, npar, maxNpar, parity);
}
public unsafe ushort[,] Syndrome
{
get
{
if (syndrome == null)
syndrome = GetSyndrome();
return syndrome;
}
}
private ushort[,] syndrome;
internal byte[] parity;
private byte[] parity;
internal ushort[, ,] encodeTable;
private int maxOffset;
internal ushort[] leadin;
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;
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)
throw new ArgumentOutOfRangeException("stride");
this.stride = stride;
this.laststride = laststride;
this.stridecount = stridecount;
this.npar = npar;
this.calcParity = calcParity;
Init(_toc);
}
@@ -572,20 +410,37 @@ namespace CUETools.AccurateRip
// ((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
uint wrlo = wr[0] ^ lo;
uint wrhi = wr[8] ^ hi;
ushort* ptiblo0 = pt + (wrlo & 255) * 16;
ushort* ptiblo1 = pt + (wrlo >> 8) * 16 + 8;
ushort* ptibhi0 = pt + (wrhi & 255) * 16;
ushort* ptibhi1 = pt + (wrhi >> 8) * 16 + 8;
wr[8] = 0;
uint wrhi = wr[maxNpar] ^ hi;
ushort* ptiblo0 = pt + (wrlo & 255) * maxNpar * 2;
ushort* ptiblo1 = pt + (wrlo >> 8) * maxNpar * 2 + maxNpar;
ushort* ptibhi0 = pt + (wrhi & 255) * maxNpar * 2;
ushort* ptibhi1 = pt + (wrhi >> 8) * maxNpar * 2 + maxNpar;
wr[maxNpar] = 0;
if (maxNpar == 16)
{
((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*)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
const int npar = 8;
@@ -665,7 +520,7 @@ namespace CUETools.AccurateRip
}
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);
//uint hi = sample >> 16;
@@ -738,7 +593,7 @@ namespace CUETools.AccurateRip
uint* samples = ((uint*)pSampleBuff) + pos;
int currentPart = ((int)_sampleCount * 2) % stride;
//ushort* synptr = synptr1 + npar * currentPart;
ushort* wr = ((ushort*)bpar) + 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++)
@@ -887,18 +742,13 @@ namespace CUETools.AccurateRip
var imax = Math.Max(i1s, i2s);
var diff1 = diff + (imin < i2s ? 1 : 0) - (imin < i1s ? 1 : 0);
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);
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)
{
ushort* p1 = (ushort*)p;
for (int i = 0; i < stride; i++)
Galois16.instance.Syndrome2Parity(syn + i * npar, p1 + i * npar, npar);
}
ParityToSyndrome.Syndrome2Parity(newSyndrome1, this.parity);
}
}
@@ -924,10 +774,12 @@ namespace CUETools.AccurateRip
_CRCV2 = new uint[_toc.AudioTracks + 1, 3 * maxOffset];
_Peak = new int[_toc.AudioTracks + 1];
syndrome = null;
parity = calcParity ? new byte[stride * npar * 2] : null;
if (calcParity && npar == 8)
encodeTable = Galois16.instance.makeEncodeTable(npar);
parity = null;
if (calcParity)
{
parity = new byte[stride * maxNpar * 2];
encodeTable = Galois16.instance.makeEncodeTable(maxNpar);
}
int leadin_len = Math.Max(4096 * 4, calcParity ? stride * 2 : 0);
int leadout_len = Math.Max(4096 * 4, calcParity ? stride + laststride : 0);

View File

@@ -94,7 +94,7 @@ namespace CUETools.AccurateRip
: base ((int)ar.FinalSampleCount, stride, npar)
{
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)
@@ -315,7 +315,7 @@ namespace CUETools.AccurateRip
int* _errpos = stackalloc int[npar];
int* syn = stackalloc int[npar];
bool foundOffset = false;
var arSyndrome = ar.Syndrome;
var arSyndrome = ar.GetSyndrome(npar);
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 offset = fix.actualOffset;
var arSyndrome = ar.Syndrome;
var arSyndrome = ar.GetSyndrome(npar);
for (int part = 0; part < stride; part++)
{
@@ -473,7 +473,7 @@ namespace CUETools.AccurateRip
{
get
{
return ar.Syndrome;
return this.ar.GetSyndrome(this.npar);
}
}
@@ -481,7 +481,7 @@ namespace CUETools.AccurateRip
{
get
{
return ar.parity;
return this.ar.GetParity(this.npar);
}
}
}

View File

@@ -64,6 +64,7 @@
<ItemGroup>
<Compile Include="AccurateRip.cs" />
<Compile Include="CDRepair.cs" />
<Compile Include="OffsetSafeCRCRecord.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

View 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;
}
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using CUETools.Codecs;
using System.IO;
namespace CUETools.Codecs.LAME
{

View File

@@ -60,6 +60,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Galois.cs" />
<Compile Include="Parity2Syndrome.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RsDecode.cs" />
<Compile Include="RsEncode.cs" />

Binary file not shown.

View 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)];
}
}
}
}

View File

@@ -97,6 +97,29 @@ namespace CUETools.TestCodecs
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();
}
}

View File

@@ -93,7 +93,9 @@ namespace CUETools.TestParity
public void CDRepairEncodeWriteTest()
{
Assert.AreEqual<string>("jvR9QJ1cSWpqbyP0I0tBrBkQRjCDTDDQkttZGj14ROvsXyg+AnnxVKxL7gwLZbrQmTw5ZPps1Q3744g94qaOOQ==",
Convert.ToBase64String(encode.Parity, 0, 64));
Convert.ToBase64String(encode.AR.GetParity(8), 0, 64));
//Assert.AreEqual<string>("gwln1GxlYWH/Jn74PreMLv4aFF2glkScSWVFlxMBx94v5D3/3wPx+2guRLquED0s9tOFikPLiSnAv0Xq8aIQ6Q==",
// Convert.ToBase64String(encode.AR.GetParity(16), 0, 64));
Assert.AreEqual<uint>(377539636, encode.CRC);
}
@@ -262,6 +264,7 @@ namespace CUETools.TestParity
///A test for CRC parralelism
///</summary>
[TestMethod()]
//[Ignore]
public void CDRepairSplitTest()
{
var seed = 723722;
@@ -272,7 +275,6 @@ namespace CUETools.TestParity
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);
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();
Assert.AreEqual(ar0.CRC, ar1.CRC, "CRC was not set correctly, " + message);
CollectionAssert.AreEqual(ar0.Parity, ar1.Parity, "Parity was not set correctly, " + message);
@@ -300,30 +302,16 @@ namespace CUETools.TestParity
public unsafe void CDRepairSyndrome2ParitySpeedTest()
{
byte[] parityCopy = new byte[encode.Parity.Length];
var syndrome = encode.Syndrome;
for (int t = 0; t < 100; t++)
{
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);
}
}
ParityToSyndrome.Syndrome2Parity(syndrome, parityCopy);
CollectionAssert.AreEqual(encode.Parity, parityCopy);
}
[TestMethod]
public unsafe void CDRepairEncodeSynParTest()
{
byte[] parityCopy = new byte[encode.Parity.Length];
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);
}
var parityCopy = ParityToSyndrome.Syndrome2Parity(encode.Syndrome);
CollectionAssert.AreEqual(encode.Parity, parityCopy);
}
@@ -350,7 +338,7 @@ namespace CUETools.TestParity
///Verifying rip that has errors
///</summary>
[TestMethod()]
//[Ignore]
[Ignore]
public void CDRepairVerifyParitySpeedTest()
{
var generator1 = new TestImageGenerator("0 98011", seed, 32 * 588, 0);