diff --git a/CUETools.AccurateRip/AccurateRip.cs b/CUETools.AccurateRip/AccurateRip.cs index d24ab1a..cfdbd80 100644 --- a/CUETools.AccurateRip/AccurateRip.cs +++ b/CUETools.AccurateRip/AccurateRip.cs @@ -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,7 +284,27 @@ 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; - crc = _crc32.Combine(crc, _offsetedCRC32[iTrack, 10 * 588 - 1], trackLength); + 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; } @@ -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 _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; diff --git a/CUETools.Codecs/CRCs/CRC32.cs b/CUETools.Codecs/CRCs/CRC32.cs index db4f876..f352e19 100644 --- a/CUETools.Codecs/CRCs/CRC32.cs +++ b/CUETools.Codecs/CRCs/CRC32.cs @@ -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; diff --git a/CUETools/CUETools.TestCodecs/AccurateRipTest.cs b/CUETools/CUETools.TestCodecs/AccurateRipTest.cs index d744785..72092cd 100644 --- a/CUETools/CUETools.TestCodecs/AccurateRipTest.cs +++ b/CUETools/CUETools.TestCodecs/AccurateRipTest.cs @@ -20,8 +20,6 @@ namespace CUETools.TestCodecs private TestContext testContextInstance; - private int[,] testSamples = new int[,] { { 0, 0 }, { -2, -3 }, { 32767, 32766 }, { -32765, -32764 } }; - /// ///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(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(crc2, crc5, "CRC32 was not combined correctly."); - uint crc6 = crc2 ^ crc32.Combine(crc3, 0, buff.ByteLength - 7); - Assert.AreEqual(crc4, crc6, "CRC32 was not substracted correctly."); - Assert.AreEqual(3856971150, target.CRC32(0), "CRC32 was not set correctly."); - Assert.AreEqual(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(3762425816, target.CRC(0), "CRC[0] was not set correctly."); + Assert.AreEqual(3103217968, target.CRC(1), "CRC[1] was not set correctly."); + Assert.AreEqual(3206462296, target.CRC(1, 11), "CRC[1][11] was not set correctly."); + Assert.AreEqual(3068174852, target.CRC(2), "CRC[2] was not set correctly."); + Assert.AreEqual(3233779629, target.CRC32(0), "CRC32[0] was not set correctly."); + Assert.AreEqual(3753760724, target.CRC32(0, 13), "CRC32[0][13] was not set correctly."); + Assert.AreEqual(3153592639, target.CRC32(0, -7), "CRC32[0][-7] was not set correctly."); + Assert.AreEqual(0408974480, target.CRC32(1), "CRC32[1] was not set correctly."); + Assert.AreEqual(4123211700, target.CRC32(2), "CRC32[2] was not set correctly."); + Assert.AreEqual(0297562037, target.CRC32(2, 15), "CRC32[2][15] was not set correctly."); + Assert.AreEqual(0398293317, target.CRC32(2, -1), "CRC32[2][-1] was not set correctly."); + Assert.AreEqual(0564210909, target.CRC32(3), "CRC32[3] was not set correctly."); + Assert.AreEqual(2395016718, target.CRCWONULL(0), "CRC32WONULL[0] was not set correctly."); + Assert.AreEqual(0834934371, target.CRCWONULL(1), "CRC32WONULL[1] was not set correctly."); + Assert.AreEqual(4123211700, target.CRCWONULL(2), "CRC32WONULL[2] was not set correctly."); + Assert.AreEqual(0062860870, target.CRCWONULL(2, 19), "CRC32WONULL[2][19] was not set correctly."); + Assert.AreEqual(0950746738, target.CRCWONULL(2, -2), "CRC32WONULL[2][-2] was not set correctly."); + Assert.AreEqual(0564210909, target.CRCWONULL(3), "CRC32WONULL[3] was not set correctly."); } } diff --git a/CUETools/CUETools.TestCodecs/CUETools.TestCodecs.csproj b/CUETools/CUETools.TestCodecs/CUETools.TestCodecs.csproj index 8405440..74a1ffd 100644 --- a/CUETools/CUETools.TestCodecs/CUETools.TestCodecs.csproj +++ b/CUETools/CUETools.TestCodecs/CUETools.TestCodecs.csproj @@ -40,6 +40,7 @@ + diff --git a/CUETools/CUETools.TestCodecs/Crc32Test.cs b/CUETools/CUETools.TestCodecs/Crc32Test.cs new file mode 100644 index 0000000..76c32e0 --- /dev/null +++ b/CUETools/CUETools.TestCodecs/Crc32Test.cs @@ -0,0 +1,94 @@ +using CUETools.Codecs; +using Microsoft.VisualStudio.TestTools.UnitTesting; +namespace CUETools.TestCodecs +{ + + + /// + ///This is a test class for Crc32Test and is intended + ///to contain all Crc32Test Unit Tests + /// + [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; + + /// + ///Gets or sets the test context which provides + ///information about and functionality for the current test run. + /// + 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 + + + /// + ///A test for Combine + /// + [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(crcAB, crc32.Combine(crcA, crcB, lenB), "CRC32 was not combined correctly."); + Assert.AreEqual(crcB, crc32.Combine(crcA, crcAB, lenB), "CRC32 was not substracted correctly."); + } + + /// + ///A test for ComputeChecksum + /// + [TestMethod()] + public void ComputeChecksumTest() + { + Crc32 crc32 = new Crc32(); + uint actual = crc32.ComputeChecksum(0xffffffff, testBytes, 0, testBytes.Length) ^ 0xffffffff; + Assert.AreEqual(2028688632, actual, "CRC32 was not combined correctly."); + } + } +} diff --git a/CUETools/CUETools.TestProcessor/CUETools.TestProcessor.csproj b/CUETools/CUETools.TestProcessor/CUETools.TestProcessor.csproj new file mode 100644 index 0000000..c87f2a0 --- /dev/null +++ b/CUETools/CUETools.TestProcessor/CUETools.TestProcessor.csproj @@ -0,0 +1,76 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {A430AD28-B76A-4ED0-AF7D-D13B8969297F} + Library + CUETools.TestProcessor + CUETools.TestProcessor + 4 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + 2.0 + + + + + true + full + false + .\bin\Debug\ + DEBUG;TRACE + + + false + true + ..\bin\Release\ + TRACE + + + + False + ..\..\CUETools.Processor\CSScriptLibrary.v1.1.dll + + + + + + + + + + + + + + + {5802C7E9-157E-4124-946D-70B5AE48A5A1} + CUETools.AccurateRip + + + {1DD41038-D885-46C5-8DDE-E0B82F066584} + CUETools.CDImage + + + {6458A13A-30EF-45A9-9D58-E5031B17BEE2} + CUETools.Codecs + + + {4911BD82-49EF-4858-8B51-5394F86739A4} + CUETools.Processor + + + {5ADCFD6D-BFEA-4B10-BB45-9083BBB56AF4} + Freedb + + + {74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533} + MusicBrainz + + + + \ No newline at end of file diff --git a/CUETools/CUETools.TestProcessor/ProcessorTest.cs b/CUETools/CUETools.TestProcessor/ProcessorTest.cs new file mode 100644 index 0000000..02118dd --- /dev/null +++ b/CUETools/CUETools.TestProcessor/ProcessorTest.cs @@ -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 +{ + /// + ///This is a test class for CUETools.Processor.CUESheet and is intended + ///to contain all CUETools.Processor.CUESheet Unit Tests + /// + [TestClass()] + public class CUESheetTest + { + + + private TestContext testContextInstance; + + /// + ///Gets or sets the test context which provides + ///information about and functionality for the current test run. + /// + 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 + + + /// + ///A test for Open (string) + /// + [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("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("0015c42c-00d1e13f-ba0fe50d", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC"); + + // test one-track CD + target = new CUESheet(config); + target.Open("Amarok\\Amarok.cue"); + Assert.AreEqual("00041f6d-00083ece-020e1201", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC"); + } + + } + + +} diff --git a/CUETools/CUETools.TestProcessor/Properties/AssemblyInfo.cs b/CUETools/CUETools.TestProcessor/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4c763af --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Properties/AssemblyInfo.cs @@ -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")] diff --git a/CUETools/CUETools.TestProcessor/Test Images/Amarok/Amarok.cue b/CUETools/CUETools.TestProcessor/Test Images/Amarok/Amarok.cue new file mode 100644 index 0000000..c5b1219 --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/Amarok/Amarok.cue @@ -0,0 +1,5 @@ +REM DISCID 020E1201 +FILE "Amarok.dummy" WAVE + TRACK 01 AUDIO + INDEX 00 00:00:00 + INDEX 01 00:00:12 diff --git a/CUETools/CUETools.TestProcessor/Test Images/Amarok/Amarok.dummy b/CUETools/CUETools.TestProcessor/Test Images/Amarok/Amarok.dummy new file mode 100644 index 0000000..5182bf1 --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/Amarok/Amarok.dummy @@ -0,0 +1 @@ +60:02:27 \ No newline at end of file diff --git a/CUETools/CUETools.TestProcessor/Test Images/Circuitry/1.accurip b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/1.accurip new file mode 100644 index 0000000..daa926d --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/1.accurip @@ -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 diff --git a/CUETools/CUETools.TestProcessor/Test Images/Circuitry/1.cue b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/1.cue new file mode 100644 index 0000000..2283a36 --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/1.cue @@ -0,0 +1,17 @@ +FILE ".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 diff --git a/CUETools/CUETools.TestProcessor/Test Images/Circuitry/1.log b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/1.log new file mode 100644 index 0000000..812560b --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/1.log @@ -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 diff --git a/CUETools/CUETools.TestProcessor/Test Images/Circuitry/2.dummy b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/2.dummy new file mode 100644 index 0000000..22265fd --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/2.dummy @@ -0,0 +1 @@ +07:20:00 \ No newline at end of file diff --git a/CUETools/CUETools.TestProcessor/Test Images/Circuitry/3.dummy b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/3.dummy new file mode 100644 index 0000000..258715d --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/3.dummy @@ -0,0 +1 @@ +06:37:38 \ No newline at end of file diff --git a/CUETools/CUETools.TestProcessor/Test Images/Circuitry/4.dummy b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/4.dummy new file mode 100644 index 0000000..f5adcbd --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/4.dummy @@ -0,0 +1 @@ +06:00:05 \ No newline at end of file diff --git a/CUETools/CUETools.TestProcessor/Test Images/Circuitry/5.dummy b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/5.dummy new file mode 100644 index 0000000..a5b7a75 --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/Circuitry/5.dummy @@ -0,0 +1 @@ +07:35:32 \ No newline at end of file diff --git a/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.accurip b/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.accurip new file mode 100644 index 0000000..68aaf2b --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.accurip @@ -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 diff --git a/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.cue b/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.cue new file mode 100644 index 0000000..7a072f5 --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.cue @@ -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 diff --git a/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.dummy b/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.dummy new file mode 100644 index 0000000..b09c7cf --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.dummy @@ -0,0 +1 @@ +51:22:00 \ No newline at end of file diff --git a/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.log b/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.log new file mode 100644 index 0000000..419dc07 --- /dev/null +++ b/CUETools/CUETools.TestProcessor/Test Images/No Man's Land/1.log @@ -0,0 +1,57 @@ +Exact Audio Copy V0.99 prebeta 4 from 23. January 2008 + +Îò÷¸ò EAC îá èçâëå÷åíèè, âûïîëíåííîì 3. îêòÿáðÿ 2008, 11:04 + +Waldo's People / No-Man's-Land + +Äèñêîâîä: HL-DT-STDVDRAM GSA-H10N Adapter: 0 ID: 0 + +Ðåæèì ÷òåíèÿ : Äîñòîâåðíîñòü +Èñïîëüçîâàíèå òî÷íîãî ïîòîêà : Äà +Îòêëþ÷åíèå êýøà àóäèî : Äà +Èñïîëüçîâàíèå óêàçàòåëåé C2 : Íåò + +Êîððåêöèÿ ñìåùåíèÿ ïðè ÷òåíèè : 667 +Ñïîñîáíîñòü ÷èòàòü îáëàñòè Lead-in è Lead-out : Íåò +Çàïîëíåíèå ïðîïóùåííûõ ñýìïëîâ òèøèíîé : Äà +Óäàëåíèå áëîêîâ ñ òèøèíîé â íà÷àëå è êîíöå : Íåò +Ïðè âû÷èñëåíèÿõ CRC èñïîëüçîâàëèñü íóëåâûå ñýìïëû : Äà +Èíòåðôåéñ : Óñòàíîâëåííûé âíåøíèé ASPI-èíòåðôåéñ + +Âûõîäíîé ôîðìàò : Âíóòðåííèå WAV-îïåðàöèè +Ôîðìàò ñýìïëîâ : 44.100 Ãö; 16 áèò; ñòåðåî + + +TOC èçâëå÷¸ííîãî CD + + Òðåê | Ñòàðò | Äëèòåëüíîñòü | Íà÷àëüíûé ñåêòîð | Êîíå÷íûé ñåêòîð + --------------------------------------------------------------------- + 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 + + +Õàðàêòåðèñòèêè äèàïàçîíà èçâëå÷åíèÿ è ñîîáùåíèÿ îá îøèáêàõ + +Âûáðàííûé äèàïàçîí + + Èìÿ ôàéëà D:\Eurodance Uncompress\Waldo's People - No-Man's-Land (CD-Extra) (2000-APE)\Waldo's People - No-Man's-Land.wav + + Ïèêîâûé óðîâåíü 98.7 % + Êà÷åñòâî äèàïàçîíà 100.0 % + CRC êîïèè BFBC4E1C + Êîïèðîâàíèå... OK + +Îøèáîê íå ïðîèçîøëî + +Êîíåö îò÷¸òà