Calculating CRC32 with offsets and fast

This commit is contained in:
chudov
2010-02-09 20:05:54 +00:00
parent 6d5e0602bd
commit 478799379a
21 changed files with 770 additions and 92 deletions

View File

@@ -136,19 +136,37 @@ All the other CRC's in this offset range are calculated by consequently adding s
}
uint crc32 = _offsetedCRC32[_currentTrack, 10 * 588 - 1];
uint crcwn = _offsetedCRCWN[_currentTrack, 10 * 588 - 1];
int crcnulls = _offsetedCRCNulls[_currentTrack, 10 * 588 - 1];
fixed (uint* CRCs = &_offsetedCRC[iTrack, 0], t = _crc32.table)
{
uint baseSum = 0, stepSum = 0;
int* s = samples;
for (uint mult = 0; mult < count; mult++)
{
uint sampleValue = (uint)((*(s++) & 0xffff) + (*(s++) << 16));
uint lo = (uint)*(s++) & 0xffff;
crc32 = (crc32 >> 8) ^ t[(byte)(crc32 ^ lo)];
crc32 = (crc32 >> 8) ^ t[(byte)(crc32 ^ (lo >> 8))];
if (lo != 0)
{
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ lo)];
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ (lo >> 8))];
}
else crcnulls++;
uint hi = (uint)*(s++) & 0xffff;
crc32 = (crc32 >> 8) ^ t[(byte)(crc32 ^ hi)];
crc32 = (crc32 >> 8) ^ t[(byte)(crc32 ^ (hi >> 8))];
if (hi != 0)
{
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ hi)];
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ (hi >> 8))];
}
else crcnulls++;
uint sampleValue = lo + (hi << 16);
stepSum += sampleValue;
baseSum += sampleValue * mult;
crc32 = (crc32 >> 8) ^ t[(byte)(crc32 ^ sampleValue)];
crc32 = (crc32 >> 8) ^ t[(byte)(crc32 ^ (sampleValue >> 8))];
crc32 = (crc32 >> 8) ^ t[(byte)(crc32 ^ (sampleValue >> 16))];
crc32 = (crc32 >> 8) ^ t[(byte)(crc32 ^ (sampleValue >> 24))];
}
currentOffset += _arOffsetRange + 1;
baseSum += stepSum * (uint)currentOffset;
@@ -159,6 +177,8 @@ All the other CRC's in this offset range are calculated by consequently adding s
}
}
_offsetedCRC32[_currentTrack, 10 * 588 - 1] = crc32;
_offsetedCRCWN[_currentTrack, 10 * 588 - 1] = crcwn;
_offsetedCRCNulls[_currentTrack, 10 * 588 - 1] = crcnulls;
}
public uint CRC(int iTrack)
@@ -264,8 +284,28 @@ All the other CRC's in this offset range are calculated by consequently adding s
for (iTrack = 0; iTrack <= _toc.AudioTracks; iTrack++)
{
int trackLength = (int)(iTrack > 0 ? _toc[iTrack + _toc.FirstAudio - 1].Length : _toc[_toc.FirstAudio].Pregap) * 588 * 4;
if (oi < 0 && iTrack == 0)
crc = _crc32.Combine(crc, 0, -oi * 4);
if (trackLength == 0)
continue;
if (oi > 0 && (iTrack == 0 || (iTrack == 1 && _toc[_toc.FirstAudio].Pregap == 0)))
{
// Calculate track CRC skipping first oi samples by 'subtracting' their CRC
crc = _crc32.Combine(_offsetedCRC32[iTrack, oi - 1], _offsetedCRC32[iTrack, 10 * 588 - 1], trackLength - oi * 4);
// Use 0xffffffff as an initial state
crc = _crc32.Combine(0xffffffff, crc, trackLength - oi * 4);
}
else if (oi < 0 && iTrack == _toc.AudioTracks)
{
crc = _crc32.Combine(crc, _offsetedCRC32[iTrack, 10 * 588 + oi - 1], trackLength + oi * 4);
}
else
{
crc = _crc32.Combine(crc, _offsetedCRC32[iTrack, 10 * 588 - 1], trackLength);
}
if (oi > 0 && iTrack == _toc.AudioTracks)
crc = _crc32.Combine(crc, 0, oi * 4);
}
iTrack = 0;
}
else
@@ -305,7 +345,69 @@ All the other CRC's in this offset range are calculated by consequently adding s
public uint CRCWONULL(int iTrack)
{
return _CRCWONULL[iTrack] ^ 0xffffffff;
return CRCWONULL(iTrack, 0);
}
public uint CRCWONULL(int iTrack, int oi)
{
if (_offsetedCRCWNRes[iTrack, _arOffsetRange + oi] == 0)
{
uint crc = 0xffffffff;
if (iTrack == 0)
{
for (iTrack = 0; iTrack <= _toc.AudioTracks; iTrack++)
{
int trackLength = (int)(iTrack > 0 ? _toc[iTrack + _toc.FirstAudio - 1].Length : _toc[_toc.FirstAudio].Pregap) * 588 * 4
- _offsetedCRCNulls[iTrack, 10 * 588 - 1] * 2;
crc = _crc32.Combine(crc, _offsetedCRCWN[iTrack, 10 * 588 - 1], trackLength);
}
iTrack = 0;
}
else
{
int trackLength = (int)(iTrack > 0 ? _toc[iTrack + _toc.FirstAudio - 1].Length : _toc[_toc.FirstAudio].Pregap) * 588 * 4;
if (oi > 0)
{
int nonzeroPrevLength = trackLength - oi * 4 -
(_offsetedCRCNulls[iTrack, 10 * 588 - 1] - _offsetedCRCNulls[iTrack, oi - 1]) * 2;
// Calculate track CRC skipping first oi samples by 'subtracting' their CRC
crc = _crc32.Combine(
_offsetedCRCWN[iTrack, oi - 1],
_offsetedCRCWN[iTrack, 10 * 588 - 1],
nonzeroPrevLength);
// Use 0xffffffff as an initial state
crc = _crc32.Combine(0xffffffff, crc, nonzeroPrevLength);
// Add oi samples from next track CRC
if (iTrack < _toc.AudioTracks)
crc = _crc32.Combine(crc,
_offsetedCRCWN[iTrack + 1, oi - 1],
oi * 4 - _offsetedCRCNulls[iTrack + 1, oi - 1] * 2);
}
else if (oi < 0)
{
int nonzeroPrevLength = -oi * 4 -
(_offsetedCRCNulls[iTrack - 1, 10 * 588 - 1] - _offsetedCRCNulls[iTrack - 1, 10 * 588 + oi - 1]) * 2;
// Calculate CRC of previous track's last oi samples by 'subtracting' it's last CRCs
crc = _crc32.Combine(
_offsetedCRCWN[iTrack - 1, 10 * 588 + oi - 1],
_offsetedCRCWN[iTrack - 1, 10 * 588 - 1],
nonzeroPrevLength);
// Use 0xffffffff as an initial state
crc = _crc32.Combine(0xffffffff, crc, nonzeroPrevLength);
// Add this track's CRC without last oi samples
crc = _crc32.Combine(crc,
_offsetedCRCWN[iTrack, 10 * 588 + oi - 1],
trackLength + oi * 4 - _offsetedCRCNulls[iTrack, 10 * 588 + oi - 1] * 2);
}
else // oi == 0
{
// Use 0xffffffff as an initial state
crc = _crc32.Combine(0xffffffff, _offsetedCRCWN[iTrack, 10 * 588 - 1], trackLength - _offsetedCRCNulls[iTrack, 10 * 588 - 1] * 2);
}
}
_offsetedCRCWNRes[iTrack, _arOffsetRange + oi] = crc ^ 0xffffffff;
}
return _offsetedCRCWNRes[iTrack, _arOffsetRange + oi];
}
public uint CRCLOG(int iTrack)
@@ -324,37 +426,11 @@ All the other CRC's in this offset range are calculated by consequently adding s
return _offsetedFrame450CRC[iTrack, _arOffsetRange - oi];
}
public unsafe void CalculateCRCs(AudioBuffer buff, int pos, int count)
{
uint crc2 = _CRCWONULL[0];
uint crc3 = _CRCWONULL[_currentTrack];
fixed (int* pSampleBuff = &buff.Samples[pos, 0])
fixed (uint* t = _crc32.table)
{
for (int i = 0; i < 2 * count; i++)
{
int s = pSampleBuff[i];
if (s != 0)
{
byte s0 = (byte)s;
byte s1 = (byte)(s >> 8);
crc2 = (crc2 >> 8) ^ t[((byte)crc2) ^ s0];
crc2 = (crc2 >> 8) ^ t[((byte)crc2) ^ s1];
crc3 = (crc3 >> 8) ^ t[((byte)crc3) ^ s0];
crc3 = (crc3 >> 8) ^ t[((byte)crc3) ^ s1];
}
}
}
_CRCWONULL[0] = crc2;
if (_currentTrack > 0)
_CRCWONULL[_currentTrack] = crc3;
}
public unsafe void CalculateCRCs(int* pSampleBuff, int count, int currentOffset)
{
uint crc = _offsetedCRC32[_currentTrack, 10 * 588 - 1];
uint crcwn = _offsetedCRCWN[_currentTrack, 10 * 588 - 1];
int crcnulls = _offsetedCRCNulls[_currentTrack, 10 * 588 - 1];
fixed (uint* t = _crc32.table)
{
for (int i = 0; i < count; i++)
@@ -367,22 +443,40 @@ All the other CRC's in this offset range are calculated by consequently adding s
s1 = (byte)(s >> 8);
crc = (crc >> 8) ^ t[((byte)crc) ^ s0];
crc = (crc >> 8) ^ t[((byte)crc) ^ s1];
if (s != 0)
{
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ s0)];
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ s1)];
}
else crcnulls++;
s = *(pSampleBuff++);
s0 = (byte)s;
s1 = (byte)(s >> 8);
crc = (crc >> 8) ^ t[((byte)crc) ^ s0];
crc = (crc >> 8) ^ t[((byte)crc) ^ s1];
if (s != 0)
{
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ s0)];
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ s1)];
}
else crcnulls++;
_offsetedCRC32[_currentTrack, currentOffset + i] = crc;
_offsetedCRCWN[_currentTrack, currentOffset + i] = crcwn;
_offsetedCRCNulls[_currentTrack, currentOffset + i] = crcnulls;
}
}
_offsetedCRC32[_currentTrack, 10 * 588 - 1] = crc;
_offsetedCRCWN[_currentTrack, 10 * 588 - 1] = crcwn;
_offsetedCRCNulls[_currentTrack, 10 * 588 - 1] = crcnulls;
}
public unsafe void CalculateCRCs(int* pSampleBuff, int count)
{
uint crc = _offsetedCRC32[_currentTrack, 10 * 588 - 1];
uint crcwn = _offsetedCRCWN[_currentTrack, 10 * 588 - 1];
int crcnulls = _offsetedCRCNulls[_currentTrack, 10 * 588 - 1];
fixed (uint* t = _crc32.table)
{
for (int i = 0; i < count; i++)
@@ -395,15 +489,29 @@ All the other CRC's in this offset range are calculated by consequently adding s
s1 = (byte)(s >> 8);
crc = (crc >> 8) ^ t[((byte)crc) ^ s0];
crc = (crc >> 8) ^ t[((byte)crc) ^ s1];
if (s != 0)
{
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ s0)];
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ s1)];
}
else crcnulls++;
s = *(pSampleBuff++);
s0 = (byte)s;
s1 = (byte)(s >> 8);
crc = (crc >> 8) ^ t[((byte)crc) ^ s0];
crc = (crc >> 8) ^ t[((byte)crc) ^ s1];
if (s != 0)
{
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ s0)];
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ s1)];
}
else crcnulls++;
}
}
_offsetedCRC32[_currentTrack, 10 * 588 - 1] = crc;
_offsetedCRCWN[_currentTrack, 10 * 588 - 1] = crcwn;
_offsetedCRCNulls[_currentTrack, 10 * 588 - 1] = crcnulls;
}
public void Write(AudioBuffer sampleBuffer)
@@ -420,8 +528,6 @@ All the other CRC's in this offset range are calculated by consequently adding s
int currentSector = currentOffset / 588;
int remaingSectors = (int)(_samplesRemTrack - 1) / 588;
CalculateCRCs(sampleBuffer, pos, copyCount);
unsafe
{
fixed (int* pSampleBuff = &sampleBuffer.Samples[pos, 0])
@@ -459,10 +565,10 @@ All the other CRC's in this offset range are calculated by consequently adding s
_offsetedCRC = new uint[_toc.AudioTracks, 10 * 588];
_offsetedCRC32 = new uint[_toc.AudioTracks + 1, 10 * 588];
_offsetedCRC32Res = new uint[_toc.AudioTracks + 1, 10 * 588];
_offsetedCRCWN = new uint[_toc.AudioTracks + 1, 10 * 588];
_offsetedCRCWNRes = new uint[_toc.AudioTracks + 1, 10 * 588];
_offsetedCRCNulls = new int[_toc.AudioTracks + 1, 10 * 588];
_offsetedFrame450CRC = new uint[_toc.AudioTracks, 10 * 588];
_CRCWONULL = new uint[_toc.AudioTracks + 1];
for (int i = 0; i <= _toc.AudioTracks; i++)
_CRCWONULL[i] = 0xffffffff;
_currentTrack = 0;
_sampleCount = _toc[_toc.FirstAudio][0].Start * 588;
_samplesRemTrack = _toc[_toc.FirstAudio].Pregap * 588;
@@ -761,8 +867,7 @@ All the other CRC's in this offset range are calculated by consequently adding s
{
sw.WriteLine("");
sw.WriteLine("Track\t[ CRC32 ]\t[W/O NULL]\t{0:10}", _hasLogCRC ? "[ LOG ]" : "");
sw.WriteLine(String.Format(" --\t[{0:X8}]\t[{1:X8}]\t{2:10}", CRC32(0), CRCWONULL(0), CRCLOG(0) == CRC32(0) ? " CRC32 " : CRCLOG(0) == CRCWONULL(0) ? " W/O NULL " : CRCLOG(0) == 0 ? "" : String.Format("[{0:X8}]", CRCLOG(0))));
for (int iTrack = 1; iTrack <= _toc.AudioTracks; iTrack++)
for (int iTrack = 0; iTrack <= _toc.AudioTracks; iTrack++)
{
string inLog, extra = "";
if (CRCLOG(iTrack) == 0)
@@ -788,16 +893,28 @@ All the other CRC's in this offset range are calculated by consequently adding s
}
}
if (extra == "")
{
for (int oi = -_arOffsetRange; oi <= _arOffsetRange; oi++)
if (CRCLOG(iTrack) == CRC32(iTrack, oi))
{
inLog = " CRC32 ";
extra = string.Format(": offset {0}", oi);
break;
}
if (extra == "")
for (int oi = -_arOffsetRange; oi <= _arOffsetRange; oi++)
if (CRCLOG(iTrack) == CRCWONULL(iTrack, oi))
{
inLog = " W/O NULL ";
if (extra == "")
extra = string.Format(": offset {0}", oi);
else
{
extra = string.Format(": with offset");
break;
}
}
}
sw.WriteLine(String.Format(" {0:00}\t[{1:X8}]\t[{2:X8}]\t{3:10}{4}", iTrack, CRC32(iTrack), CRCWONULL(iTrack), inLog, extra));
sw.WriteLine(String.Format(" {0}\t[{1:X8}]\t[{2:X8}]\t{3:10}{4}", iTrack == 0 ? "--" : string.Format("{0:00}", iTrack), CRC32(iTrack), CRCWONULL(iTrack), inLog, extra));
}
}
}
@@ -948,10 +1065,13 @@ All the other CRC's in this offset range are calculated by consequently adding s
private List<AccDisk> _accDisks;
private HttpStatusCode _accResult;
private uint[,] _offsetedCRC32;
private uint[,] _offsetedCRCWN;
private uint[,] _offsetedCRCWNRes;
private int[,] _offsetedCRCNulls;
private uint[,] _offsetedCRC32Res;
private uint[,] _offsetedCRC;
private uint[,] _offsetedFrame450CRC;
private uint[] _CRCWONULL, _CRCLOG;
private uint[] _CRCLOG;
private uint[] _backupCRC;
Crc32 _crc32;

View File

@@ -44,34 +44,6 @@ namespace CUETools.Codecs
return crc;
}
public unsafe uint ComputeChecksumWONULL(uint crc, short* samples, int count)
{
fixed (uint* t = table)
for (int i = 0; i < count; i++)
{
short s1 = samples[i];
if (s1 != 0)
{
crc = (crc >> 8) ^ t[(crc ^ s1) & 0xff];
crc = (crc >> 8) ^ t[(crc ^ (s1 >> 8)) & 0xff];
}
}
return crc;
}
public unsafe uint ComputeChecksumWONULL(uint crc, int* samples, int count)
{
for (int i = 0; i < count; i++)
{
int s1 = samples[2 * i], s2 = samples[2 * i + 1];
if (s1 != 0)
crc = ComputeChecksum(ComputeChecksum(crc, (byte)s1), (byte)(s1 >> 8));
if (s2 != 0)
crc = ComputeChecksum(ComputeChecksum(crc, (byte)s2), (byte)(s2 >> 8));
}
return crc;
}
uint Reflect(uint val, int ch)
{
uint value = 0;

View File

@@ -20,8 +20,6 @@ namespace CUETools.TestCodecs
private TestContext testContextInstance;
private int[,] testSamples = new int[,] { { 0, 0 }, { -2, -3 }, { 32767, 32766 }, { -32765, -32764 } };
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
@@ -79,23 +77,39 @@ namespace CUETools.TestCodecs
public void CalculateCRCsTest()
{
CDImageLayout toc = new CDImageLayout();
toc.AddTrack(new CDTrack(1, 0, 10, true, false));
toc.AddTrack(new CDTrack(1, 03, 20, true, false));
toc.AddTrack(new CDTrack(2, 23, 20, true, false));
toc.AddTrack(new CDTrack(3, 43, 20, true, false));
AccurateRipVerify target = new AccurateRipVerify(toc);
AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, testSamples, testSamples.GetLength(0));
target.CalculateCRCs(buff, 0, testSamples.GetLength(0));
Crc32 crc32 = new Crc32();
uint crc1 = crc32.ComputeChecksum(0xffffffff, buff.Bytes, 0, buff.ByteLength) ^ 0xffffffff;
Assert.AreEqual<uint>(3856971150, crc1, "CRC32 was not set correctly.");
uint crc2 = crc32.ComputeChecksum(0, buff.Bytes, 0, buff.ByteLength);
uint crc3 = crc32.ComputeChecksum(0, buff.Bytes, 0, 7);
uint crc4 = crc32.ComputeChecksum(0, buff.Bytes, 7, buff.ByteLength - 7);
uint crc5 = crc32.Combine(crc3, crc4, buff.ByteLength - 7);
Assert.AreEqual<uint>(crc2, crc5, "CRC32 was not combined correctly.");
uint crc6 = crc2 ^ crc32.Combine(crc3, 0, buff.ByteLength - 7);
Assert.AreEqual<uint>(crc4, crc6, "CRC32 was not substracted correctly.");
Assert.AreEqual<uint>(3856971150, target.CRC32(0), "CRC32 was not set correctly.");
Assert.AreEqual<uint>(1921661108, target.CRCWONULL(0), "CRC32WONULL was not set correctly.");
for (int sector = 0; sector < toc.AudioLength; sector++)
{
AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 588);
buff.Length = 588;
for (int i = 0; i < buff.Length; i++)
{
buff.Samples[i, 0] = sector * 588 + i;
buff.Samples[i, 1] = sector * 588;
}
target.Write(buff);
}
Assert.AreEqual<uint>(3762425816, target.CRC(0), "CRC[0] was not set correctly.");
Assert.AreEqual<uint>(3103217968, target.CRC(1), "CRC[1] was not set correctly.");
Assert.AreEqual<uint>(3206462296, target.CRC(1, 11), "CRC[1][11] was not set correctly.");
Assert.AreEqual<uint>(3068174852, target.CRC(2), "CRC[2] was not set correctly.");
Assert.AreEqual<uint>(3233779629, target.CRC32(0), "CRC32[0] was not set correctly.");
Assert.AreEqual<uint>(3753760724, target.CRC32(0, 13), "CRC32[0][13] was not set correctly.");
Assert.AreEqual<uint>(3153592639, target.CRC32(0, -7), "CRC32[0][-7] was not set correctly.");
Assert.AreEqual<uint>(0408974480, target.CRC32(1), "CRC32[1] was not set correctly.");
Assert.AreEqual<uint>(4123211700, target.CRC32(2), "CRC32[2] was not set correctly.");
Assert.AreEqual<uint>(0297562037, target.CRC32(2, 15), "CRC32[2][15] was not set correctly.");
Assert.AreEqual<uint>(0398293317, target.CRC32(2, -1), "CRC32[2][-1] was not set correctly.");
Assert.AreEqual<uint>(0564210909, target.CRC32(3), "CRC32[3] was not set correctly.");
Assert.AreEqual<uint>(2395016718, target.CRCWONULL(0), "CRC32WONULL[0] was not set correctly.");
Assert.AreEqual<uint>(0834934371, target.CRCWONULL(1), "CRC32WONULL[1] was not set correctly.");
Assert.AreEqual<uint>(4123211700, target.CRCWONULL(2), "CRC32WONULL[2] was not set correctly.");
Assert.AreEqual<uint>(0062860870, target.CRCWONULL(2, 19), "CRC32WONULL[2][19] was not set correctly.");
Assert.AreEqual<uint>(0950746738, target.CRCWONULL(2, -2), "CRC32WONULL[2][-2] was not set correctly.");
Assert.AreEqual<uint>(0564210909, target.CRCWONULL(3), "CRC32WONULL[3] was not set correctly.");
}
}

View File

@@ -40,6 +40,7 @@
<Compile Include="AccurateRipTest.cs" />
<Compile Include="ALACWriterTest.cs" />
<Compile Include="CodecsTest.cs" />
<Compile Include="Crc32Test.cs" />
<Compile Include="FlakeWriterTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>

View File

@@ -0,0 +1,94 @@
using CUETools.Codecs;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace CUETools.TestCodecs
{
/// <summary>
///This is a test class for Crc32Test and is intended
///to contain all Crc32Test Unit Tests
///</summary>
[TestClass()]
public class Crc32Test
{
private byte[] testBytes = new byte[] { 0, 0, 1, 0, 254, 255, 253, 255, 255, 127, 254, 127, 3, 128, 4, 128 };
private TestContext testContextInstance;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
#region Additional test attributes
//
//You can use the following additional attributes as you write your tests:
//
//Use ClassInitialize to run code before running the first test in the class
//[ClassInitialize()]
//public static void MyClassInitialize(TestContext testContext)
//{
//}
//
//Use ClassCleanup to run code after all tests in a class have run
//[ClassCleanup()]
//public static void MyClassCleanup()
//{
//}
//
//Use TestInitialize to run code before running each test
//[TestInitialize()]
//public void MyTestInitialize()
//{
//}
//
//Use TestCleanup to run code after each test has run
//[TestCleanup()]
//public void MyTestCleanup()
//{
//}
//
#endregion
/// <summary>
///A test for Combine
///</summary>
[TestMethod()]
public void CombineTest()
{
Crc32 crc32 = new Crc32();
int lenAB = testBytes.Length;
int lenA = 7;
int lenB = lenAB - lenA;
uint crcAB = crc32.ComputeChecksum(0, testBytes, 0, lenAB);
uint crcA = crc32.ComputeChecksum(0, testBytes, 0, lenA);
uint crcB = crc32.ComputeChecksum(0, testBytes, lenA, lenB);
Assert.AreEqual<uint>(crcAB, crc32.Combine(crcA, crcB, lenB), "CRC32 was not combined correctly.");
Assert.AreEqual<uint>(crcB, crc32.Combine(crcA, crcAB, lenB), "CRC32 was not substracted correctly.");
}
/// <summary>
///A test for ComputeChecksum
///</summary>
[TestMethod()]
public void ComputeChecksumTest()
{
Crc32 crc32 = new Crc32();
uint actual = crc32.ComputeChecksum(0xffffffff, testBytes, 0, testBytes.Length) ^ 0xffffffff;
Assert.AreEqual<uint>(2028688632, actual, "CRC32 was not combined correctly.");
}
}
}

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A430AD28-B76A-4ED0-AF7D-D13B8969297F}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>CUETools.TestProcessor</RootNamespace>
<AssemblyName>CUETools.TestProcessor</AssemblyName>
<WarningLevel>4</WarningLevel>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>2.0</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>.\bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>false</DebugSymbols>
<Optimize>true</Optimize>
<OutputPath>..\bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference Include="CSScriptLibrary.v1.1, Version=2.3.2.0, Culture=neutral">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\CUETools.Processor\CSScriptLibrary.v1.1.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ProcessorTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\CUETools.AccurateRip\CUETools.AccurateRip.csproj">
<Project>{5802C7E9-157E-4124-946D-70B5AE48A5A1}</Project>
<Name>CUETools.AccurateRip</Name>
</ProjectReference>
<ProjectReference Include="..\..\CUETools.CDImage\CUETools.CDImage.csproj">
<Project>{1DD41038-D885-46C5-8DDE-E0B82F066584}</Project>
<Name>CUETools.CDImage</Name>
</ProjectReference>
<ProjectReference Include="..\..\CUETools.Codecs\CUETools.Codecs.csproj">
<Project>{6458A13A-30EF-45A9-9D58-E5031B17BEE2}</Project>
<Name>CUETools.Codecs</Name>
</ProjectReference>
<ProjectReference Include="..\..\CUETools.Processor\CUETools.Processor.csproj">
<Project>{4911BD82-49EF-4858-8B51-5394F86739A4}</Project>
<Name>CUETools.Processor</Name>
</ProjectReference>
<ProjectReference Include="..\..\Freedb\Freedb.csproj">
<Project>{5ADCFD6D-BFEA-4B10-BB45-9083BBB56AF4}</Project>
<Name>Freedb</Name>
</ProjectReference>
<ProjectReference Include="..\..\MusicBrainz\MusicBrainz.csproj">
<Project>{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}</Project>
<Name>MusicBrainz</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>

View File

@@ -0,0 +1,101 @@
// The following code was generated by Microsoft Visual Studio 2005.
// The test owner should check each test for validity.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Text;
using System.Collections.Generic;
using CUETools.Processor;
using CUETools.AccurateRip;
namespace CUETools.TestProcessor
{
/// <summary>
///This is a test class for CUETools.Processor.CUESheet and is intended
///to contain all CUETools.Processor.CUESheet Unit Tests
///</summary>
[TestClass()]
public class CUESheetTest
{
private TestContext testContextInstance;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
#region Additional test attributes
//
//You can use the following additional attributes as you write your tests:
//
//Use ClassInitialize to run code before running the first test in the class
//
//[ClassInitialize()]
//public static void MyClassInitialize(TestContext testContext)
//{
//}
//
//Use ClassCleanup to run code after all tests in a class have run
//
//[ClassCleanup()]
//public static void MyClassCleanup()
//{
//}
//
//Use TestInitialize to run code before running each test
//
//[TestInitialize()]
//public void MyTestInitialize()
//{
//}
//
//Use TestCleanup to run code after each test has run
//
//[TestCleanup()]
//public void MyTestCleanup()
//{
//}
//
#endregion
/// <summary>
///A test for Open (string)
///</summary>
[TestMethod()]
public void OpenTest()
{
CUEConfig config = new CUEConfig();
CUESheet target = null;
// test playstation-type CD-Extra
target = new CUESheet(config);
target.Open("Circuitry\\1.cue");
Assert.AreEqual<string>("00078c13-001b4ab9-40086205", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC");
// test Enhanced-CD
target = new CUESheet(config);
target.Open("No Man's Land\\1.cue");
Assert.AreEqual<string>("0015c42c-00d1e13f-ba0fe50d", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC");
// test one-track CD
target = new CUESheet(config);
target.Open("Amarok\\Amarok.cue");
Assert.AreEqual<string>("00041f6d-00083ece-020e1201", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC");
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CUETools.TestProcessor")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("CUETools.TestProcessor")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM componenets. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("326c452b-4615-4875-ae4f-0f97db286ef3")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,5 @@
REM DISCID 020E1201
FILE "Amarok.dummy" WAVE
TRACK 01 AUDIO
INDEX 00 00:00:00
INDEX 01 00:00:12

View File

@@ -0,0 +1 @@
60:02:27

View File

@@ -0,0 +1,15 @@
[Verification date: 04.02.2010 1:34:25]
[Disc ID: 00078c13-001b4ab9-40086205]
Playstation type data track length 08:13:26.
Track [ CRC ] Status
01 [00000000] (00/00) No matches
02 [00000000] (00/32) No matches
03 [00000000] (00/32) No matches
04 [00000000] (00/32) No matches
Track [ CRC32 ] [W/O NULL]
-- [A5DC303C] [00000000] W/O NULL
01 [705A9F3D] [00000000] W/O NULL
02 [89473925] [00000000] W/O NULL
03 [4A0E49E8] [00000000] W/O NULL
04 [5CEE4589] [00000000] W/O NULL

View File

@@ -0,0 +1,17 @@
FILE "<Filename>.iso" BINARY
TRACK 01 MODEx/2xxx
FILE "2.dummy" WAVE
TRACK 02 AUDIO
INDEX 01 00:00:00
TRACK 03 AUDIO
INDEX 00 07:17:67
FILE "3.dummy" WAVE
INDEX 01 00:00:00
TRACK 04 AUDIO
INDEX 00 06:36:38
FILE "4.dummy" WAVE
INDEX 01 00:00:00
TRACK 05 AUDIO
INDEX 00 05:57:69
FILE "5.dummy" WAVE
INDEX 01 00:00:00

View File

@@ -0,0 +1,98 @@
X Lossless Decoder version 20091114 (113.2)
XLD extraction logfile from 2009-11-14 11:55:20 +0100
Front Line Assembly / Circuitry
Used drive : PIONEER DVD-RW DVR-107D (revision 1.21)
Use cdparanoia mode : YES (CDParanoia III 10.2 engine)
Disable audio cache : OK for the drive with cache less than 2750KB
Make use of C2 pointers : NO
Read offset correction : 48
Max retry count : 100
TOC of the extracted CD
Track | Start | Length | Start sector | End sector
---------------------------------------------------------
1 | 00:00:00 | 08:13:26 | 0 | 37000
2 | 08:13:26 | 07:20:00 | 37001 | 70000
3 | 15:33:26 | 06:37:38 | 70001 | 99813
4 | 22:10:64 | 06:00:05 | 99814 | 126818
5 | 28:10:69 | 07:35:32 | 126819 | 160975
Track 02
Filename : /Volumes/Rips/02 - Circuitry (Predator Mix).flac
CRC32 hash (test run) : C5385687
CRC32 hash : C5385687
CRC32 hash (skip zero) : F3A4E7D4
AccurateRip signature : FF4A6379
->Track not present in AccurateRip database.
Statistics
Read error : 0
Skipped (treated as error) : 0
Edge jitter error (maybe fixed) : 0
Atom jitter error (maybe fixed) : 0
Drift error (maybe fixed) : 0
Dropped bytes error (maybe fixed) : 0
Duplicated bytes error (maybe fixed) : 0
Inconsistency in error sectors : 0
Track 03
Filename : /Volumes/Rips/03 - Circuitry (Biosphere Remix).flac
CRC32 hash (test run) : 2C3BF4BF
CRC32 hash : 2C3BF4BF
CRC32 hash (skip zero) : C6E44ECE
AccurateRip signature : 77C5F53E
->Track not present in AccurateRip database.
Statistics
Read error : 0
Skipped (treated as error) : 0
Edge jitter error (maybe fixed) : 0
Atom jitter error (maybe fixed) : 0
Drift error (maybe fixed) : 0
Dropped bytes error (maybe fixed) : 0
Duplicated bytes error (maybe fixed) : 0
Inconsistency in error sectors : 0
Track 04
Filename : /Volumes/Rips/04 - Epidemic.flac
CRC32 hash (test run) : C0DB0DF0
CRC32 hash : C0DB0DF0
CRC32 hash (skip zero) : B7199FE7
AccurateRip signature : 59A983A2
->Track not present in AccurateRip database.
Statistics
Read error : 0
Skipped (treated as error) : 0
Edge jitter error (maybe fixed) : 0
Atom jitter error (maybe fixed) : 0
Drift error (maybe fixed) : 0
Dropped bytes error (maybe fixed) : 0
Duplicated bytes error (maybe fixed) : 0
Inconsistency in error sectors : 0
Track 05
Filename : /Volumes/Rips/05 - Circuitry (Complexity Remix).flac
CRC32 hash (test run) : FCA0EC8C
CRC32 hash : FCA0EC8C
CRC32 hash (skip zero) : 6C5446CA
AccurateRip signature : 96CAD6B0
->Track not present in AccurateRip database.
Statistics
Read error : 0
Skipped (treated as error) : 0
Edge jitter error (maybe fixed) : 0
Atom jitter error (maybe fixed) : 0
Drift error (maybe fixed) : 0
Dropped bytes error (maybe fixed) : 0
Duplicated bytes error (maybe fixed) : 0
Inconsistency in error sectors : 0
No errors occurred
End of status report

View File

@@ -0,0 +1 @@
07:20:00

View File

@@ -0,0 +1 @@
06:37:38

View File

@@ -0,0 +1 @@
06:00:05

View File

@@ -0,0 +1 @@
07:35:32

View File

@@ -0,0 +1,31 @@
[Verification date: 04.02.2010 1:34:37]
[Disc ID: 0015c42c-00d1e13f-ba0fe50d]
CD-Extra data track length 13:55:74.
Track [ CRC ] Status
01 [00000000] (00/03) No matches
02 [00000000] (00/03) No matches
03 [00000000] (00/03) No matches
04 [00000000] (00/02) No matches
05 [00000000] (00/02) No matches
06 [00000000] (00/02) No matches
07 [00000000] (00/02) No matches
08 [00000000] (00/02) No matches
09 [00000000] (00/00) No matches
10 [00000000] (00/02) No matches
11 [00000000] (00/02) No matches
12 [00000000] (00/02) No matches
Track [ CRC32 ] [W/O NULL] [ LOG ]
-- [C5B12F88] [00000000] [BFBC4E1C]
01 [E86DE3AB] [00000000] W/O NULL
02 [98304860] [00000000] W/O NULL
03 [E9634AD8] [00000000] W/O NULL
04 [D3E70791] [00000000] W/O NULL
05 [68EF5945] [00000000] W/O NULL
06 [BF93EF61] [00000000] W/O NULL
07 [054B4E84] [00000000] W/O NULL
08 [C6B1650A] [00000000] W/O NULL
09 [30B49D56] [00000000] W/O NULL
10 [E31612F7] [00000000] W/O NULL
11 [C084D129] [00000000] W/O NULL
12 [012CDBF0] [00000000] W/O NULL

View File

@@ -0,0 +1,36 @@
REM DISCID BA0FE50D
FILE "1.dummy" WAVE
TRACK 01 AUDIO
INDEX 01 00:00:00
TRACK 02 AUDIO
INDEX 00 03:57:70
INDEX 01 03:58:08
TRACK 03 AUDIO
INDEX 00 07:37:50
INDEX 01 07:37:55
TRACK 04 AUDIO
INDEX 00 11:01:64
INDEX 01 11:02:39
TRACK 05 AUDIO
INDEX 01 14:32:67
TRACK 06 AUDIO
INDEX 00 18:09:37
INDEX 01 18:10:02
TRACK 07 AUDIO
INDEX 00 21:23:29
INDEX 01 21:23:48
TRACK 08 AUDIO
INDEX 00 26:19:05
INDEX 01 26:20:08
TRACK 09 AUDIO
INDEX 00 30:07:64
INDEX 01 30:07:73
TRACK 10 AUDIO
INDEX 00 33:47:23
INDEX 01 33:47:49
TRACK 11 AUDIO
INDEX 00 37:20:03
INDEX 01 37:21:18
TRACK 12 AUDIO
INDEX 00 44:45:71
INDEX 01 44:47:60

View File

@@ -0,0 +1 @@
51:22:00

View File

@@ -0,0 +1,57 @@
Exact Audio Copy V0.99 prebeta 4 from 23. January 2008
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> EAC <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2008, 11:04
Waldo's People / No-Man's-Land
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: HL-DT-STDVDRAM GSA-H10N Adapter: 0 ID: 0
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <20><>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> : <20><>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> C2 : <20><><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : 667
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Lead-in <20> Lead-out : <20><><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <20><>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> : <20><><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CRC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <20><>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ASPI-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WAV-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : 44.100 <20><>; 16 <20><><EFBFBD>; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TOC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CD
<20><><EFBFBD><EFBFBD> | <20><><EFBFBD><EFBFBD><EFBFBD> | <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
---------------------------------------------------------------------
1 | 0:00.00 | 3:58.08 | 0 | 17857
2 | 3:58.08 | 3:39.47 | 17858 | 34329
3 | 7:37.55 | 3:24.59 | 34330 | 49688
4 | 11:02.39 | 3:30.28 | 49689 | 65466
5 | 14:32.67 | 3:37.10 | 65467 | 81751
6 | 18:10.02 | 3:13.46 | 81752 | 96272
7 | 21:23.48 | 4:56.35 | 96273 | 118507
8 | 26:20.08 | 3:47.65 | 118508 | 135597
9 | 30:07.73 | 3:39.51 | 135598 | 152073
10 | 33:47.49 | 3:33.44 | 152074 | 168092
11 | 37:21.18 | 7:26.42 | 168093 | 201584
12 | 44:47.60 | 6:34.15 | 201585 | 231149
13 | 53:54.00 | 13:55.74 | 242550 | 305248
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> D:\Eurodance Uncompress\Waldo's People - No-Man's-Land (CD-Extra) (2000-APE)\Waldo's People - No-Man's-Land.wav
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 98.7 %
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 100.0 %
CRC <20><><EFBFBD><EFBFBD><EFBFBD> BFBC4E1C
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>... OK
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>