From 3f717d14c8100cb7c87e1775b5451a9c00c5d57e Mon Sep 17 00:00:00 2001 From: chudov Date: Fri, 23 Apr 2010 19:59:42 +0000 Subject: [PATCH] Optimizing verification --- CUETools.AccurateRip/AccurateRip.cs | 407 +++- CUETools.CDRepair/CDRepair.cs | 329 +-- CUETools.CDRepair/CUETools.CDRepair.csproj | 8 + CUETools.CTDB/CUETools.CTDB.csproj | 4 + CUETools.CTDB/CUEToolsDB.cs | 5 +- CUETools.Codecs/CRCs/CRC32.cs | 188 +- CUETools.Codecs/Codecs.cs | 2 +- CUETools.Processor/Processor.cs | 376 ++-- CUETools/CUETools.TestCodecs/Crc32Test.cs | 15 +- .../CUETools.TestParity/CDRepairDecodeTest.cs | 39 +- .../CUETools.TestParity/CDRepairEncodeTest.cs | 10 +- CUETools/CUETools.TestParity/CDRepairTest.cs | 19 +- .../CUETools.TestParity.csproj | 11 +- CUETools/frmBatch.Designer.cs | 32 +- CUETools/frmBatch.cs | 12 +- CUETools/frmCUETools.Designer.cs | 10 - CUETools/frmCUETools.cs | 33 +- CUETools/frmCUETools.resx | 1997 ++++++++++------- 18 files changed, 2192 insertions(+), 1305 deletions(-) diff --git a/CUETools.AccurateRip/AccurateRip.cs b/CUETools.AccurateRip/AccurateRip.cs index 8d96c2d..bf9931e 100644 --- a/CUETools.AccurateRip/AccurateRip.cs +++ b/CUETools.AccurateRip/AccurateRip.cs @@ -16,11 +16,13 @@ namespace CUETools.AccurateRip this.proxy = proxy; _toc = toc; _accDisks = new List(); - _crc32 = new Crc32(); + //_crc32 = new Crc32(); _hasLogCRC = false; _CRCLOG = new uint[_toc.AudioTracks + 1]; - for (int i = 0; i <= _toc.AudioTracks; i++) - _CRCLOG[i] = 0; + _CRCMASK = new uint[_toc.AudioTracks + 1]; + _CRCMASK[0] = 0xffffffff ^ Crc32.Combine(0xffffffff, 0, (int)_toc.AudioLength * 588 * 4); + for (int iTrack = 1; iTrack <= _toc.AudioTracks; iTrack++) + _CRCMASK[iTrack] = 0xffffffff ^ Crc32.Combine(0xffffffff, 0, (int)_toc[iTrack + _toc.FirstAudio - 1].Length * 588 * 4); Init(); } @@ -160,39 +162,50 @@ namespace CUETools.AccurateRip return CRC32(iTrack, 0); } + public uint GetCRC32(uint crcA, int lenA, uint crcB, int lenB) + { + int lenAXB = (int)_toc.AudioLength * 588 * 4; + int lenXB = lenAXB - lenA; + int lenX = lenXB - lenB; + uint crcAXB = CRC32(0, 0) ^ _CRCMASK[0]; + uint crcXB = Crc32.Combine(crcA, crcAXB, lenXB); + uint crcX = Crc32.Substract(crcXB, crcB, lenB); + return Crc32.Combine(0xffffffff, crcX, lenX) ^ 0xffffffff; + } + public uint CRC32(int iTrack, int oi) { if (_CacheCRC32[iTrack, _arOffsetRange + oi] == 0) { - uint crc = 0xffffffff; + uint crc = 0; 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; if (oi < 0 && iTrack == 0) - crc = _crc32.Combine(crc, 0, -oi * 4); + 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(_CRC32[iTrack, oi], _CRC32[iTrack, 0], trackLength - oi * 4); - // Use 0xffffffff as an initial state - crc = _crc32.Combine(0xffffffff, crc, trackLength - oi * 4); + crc = Crc32.Combine(_CRC32[iTrack, oi], _CRC32[iTrack, 0], trackLength - oi * 4); } else if (oi < 0 && iTrack == _toc.AudioTracks) { - crc = _crc32.Combine(crc, _CRC32[iTrack, 20 * 588 + oi], trackLength + oi * 4); + crc = Crc32.Combine(crc, _CRC32[iTrack, 20 * 588 + oi], trackLength + oi * 4); } else { - crc = _crc32.Combine(crc, _CRC32[iTrack, 0], trackLength); + crc = Crc32.Combine(crc, _CRC32[iTrack, 0], trackLength); } if (oi > 0 && iTrack == _toc.AudioTracks) - crc = _crc32.Combine(crc, 0, oi * 4); + crc = Crc32.Combine(crc, 0, oi * 4); } iTrack = 0; + // Use 0xffffffff as an initial state + crc ^= _CRCMASK[0]; } else { @@ -200,31 +213,27 @@ namespace CUETools.AccurateRip if (oi > 0) { // Calculate track CRC skipping first oi samples by 'subtracting' their CRC - crc = _crc32.Combine(_CRC32[iTrack, oi], _CRC32[iTrack, 0], trackLength - oi * 4); - // Use 0xffffffff as an initial state - crc = _crc32.Combine(0xffffffff, crc, trackLength - oi * 4); + crc = Crc32.Combine(_CRC32[iTrack, oi], _CRC32[iTrack, 0], trackLength - oi * 4); // Add oi samples from next track CRC + crc = Crc32.Combine(crc, 0, oi * 4); if (iTrack < _toc.AudioTracks) - crc = _crc32.Combine(crc, _CRC32[iTrack + 1, oi], oi * 4); - else - crc = _crc32.Combine(crc, 0, oi * 4); + crc ^= _CRC32[iTrack + 1, oi]; } else if (oi < 0) { // Calculate CRC of previous track's last oi samples by 'subtracting' it's last CRCs - crc = _crc32.Combine(_CRC32[iTrack - 1, 20 * 588 + oi], _CRC32[iTrack - 1, 0], -oi * 4); - // Use 0xffffffff as an initial state - crc = _crc32.Combine(0xffffffff, crc, -oi * 4); + crc = Crc32.Combine(_CRC32[iTrack - 1, 20 * 588 + oi], _CRC32[iTrack - 1, 0], -oi * 4); // Add this track's CRC without last oi samples - crc = _crc32.Combine(crc, _CRC32[iTrack, 20 * 588 + oi], trackLength + oi * 4); + crc = Crc32.Combine(crc, _CRC32[iTrack, 20 * 588 + oi], trackLength + oi * 4); } else // oi == 0 { - // Use 0xffffffff as an initial state - crc = _crc32.Combine(0xffffffff, _CRC32[iTrack, 0], trackLength); + crc = _CRC32[iTrack, 0]; } + // Use 0xffffffff as an initial state + crc ^= _CRCMASK[iTrack]; } - _CacheCRC32[iTrack, _arOffsetRange + oi] = crc ^ 0xffffffff; + _CacheCRC32[iTrack, _arOffsetRange + oi] = crc; } return _CacheCRC32[iTrack, _arOffsetRange + oi]; } @@ -245,7 +254,7 @@ namespace CUETools.AccurateRip { int trackLength = (int)(iTrack > 0 ? _toc[iTrack + _toc.FirstAudio - 1].Length : _toc[_toc.FirstAudio].Pregap) * 588 * 4 - _CRCNL[iTrack, 0] * 2; - crc = _crc32.Combine(crc, _CRCWN[iTrack, 0], trackLength); + crc = Crc32.Combine(crc, _CRCWN[iTrack, 0], trackLength); } iTrack = 0; } @@ -257,15 +266,15 @@ namespace CUETools.AccurateRip int nonzeroPrevLength = trackLength - oi * 4 - (_CRCNL[iTrack, 0] - _CRCNL[iTrack, oi]) * 2; // Calculate track CRC skipping first oi samples by 'subtracting' their CRC - crc = _crc32.Combine( + crc = Crc32.Combine( _CRCWN[iTrack, oi], _CRCWN[iTrack, 0], nonzeroPrevLength); // Use 0xffffffff as an initial state - crc = _crc32.Combine(0xffffffff, crc, nonzeroPrevLength); + crc = Crc32.Combine(0xffffffff, crc, nonzeroPrevLength); // Add oi samples from next track CRC if (iTrack < _toc.AudioTracks) - crc = _crc32.Combine(crc, + crc = Crc32.Combine(crc, _CRCWN[iTrack + 1, oi], oi * 4 - _CRCNL[iTrack + 1, oi] * 2); } @@ -274,21 +283,21 @@ namespace CUETools.AccurateRip int nonzeroPrevLength = -oi * 4 - (_CRCNL[iTrack - 1, 0] - _CRCNL[iTrack - 1, 20 * 588 + oi]) * 2; // Calculate CRC of previous track's last oi samples by 'subtracting' it's last CRCs - crc = _crc32.Combine( + crc = Crc32.Combine( _CRCWN[iTrack - 1, 20 * 588 + oi], _CRCWN[iTrack - 1, 0], nonzeroPrevLength); // Use 0xffffffff as an initial state - crc = _crc32.Combine(0xffffffff, crc, nonzeroPrevLength); + crc = Crc32.Combine(0xffffffff, crc, nonzeroPrevLength); // Add this track's CRC without last oi samples - crc = _crc32.Combine(crc, + crc = Crc32.Combine(crc, _CRCWN[iTrack, 20 * 588 + oi], trackLength + oi * 4 - _CRCNL[iTrack, 20 * 588 + oi] * 2); } else // oi == 0 { // Use 0xffffffff as an initial state - crc = _crc32.Combine(0xffffffff, _CRCWN[iTrack, 0], trackLength - _CRCNL[iTrack, 0] * 2); + crc = Crc32.Combine(0xffffffff, _CRCWN[iTrack, 0], trackLength - _CRCNL[iTrack, 0] * 2); } } _CacheCRCWN[iTrack, _arOffsetRange + oi] = crc ^ 0xffffffff; @@ -307,6 +316,85 @@ namespace CUETools.AccurateRip _CRCLOG[iTrack] = value; } + private ushort[,] syndrome = new ushort[1,1]; + private byte[] parity = new byte[1]; + private ushort[] expTbl = new ushort[1]; + private ushort[] logTbl = new ushort[1]; + private int stride = 1, stridecount, npar; + private bool calcSyn = false; + private bool calcParity = false; + + public void CalcSyndrome(ushort[] expTbl, ushort[] logTbl, ushort[,] syndrome, byte[] parity, int stride, int stridecount, int npar, bool calcParity, bool calcSyn) + { + if (npar != 8) + throw new NotSupportedException(); + this.syndrome = syndrome; + this.parity = parity; + this.logTbl = logTbl; + this.expTbl = expTbl; + this.stride = stride; + this.stridecount = stridecount; + this.npar = npar; + this.calcSyn = calcSyn; + this.calcParity = calcParity; + } + + private unsafe static void CalcSyn8(ushort* exp, ushort* log, ushort* syn, uint lo, uint n) + { + syn[0] ^= (ushort)lo; + uint idx = log[lo] + n; syn[1] ^= exp[(idx & 0xffff) + (idx >> 16)]; + idx += n; syn[2] ^= exp[(idx & 0xffff) + (idx >> 16)]; + idx += n; syn[3] ^= exp[(idx & 0xffff) + (idx >> 16)]; + idx += n; syn[4] ^= exp[(idx & 0xffff) + (idx >> 16)]; + idx += n; syn[5] ^= exp[(idx & 0xffff) + (idx >> 16)]; + idx += n; syn[6] ^= exp[(idx & 0xffff) + (idx >> 16)]; + idx += n; syn[7] ^= exp[(idx & 0xffff) + (idx >> 16)]; + } + +#if alternateSynCalc + private unsafe static void CalcSyn8Alt(ushort* exp, ushort* log, ushort* syn, uint lo, uint n) + { + uint idx = log[lo] + 7 * n; + ulong x = exp[(idx & 0xffff) + (idx >> 16)]; + x <<= 16; idx -= n; x ^= exp[(idx & 0xffff) + (idx >> 16)]; + x <<= 16; idx -= n; x ^= exp[(idx & 0xffff) + (idx >> 16)]; + x <<= 16; idx -= n; x ^= exp[(idx & 0xffff) + (idx >> 16)]; + ((ulong*)syn)[1] ^= x; + idx -= n; x = exp[(idx & 0xffff) + (idx >> 16)]; + x <<= 16; idx -= n; x ^= exp[(idx & 0xffff) + (idx >> 16)]; + x <<= 16; idx -= n; x ^= exp[(idx & 0xffff) + (idx >> 16)]; + ((ulong*)syn)[0] ^= (x << 16) + lo; + } +#endif + + private unsafe static void CalcPar8(ushort* exp, ushort* log, ushort* wr, uint lo) + { + uint ib = wr[0] ^ lo; + if (ib != 0) + { + ushort* myexp = exp + log[ib]; + wr[0] = (ushort)(wr[1] ^ myexp[19483]); + wr[1] = (ushort)(wr[2] ^ myexp[41576]); + wr[2] = (ushort)(wr[3] ^ myexp[9460]); + wr[3] = (ushort)(wr[4] ^ myexp[52075]); + wr[4] = (ushort)(wr[5] ^ myexp[9467]); + wr[5] = (ushort)(wr[6] ^ myexp[41590]); + wr[6] = (ushort)(wr[7] ^ myexp[19504]); + wr[7] = myexp[28]; + } + else + { + wr[0] = wr[1]; + wr[1] = wr[2]; + wr[2] = wr[3]; + wr[3] = wr[4]; + wr[4] = wr[5]; + wr[5] = wr[6]; + wr[6] = wr[7]; + wr[7] = 0; + } + } + /// /// This function calculates three different CRCs and also /// collects some additional information for the purposes of @@ -322,57 +410,66 @@ namespace CUETools.AccurateRip /// /// /// - public unsafe void CalculateCRCs(uint* pSampleBuff, int count, int currentOffset, int offs) + public unsafe void CalculateCRCs(uint* t, ushort* exp, ushort* log, ushort* syn, ushort* wr, uint* pSampleBuff, int count, int currentOffset, int offs) { + int currentStride = ((int)_sampleCount * 2) / stride; + bool doSyn = currentStride >= 1 && currentStride <= stridecount && calcSyn; + bool doPar = currentStride >= 1 && currentStride <= stridecount && calcParity; + uint n = (uint)(stridecount - currentStride); + uint crcar = _CRCAR[_currentTrack, 0]; uint crcsm = _CRCSM[_currentTrack, 0]; uint crc32 = _CRC32[_currentTrack, 0]; uint crcwn = _CRCWN[_currentTrack, 0]; int crcnl = _CRCNL[_currentTrack, 0]; int peak = _Peak[_currentTrack]; - fixed (uint* t = _crc32.table) + //fixed (ushort* exp = expTbl, log = logTbl, synptr = syndrome) + for (int i = 0; i < count; i++) { - for (int i = 0; i < count; i++) + if (offs >= 0) { - if (offs >= 0) - { - _CRCAR[_currentTrack, offs + i] = crcar; - _CRCSM[_currentTrack, offs + i] = crcsm; - _CRC32[_currentTrack, offs + i] = crc32; - _CRCWN[_currentTrack, offs + i] = crcwn; - _CRCNL[_currentTrack, offs + i] = crcnl; - } - - uint sample = *(pSampleBuff++); - crcsm += sample; - crcar += sample * (uint)(currentOffset + i + 1); - - uint lo = sample & 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 crcnl++; - - int pk = ((int)(lo << 16)) >> 16; - peak = Math.Max(peak, (pk << 1) ^ (pk >> 31)); - - uint hi = sample >> 16; - 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 crcnl++; - - pk = ((int)(hi << 16)) >> 16; - peak = Math.Max(peak, (pk << 1) ^ (pk >> 31)); + _CRCAR[_currentTrack, offs + i] = crcar; + _CRCSM[_currentTrack, offs + i] = crcsm; + _CRC32[_currentTrack, offs + i] = crc32; + _CRCWN[_currentTrack, offs + i] = crcwn; + _CRCNL[_currentTrack, offs + i] = crcnl; } + + uint sample = *(pSampleBuff++); + crcsm += sample; + crcar += sample * (uint)(currentOffset + i + 1); + + uint lo = sample & 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 crcnl++; + + int pk = ((int)(lo << 16)) >> 16; + peak = Math.Max(peak, (pk << 1) ^ (pk >> 31)); + + if (doSyn && lo != 0) CalcSyn8(exp, log, syn + i * 16, lo, n); + if (doPar) CalcPar8(exp, log, wr + i * 16, lo); + + uint hi = sample >> 16; + 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 crcnl++; + + pk = ((int)(hi << 16)) >> 16; + peak = Math.Max(peak, (pk << 1) ^ (pk >> 31)); + + if (doSyn && hi != 0) CalcSyn8(exp, log, syn + i * 16 + 8, hi, n); + if (doPar) CalcPar8(exp, log, wr + i * 16 + 8, hi); } _CRCAR[_currentTrack, 0] = crcar; @@ -383,39 +480,122 @@ namespace CUETools.AccurateRip _Peak[_currentTrack] = peak; } - public void Write(AudioBuffer sampleBuffer) + private long _samplesRemTrack = 0; + + public long Position + { + get + { + return _sampleCount; + } + set + { + _sampleCount = value; + int tempLocation = (int)_toc[_toc.FirstAudio][0].Start * 588; + for (int iTrack = 0; iTrack <= _toc.AudioTracks; iTrack++) + { + int tempLen = (int)(iTrack == 0 ? _toc[_toc.FirstAudio].Pregap : _toc[_toc.FirstAudio + iTrack - 1].Length) * 588; + if (tempLocation + tempLen > _sampleCount) + { + _currentTrack = iTrack; + _samplesRemTrack = tempLocation + tempLen - _sampleCount; + return; + } + tempLocation += tempLen; + } + throw new ArgumentOutOfRangeException(); + } + } + + public unsafe void Write(AudioBuffer sampleBuffer) { sampleBuffer.Prepare(this); int pos = 0; - while (pos < sampleBuffer.Length) - { - // Process no more than there is in the buffer, no more than there is in this track, and no more than up to a sector boundary. - int copyCount = Math.Min(Math.Min(sampleBuffer.Length - pos, (int)_samplesRemTrack), 588 - (int)_sampleCount % 588); - // Calculate offset within a track - int currentOffset = (int)_sampleCount - (int)(_currentTrack > 0 ? _toc[_currentTrack + _toc.FirstAudio - 1].Start * 588 : 0); - int currentSector = currentOffset / 588; - int remaingSectors = (int)(_samplesRemTrack - 1) / 588; - - unsafe + fixed (uint* t = Crc32.table) + fixed (ushort* exp = expTbl, log = logTbl, synptr1 = syndrome) + fixed (byte* pSampleBuff = &sampleBuffer.Bytes[0], bpar = parity) + while (pos < sampleBuffer.Length) { - fixed (byte* pSampleBuff = &sampleBuffer.Bytes[pos * 4]) + // Process no more than there is in the buffer, no more than there is in this track, and no more than up to a sector boundary. + int copyCount = Math.Min(Math.Min(sampleBuffer.Length - pos, (int)_samplesRemTrack), 588 - (int)_sampleCount % 588); + // Calculate offset within a track + int currentOffset = (int)_sampleCount - (int)(_currentTrack > 0 ? _toc[_currentTrack + _toc.FirstAudio - 1].Start * 588 : 0); + int currentSector = currentOffset / 588; + int remaingSectors = (int)(_samplesRemTrack - 1) / 588; + uint* samples = ((uint*)pSampleBuff) + pos; + int currentPart = ((int)_sampleCount * 2) % stride; + ushort* synptr = synptr1 + npar * currentPart; + ushort* wr = ((ushort*)bpar) + npar * currentPart; + + if (currentSector < 10) + CalculateCRCs(t, exp, log, synptr, wr, samples, copyCount, currentOffset, currentOffset); + else if (remaingSectors < 10) + CalculateCRCs(t, exp, log, synptr, wr, samples, copyCount, currentOffset, 20 * 588 - (int)_samplesRemTrack); + else if (currentSector >= 445 && currentSector <= 455) + CalculateCRCs(t, exp, log, synptr, wr, samples, copyCount, currentOffset, 20 * 588 + currentOffset - 445 * 588); + else + CalculateCRCs(t, exp, log, synptr, wr, samples, copyCount, currentOffset, -1); + + pos += copyCount; + _samplesRemTrack -= copyCount; + _sampleCount += copyCount; + + while (_samplesRemTrack <= 0) { - uint* samples = (uint*)pSampleBuff; - if (currentSector < 10) - CalculateCRCs(samples, copyCount, currentOffset, currentOffset); - else if (remaingSectors < 10) - CalculateCRCs(samples, copyCount, currentOffset, 20 * 588 - (int)_samplesRemTrack); - else if (currentSector >= 445 && currentSector <= 455) - CalculateCRCs(samples, copyCount, currentOffset, 20 * 588 + currentOffset - 445 * 588); - else - CalculateCRCs(samples, copyCount, currentOffset, -1); + if (++_currentTrack > _toc.AudioTracks) + return; + _samplesRemTrack = _toc[_currentTrack + _toc.FirstAudio - 1].Length * 588; } } - pos += copyCount; - _samplesRemTrack -= copyCount; - _sampleCount += copyCount; - CheckPosition(); + } + + public void Combine(AccurateRipVerify part, int start, int end) + { + for (int iTrack = 0; iTrack <= _toc.AudioTracks; iTrack++) + { + int tempLocation = (int) (iTrack == 0 ? _toc[_toc.FirstAudio][0].Start : _toc[_toc.FirstAudio + iTrack - 1].Start) * 588; + int tempLen = (int) (iTrack == 0 ? _toc[_toc.FirstAudio].Pregap : _toc[_toc.FirstAudio + iTrack - 1].Length) * 588; + int trStart = Math.Max(tempLocation, start); + int trEnd = Math.Min(tempLocation + tempLen, end); + if (trStart >= trEnd) + continue; + + uint crcar = _CRCAR[iTrack, 0]; + uint crcsm = _CRCSM[iTrack, 0]; + uint crc32 = _CRC32[iTrack, 0]; + uint crcwn = _CRCWN[iTrack, 0]; + int crcnl = _CRCNL[iTrack, 0]; + _CRCAR[iTrack, 0] = crcar + part._CRCAR[iTrack, 0]; + _CRCSM[iTrack, 0] = crcsm + part._CRCSM[iTrack, 0]; + _CRCNL[iTrack, 0] = crcnl + part._CRCNL[iTrack, 0]; + _CRC32[iTrack, 0] = Crc32.Combine(crc32, part._CRC32[iTrack, 0], 4 * (trEnd - trStart)); + _CRCWN[iTrack, 0] = Crc32.Combine(crcwn, part._CRCWN[iTrack, 0], 4 * (trEnd - trStart) - 2 * part._CRCNL[iTrack, 0]); + for (int i = 1; i < 31 * 588; i++) + { + int currentOffset; + if (i < 10 * 588) + { + currentOffset = tempLocation + i; + } + else if (i < 20 * 588) + { + currentOffset = tempLocation + tempLen + i - 20 * 588; + } + else + { + currentOffset = tempLocation + i - 20 * 588 + 445 * 588; + } + if (currentOffset <= trStart) + continue; + + _CRCAR[iTrack, i] = crcar + part._CRCAR[iTrack, i]; + _CRCSM[iTrack, i] = crcsm + part._CRCSM[iTrack, i]; + _CRCNL[iTrack, i] = crcnl + part._CRCNL[iTrack, i]; + _CRC32[iTrack, i] = Crc32.Combine(crc32, part._CRC32[iTrack, i], 4 * (currentOffset - trStart)); + _CRCWN[iTrack, i] = Crc32.Combine(crcwn, part._CRCWN[iTrack, i], 4 * (currentOffset - trStart) - 2 * part._CRCNL[iTrack, i]); + } + _Peak[iTrack] = Math.Max(_Peak[iTrack], part._Peak[iTrack]); } } @@ -430,19 +610,7 @@ namespace CUETools.AccurateRip _CRCNL = new int[_toc.AudioTracks + 1, 31 * 588]; _Peak = new int[_toc.AudioTracks + 1]; _currentTrack = 0; - _sampleCount = _toc[_toc.FirstAudio][0].Start * 588; - _samplesRemTrack = _toc[_toc.FirstAudio].Pregap * 588; - CheckPosition(); - } - - private void CheckPosition() - { - while (_samplesRemTrack <= 0) - { - if (++_currentTrack > _toc.AudioTracks) - return; - _samplesRemTrack = _toc[_currentTrack + _toc.FirstAudio - 1].Length * 588; - } + Position = _toc[_toc.FirstAudio][0].Start * 588; } private uint readIntLE(byte[] data, int pos) @@ -938,23 +1106,22 @@ namespace CUETools.AccurateRip } CDImageLayout _toc; - long _sampleCount, _finalSampleCount, _samplesRemTrack; + long _sampleCount, _finalSampleCount; int _currentTrack; private List _accDisks; private HttpStatusCode _accResult; - private uint[,] _CRCAR; - private uint[,] _CRCSM; - private uint[,] _CRC32; - private uint[,] _CRCWN; - private int[,] _CRCNL; + internal uint[,] _CRCAR; + internal uint[,] _CRCSM; + internal uint[,] _CRC32; + internal uint[,] _CRCWN; + internal int[,] _CRCNL; private uint[,] _CacheCRCWN; private uint[,] _CacheCRC32; - private int[] _Peak; + internal int[] _Peak; private uint[] _CRCLOG; + private uint[] _CRCMASK; private IWebProxy proxy; - Crc32 _crc32; - private bool _hasLogCRC; private const int _arOffsetRange = 5 * 588 - 1; diff --git a/CUETools.CDRepair/CDRepair.cs b/CUETools.CDRepair/CDRepair.cs index ed9300a..35816b1 100644 --- a/CUETools.CDRepair/CDRepair.cs +++ b/CUETools.CDRepair/CDRepair.cs @@ -1,8 +1,11 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Text; +using CUETools.CDImage; using CUETools.Codecs; using CUETools.Parity; +using CUETools.AccurateRip; namespace CUETools.CDRepair { @@ -12,8 +15,7 @@ namespace CUETools.CDRepair protected int finalSampleCount; protected Galois galois; protected RsDecode rs; - protected Crc32 crc32; - protected uint crc; + //protected uint crc; protected int[] encodeGx; protected int stride; protected int laststride; @@ -21,14 +23,14 @@ namespace CUETools.CDRepair protected int npar; public CDRepair(int finalSampleCount, int stride, int npar) - { + { this.npar = npar; this.stride = stride; this.finalSampleCount = finalSampleCount; sampleCount = 0; galois = Galois16.instance; rs = new RsDecode16(npar, galois); - crc32 = new Crc32(); + //crc32 = new Crc32(); //crc = 0xffffffff; encodeGx = galois.makeEncodeGxLog(npar); laststride = stride + (finalSampleCount * 2) % stride; @@ -104,14 +106,6 @@ namespace CUETools.CDRepair return npar; } } - - public uint CRC - { - get - { - return crc32.Combine(0xffffffff, crc, stride * 2 * stridecount) ^ 0xffffffff; - } - } } public class CDRepairEncode : CDRepair @@ -122,26 +116,29 @@ namespace CUETools.CDRepair protected ushort[] leadout; protected bool verify; protected bool encode; - protected uint crcA, crcB; + protected AccurateRipVerify ar; - public CDRepairEncode(int finalSampleCount, int stride, int npar, bool verify, bool encode) + public CDRepairEncode(int finalSampleCount, int stride, int npar, bool verify, bool encode, AccurateRipVerify ar) : base (finalSampleCount, stride, npar) { + this.ar = ar; this.verify = verify; this.encode = encode; parity = new byte[stride * npar * 2]; if (verify) - { syndrome = new ushort[stride, npar]; - leadin = new ushort[stride * 2]; - leadout = new ushort[stride + laststride]; - } else + else syndrome = new ushort[1, npar]; + + ar.CalcSyndrome(galois.ExpTbl, galois.LogTbl, syndrome, parity, stride, stridecount, npar, encode, verify); + + leadin = new ushort[stride * 2]; + leadout = new ushort[stride + laststride]; } private unsafe void ProcessStride(int currentStride, int currentPart, int count, ushort* data) { - fixed (uint* crct = crc32.table) + fixed (uint* crct = Crc32.table) fixed (byte* bpar = parity) fixed (ushort* exp = galois.ExpTbl, log = galois.LogTbl, synptr = syndrome) fixed (int* gx = encodeGx) @@ -152,8 +149,8 @@ namespace CUETools.CDRepair ushort* wr = ((ushort*)par) + part * npar; ushort dd = data[pos]; - crc = (crc >> 8) ^ crct[(byte)(crc ^ dd)]; - crc = (crc >> 8) ^ crct[(byte)(crc ^ (dd >> 8))]; + //crc = (crc >> 8) ^ crct[(byte)(crc ^ dd)]; + //crc = (crc >> 8) ^ crct[(byte)(crc ^ (dd >> 8))]; if (verify) { @@ -180,70 +177,68 @@ namespace CUETools.CDRepair } } - private unsafe void ProcessStride8(int currentStride, int currentPart, int count, ushort* data) - { - fixed (uint* crct = crc32.table) - fixed (byte* bpar = parity) - fixed (ushort* exp = galois.ExpTbl, log = galois.LogTbl, synptr = syndrome) - for (int pos = 0; pos < count; pos++) - { - ushort* par = (ushort*)bpar; - int part = currentPart + pos; - ushort* wr = par + part * 8; - ushort dd = data[pos]; + //private unsafe void ProcessStride8(int currentStride, int currentPart, int count, ushort* data, byte* bpar, ushort* synptr, ushort* exp, ushort* log) + //{ + // int n = stridecount - currentStride; - crc = (crc >> 8) ^ crct[(byte)(crc ^ dd)]; - crc = (crc >> 8) ^ crct[(byte)(crc ^ (dd >> 8))]; + // for (int pos = 0; pos < count; pos++) + // { + // int part = currentPart + pos; + // ushort dd = data[pos]; - if (encode) - { - int ib = wr[0] ^ dd; - if (ib != 0) - { - ushort* myexp = exp + log[ib]; - wr[0] = (ushort)(wr[1] ^ myexp[19483]); - wr[1] = (ushort)(wr[2] ^ myexp[41576]); - wr[2] = (ushort)(wr[3] ^ myexp[9460]); - wr[3] = (ushort)(wr[4] ^ myexp[52075]); - wr[4] = (ushort)(wr[5] ^ myexp[9467]); - wr[5] = (ushort)(wr[6] ^ myexp[41590]); - wr[6] = (ushort)(wr[7] ^ myexp[19504]); - wr[7] = myexp[28]; - } - else - { - wr[0] = wr[1]; - wr[1] = wr[2]; - wr[2] = wr[3]; - wr[3] = wr[4]; - wr[4] = wr[5]; - wr[5] = wr[6]; - wr[6] = wr[7]; - wr[7] = 0; - } - } + // //crc = (crc >> 8) ^ crct[(byte)(crc ^ dd)]; + // //crc = (crc >> 8) ^ crct[(byte)(crc ^ (dd >> 8))]; - // syn[i] += data[pos] * α^(n*i) - if (verify && dd != 0) - { - int n = stridecount - currentStride; - ushort* syn = synptr + part * 8; - syn[0] ^= dd; - int idx = log[dd]; - idx += n; syn[1] ^= exp[(idx & 0xffff) + (idx >> 16)]; - idx += n; syn[2] ^= exp[(idx & 0xffff) + (idx >> 16)]; - idx += n; syn[3] ^= exp[(idx & 0xffff) + (idx >> 16)]; - idx += n; syn[4] ^= exp[(idx & 0xffff) + (idx >> 16)]; - idx += n; syn[5] ^= exp[(idx & 0xffff) + (idx >> 16)]; - idx += n; syn[6] ^= exp[(idx & 0xffff) + (idx >> 16)]; - idx += n; syn[7] ^= exp[(idx & 0xffff) + (idx >> 16)]; - } - } - } + // //if (encode) + // //{ + // // ushort* wr = ((ushort*)bpar) + part * 8; + // // int ib = wr[0] ^ dd; + // // if (ib != 0) + // // { + // // ushort* myexp = exp + log[ib]; + // // wr[0] = (ushort)(wr[1] ^ myexp[19483]); + // // wr[1] = (ushort)(wr[2] ^ myexp[41576]); + // // wr[2] = (ushort)(wr[3] ^ myexp[9460]); + // // wr[3] = (ushort)(wr[4] ^ myexp[52075]); + // // wr[4] = (ushort)(wr[5] ^ myexp[9467]); + // // wr[5] = (ushort)(wr[6] ^ myexp[41590]); + // // wr[6] = (ushort)(wr[7] ^ myexp[19504]); + // // wr[7] = myexp[28]; + // // } + // // else + // // { + // // wr[0] = wr[1]; + // // wr[1] = wr[2]; + // // wr[2] = wr[3]; + // // wr[3] = wr[4]; + // // wr[4] = wr[5]; + // // wr[5] = wr[6]; + // // wr[6] = wr[7]; + // // wr[7] = 0; + // // } + // //} + + // // syn[i] += data[pos] * α^(n*i) + + // //if (verify && dd != 0) + // //{ + // // ushort* syn = synptr + part * 8; + // // syn[0] ^= dd; + // // int idx = log[dd]; + // // idx += n; syn[1] ^= exp[(idx & 0xffff) + (idx >> 16)]; + // // idx += n; syn[2] ^= exp[(idx & 0xffff) + (idx >> 16)]; + // // idx += n; syn[3] ^= exp[(idx & 0xffff) + (idx >> 16)]; + // // idx += n; syn[4] ^= exp[(idx & 0xffff) + (idx >> 16)]; + // // idx += n; syn[5] ^= exp[(idx & 0xffff) + (idx >> 16)]; + // // idx += n; syn[6] ^= exp[(idx & 0xffff) + (idx >> 16)]; + // // idx += n; syn[7] ^= exp[(idx & 0xffff) + (idx >> 16)]; + // //} + // } + //} private unsafe void ProcessStride16(int currentStride, int currentPart, int count, ushort* data) { - fixed (uint* crct = crc32.table) + fixed (uint* crct = Crc32.table) fixed (byte* bpar = parity) fixed (ushort* exp = galois.ExpTbl, log = galois.LogTbl, synptr = syndrome) for (int pos = 0; pos < count; pos++) @@ -253,8 +248,8 @@ namespace CUETools.CDRepair ushort* wr = par + part * 16; ushort dd = data[pos]; - crc = (crc >> 8) ^ crct[(byte)(crc ^ dd)]; - crc = (crc >> 8) ^ crct[(byte)(crc ^ (dd >> 8))]; + //crc = (crc >> 8) ^ crct[(byte)(crc ^ dd)]; + //crc = (crc >> 8) ^ crct[(byte)(crc ^ (dd >> 8))]; int ib = wr[0] ^ dd; if (ib != 0) @@ -344,36 +339,23 @@ namespace CUETools.CDRepair int copyCount = Math.Min((sampleBuffer.Length - offs) * 2, stride - currentPart); ushort* data = ((ushort*)bytes) + offs * 2; - if (verify) - { - // remember CRC after leadin - if (sampleCount * 2 == stride * 2) - crcA = crc; + if (currentStride < 2) + for (int pos = 0; pos < copyCount; pos++) + leadin[sampleCount * 2 + pos] = data[pos]; - // remember CRC before leadout - if ((finalSampleCount - sampleCount) * 2 == stride + laststride) - crcB = crc; - - if (currentStride < 2) - for (int pos = 0; pos < copyCount; pos++) - leadin[sampleCount * 2 + pos] = data[pos]; - - if (currentStride >= stridecount) - for (int pos = 0; pos < copyCount; pos++) - { - int remaining = (finalSampleCount - sampleCount) * 2 - pos - 1; - if (remaining < stride + laststride) - leadout[remaining] = data[pos]; - } - } + if (currentStride >= stridecount) + for (int pos = 0; pos < copyCount; pos++) + { + int remaining = (finalSampleCount - sampleCount) * 2 - pos - 1; + if (remaining < stride + laststride) + leadout[remaining] = data[pos]; + } if (currentStride >= 1 && currentStride <= stridecount) { - if (npar == 8) - ProcessStride8(currentStride, currentPart, copyCount, data); - else if (npar == 16) + if (npar == 16) ProcessStride16(currentStride, currentPart, copyCount, data); - else + else if (npar != 8) ProcessStride(currentStride, currentPart, copyCount, data); } @@ -388,13 +370,21 @@ namespace CUETools.CDRepair return VerifyParity(npar, parity2, 0, parity2.Length, actualOffset); } + public uint CRC + { + get + { + return OffsettedCRC(0); + } + } + private unsafe uint OffsettedCRC(int actualOffset) { - fixed (uint* crct = crc32.table) + fixed (uint* crct = Crc32.table) { // calculate leadin CRC uint crc0 = 0; - for (int off = stride - 2 * actualOffset; off < 2 * stride; off++) + for (int off = 0; off < stride - 2 * actualOffset; off++) { ushort dd = leadin[off]; crc0 = (crc0 >> 8) ^ crct[(byte)(crc0 ^ dd)]; @@ -402,26 +392,14 @@ namespace CUETools.CDRepair } // calculate leadout CRC uint crc2 = 0; - for (int off = laststride + stride - 1; off >= laststride + 2 * actualOffset; off--) + for (int off = laststride + 2 * actualOffset - 1; off >= 0; off--) { ushort dd = leadout[off]; crc2 = (crc2 >> 8) ^ crct[(byte)(crc2 ^ dd)]; crc2 = (crc2 >> 8) ^ crct[(byte)(crc2 ^ (dd >> 8))]; } - // calculate middle CRC - uint crc1 = crc32.Combine(crcA, crcB, (stridecount - 2) * stride * 2); - // calculate offsettedCRC as sum of 0xffffffff, crc0, crc1, crc2; - return crc32.Combine( - 0xffffffff, - crc32.Combine( - crc32.Combine( - crc0, - crc1, - (stridecount - 2) * stride * 2), - crc2, - (stride - 2 * actualOffset) * 2), - stridecount * stride * 2) ^ 0xffffffff; + return ar.GetCRC32(crc0, (stride - 2 * actualOffset) * 2, crc2, (laststride + 2 * actualOffset) * 2); } } @@ -509,7 +487,7 @@ namespace CUETools.CDRepair fix.sigma = new int[stride, npar / 2 + 2]; fix.omega = new int[stride, npar / 2 + 1]; fix.errpos = new int[stride, npar / 2]; - fix.erroff = new int[stride, npar / 2]; + //fix.erroff = new int[stride, npar / 2]; fix.errors = new int[stride]; fixed (byte* par = &parity2[pos]) @@ -563,7 +541,7 @@ namespace CUETools.CDRepair if (err != 0) { - fixed (int* s = &fix.sigma[part, 0], o = &fix.omega[part, 0], e = &fix.errpos[part, 0], f = &fix.erroff[part, 0]) + fixed (int* s = &fix.sigma[part, 0], o = &fix.omega[part, 0], e = &fix.errpos[part, 0]) { fix.errors[part] = rs.calcSigmaMBM(s, syn); fix.hasErrors = true; @@ -571,11 +549,7 @@ namespace CUETools.CDRepair if (fix.errors[part] <= 0 || !rs.chienSearch(e, stridecount + npar, fix.errors[part], s)) fix.canRecover = false; else - { galois.mulPoly(o, s, syn, npar / 2 + 1, npar, npar); - for (int i = 0; i < fix.errors[part]; i++) - f[i] = galois.toPos(stridecount + npar, e[i]); - } } } else @@ -603,14 +577,88 @@ namespace CUETools.CDRepair internal int[,] sigma; internal int[,] omega; internal int[,] errpos; - internal int[,] erroff; + internal int[] erroffsorted; + internal ushort[] forneysorted; + internal int erroffcount; internal int[] errors; + private BitArray affectedSectorArray; + private int nexterroff; + uint crc = 0; public CDRepairFix(CDRepairEncode decode) : base(decode) { } + public string AffectedSectors + { + get + { + StringBuilder sb = new StringBuilder(); + SortErrors(); + for (int i = 0; i < erroffcount; i++) + { + int j; + for (j = i + 1; j < erroffcount; j++) + if (erroffsorted[j] - erroffsorted[j - 1] > 2 * 588 * 5) + break; + uint sec1 = (uint)erroffsorted[i] / 2 / 588; + uint sec2 = (uint)erroffsorted[j - 1] / 2 / 588; + if (sb.Length != 0) sb.Append(","); + sb.Append(CDImageLayout.TimeToString(sec1)); + if (sec1 != sec2) sb.Append("-"); + if (sec1 != sec2) sb.Append(CDImageLayout.TimeToString(sec2)); + i = j - 1; + } + return sb.ToString(); + } + } + + public BitArray AffectedSectorArray + { + get + { + if (affectedSectorArray == null) + { + affectedSectorArray = new BitArray(finalSampleCount / 588 + 1); + SortErrors(); + for (int i = 0; i < erroffcount; i++) + affectedSectorArray[erroffsorted[i] / 2 / 588] = true; + } + return affectedSectorArray; + } + } + + private int GetErrOff(int part, int i) + { + return (2 + galois.toPos(stridecount + npar, errpos[part, i]) - (stride + part + ActualOffset * 2) / stride) * stride + part; + } + + private unsafe void SortErrors() + { + if (erroffsorted != null) + return; + erroffcount = 0; + erroffsorted = new int[errpos.GetLength(0) * errpos.GetLength(1)]; + forneysorted = new ushort[errpos.GetLength(0) * errpos.GetLength(1)]; + for (int part = 0; part < stride; part++) + { + fixed (int* s = &sigma[part, 0], o = &omega[part, 0]) + for (int i = 0; i < errors[part]; i++) + { + erroffsorted[erroffcount] = GetErrOff(part, i); + if (erroffsorted[erroffcount] >= 0 && erroffsorted[erroffcount] < finalSampleCount * 2) + { + forneysorted[erroffcount] = (ushort)rs.doForney(errors[part], errpos[part, i], s, o); + erroffcount++; + } + } + } + Array.Sort(erroffsorted, forneysorted, 0, erroffcount); + // assert erroffcount == CorrectableErrors + nexterroff = 0; + } + new public unsafe void Write(AudioBuffer sampleBuffer) { sampleBuffer.Prepare(this); @@ -621,21 +669,18 @@ namespace CUETools.CDRepair int firstPos = Math.Max(0, stride - sampleCount * 2 - ActualOffset * 2); int lastPos = Math.Min(sampleBuffer.ByteLength >> 1, (finalSampleCount - sampleCount) * 2 - laststride - ActualOffset * 2); + SortErrors(); + fixed (byte* bytes = sampleBuffer.Bytes) - fixed (uint* t = crc32.table) + fixed (uint* t = Crc32.table) { ushort* data = (ushort*)bytes; for (int pos = firstPos; pos < lastPos; pos++) { - int part = (sampleCount * 2 + pos) % stride; - int nerrors = errors[part]; - fixed (int* s = &sigma[part, 0], o = &omega[part, 0], f = &erroff[part, 0]) - for (int i = 0; i < nerrors; i++) - if (f[i] == (sampleCount * 2 + ActualOffset * 2 + pos) / stride - 1) - data[pos] ^= (ushort)rs.doForney(nerrors, errpos[part, i], s, o); - + if (sampleCount * 2 + pos == erroffsorted[nexterroff] && nexterroff < erroffsorted.Length) + data[pos] ^= forneysorted[nexterroff++]; + ushort dd = data[pos]; - crc = (crc >> 8) ^ t[(byte)(crc ^ dd)]; crc = (crc >> 8) ^ t[(byte)(crc ^ (dd >> 8))]; } @@ -674,5 +719,13 @@ namespace CUETools.CDRepair return actualOffset; } } + + public uint CRC + { + get + { + return 0xffffffff ^ Crc32.Combine(0xffffffff, crc, stride * stridecount * 2); + } + } } } diff --git a/CUETools.CDRepair/CUETools.CDRepair.csproj b/CUETools.CDRepair/CUETools.CDRepair.csproj index 74b1385..7f0ab30 100644 --- a/CUETools.CDRepair/CUETools.CDRepair.csproj +++ b/CUETools.CDRepair/CUETools.CDRepair.csproj @@ -42,6 +42,14 @@ + + {5802C7E9-157E-4124-946D-70B5AE48A5A1} + CUETools.AccurateRip + + + {1DD41038-D885-46C5-8DDE-E0B82F066584} + CUETools.CDImage + {6458A13A-30EF-45A9-9D58-E5031B17BEE2} CUETools.Codecs diff --git a/CUETools.CTDB/CUETools.CTDB.csproj b/CUETools.CTDB/CUETools.CTDB.csproj index adcce97..c51e70f 100644 --- a/CUETools.CTDB/CUETools.CTDB.csproj +++ b/CUETools.CTDB/CUETools.CTDB.csproj @@ -47,6 +47,10 @@ + + {5802C7E9-157E-4124-946D-70B5AE48A5A1} + CUETools.AccurateRip + {1DD41038-D885-46C5-8DDE-E0B82F066584} CUETools.CDImage diff --git a/CUETools.CTDB/CUEToolsDB.cs b/CUETools.CTDB/CUEToolsDB.cs index dcd110c..add404d 100644 --- a/CUETools.CTDB/CUEToolsDB.cs +++ b/CUETools.CTDB/CUEToolsDB.cs @@ -8,6 +8,7 @@ using System.Net; using System.Xml; using System.Text; using CUETools.CDImage; +using CUETools.AccurateRip; using CUETools.CDRepair; using Krystalware.UploadHelper; @@ -364,12 +365,12 @@ namespace CUETools.CTDB } } - public void Init(bool encode) + public void Init(bool encode, AccurateRipVerify ar) { int npar = 8; foreach (DBEntry entry in entries) npar = Math.Max(npar, entry.npar); - verify = new CDRepairEncode(length, 10 * 588 * 2, npar, entries.Count > 0, encode); + verify = new CDRepairEncode(length, 10 * 588 * 2, npar, entries.Count > 0, encode, ar); } public int Total diff --git a/CUETools.Codecs/CRCs/CRC32.cs b/CUETools.Codecs/CRCs/CRC32.cs index f352e19..7f0c6c6 100644 --- a/CUETools.Codecs/CRCs/CRC32.cs +++ b/CUETools.Codecs/CRCs/CRC32.cs @@ -4,16 +4,16 @@ using System.Text; namespace CUETools.Codecs { - public class Crc32 + public static class Crc32 { - public uint[] table = new uint[256]; + public static readonly uint[] table; - public uint ComputeChecksum(uint crc, byte val) + public static uint ComputeChecksum(uint crc, byte val) { return (crc >> 8) ^ table[(crc & 0xff) ^ val]; } - public unsafe uint ComputeChecksum(uint crc, byte* bytes, int count) + public static unsafe uint ComputeChecksum(uint crc, byte* bytes, int count) { fixed (uint *t = table) for (int i = 0; i < count; i++) @@ -21,19 +21,19 @@ namespace CUETools.Codecs return crc; } - public unsafe uint ComputeChecksum(uint crc, byte[] bytes, int pos, int count) + public static unsafe uint ComputeChecksum(uint crc, byte[] bytes, int pos, int count) { fixed (byte* pbytes = &bytes[pos]) return ComputeChecksum(crc, pbytes, count); } - public uint ComputeChecksum(uint crc, uint s) + public static uint ComputeChecksum(uint crc, uint s) { return ComputeChecksum(ComputeChecksum(ComputeChecksum(ComputeChecksum( crc, (byte)s), (byte)(s >> 8)), (byte)(s >> 16)), (byte)(s >> 24)); } - public unsafe uint ComputeChecksum(uint crc, int * samples, int count) + public static unsafe uint ComputeChecksum(uint crc, int* samples, int count) { for (int i = 0; i < count; i++) { @@ -44,7 +44,7 @@ namespace CUETools.Codecs return crc; } - uint Reflect(uint val, int ch) + static uint Reflect(uint val, int ch) { uint value = 0; // Swap bit 0 for bit 7 @@ -60,8 +60,66 @@ namespace CUETools.Codecs const uint ulPolynomial = 0x04c11db7; - public Crc32() + private static readonly uint[,] combineTable; + private static readonly uint[,] substractTable; + +#if need_invert_binary_matrix + static unsafe void invert_binary_matrix(uint* mat, uint* inv, int rows) { + int cols, i, j; + uint tmp; + + cols = rows; + + for (i = 0; i < rows; i++) inv[i] = (1U << i); + + /* First -- convert into upper triangular */ + + for (i = 0; i < cols; i++) + { + + /* Swap rows if we ave a zero i,i element. If we can't swap, then the + matrix was not invertible */ + + if ((mat[i] & (1 << i)) == 0) + { + for (j = i + 1; j < rows && (mat[j] & (1 << i)) == 0; j++) ; + if (j == rows) + throw new Exception("Matrix not invertible"); + tmp = mat[i]; mat[i] = mat[j]; mat[j] = tmp; + tmp = inv[i]; inv[i] = inv[j]; inv[j] = tmp; + } + + /* Now for each j>i, add A_ji*Ai to Aj */ + for (j = i + 1; j != rows; j++) + { + if ((mat[j] & (1 << i)) != 0) + { + mat[j] ^= mat[i]; + inv[j] ^= inv[i]; + } + } + } + + /* Now the matrix is upper triangular. Start at the top and multiply down */ + + for (i = rows - 1; i >= 0; i--) + { + for (j = 0; j < i; j++) + { + if ((mat[j] & (1 << i)) != 0) + { + /* mat[j] ^= mat[i]; */ + inv[j] ^= inv[i]; + } + } + } + } +#endif + + static unsafe Crc32() + { + table = new uint[256]; for (uint i = 0; i < table.Length; i++) { table[i] = Reflect(i, 8) << 24; @@ -69,11 +127,33 @@ namespace CUETools.Codecs table[i] = (table[i] << 1) ^ ((table[i] & (1U << 31)) == 0 ? 0 : ulPolynomial); table[i] = Reflect(table[i], 32); } + combineTable = new uint[GF2_DIM, GF2_DIM]; + substractTable = new uint[GF2_DIM, GF2_DIM]; + combineTable[0, 0] = 0xedb88320; /* CRC-32 polynomial */ + substractTable[0, 31] = 0xdb710641; + for (int n = 1; n < GF2_DIM; n++) + { + combineTable[0, n] = 1U << (n - 1); + substractTable[0, n - 1] = 1U << n; + } + fixed (uint* ct = &combineTable[0, 0], st = &substractTable[0, 0]) + { + //for (int i = 0; i < GF2_DIM; i++) + // st[32 + i] = ct[i]; + //invert_binary_matrix(st + 32, st, GF2_DIM); + + for (int i = 1; i < GF2_DIM; i++) + { + gf2_matrix_square(ct + i * 32, ct + (i - 1) * 32); + gf2_matrix_square(st + i * 32, st + (i - 1) * 32); + } + } } const int GF2_DIM = 32; + //const int GF2_DIM2 = 67; - private unsafe uint gf2_matrix_times(uint* mat, uint vec) + private static unsafe uint gf2_matrix_times(uint* mat, uint vec) { return *(mat++) * (vec & 1) ^ *(mat++) * ((vec >>= 1) & 1) ^ @@ -110,63 +190,67 @@ namespace CUETools.Codecs } /* ========================================================================= */ - private unsafe void gf2_matrix_square(uint *square, uint *mat) + private static unsafe void gf2_matrix_square(uint *square, uint *mat) { for (int n = 0; n < GF2_DIM; n++) square[n] = gf2_matrix_times(mat, mat[n]); } - - public unsafe uint Combine(uint crc1, uint crc2, long len2) + public static unsafe uint Combine(uint crc1, uint crc2, long len2) { - int n; - uint row; - uint* even = stackalloc uint[GF2_DIM]; /* even-power-of-two zeros operator */ - uint* odd = stackalloc uint[GF2_DIM]; /* odd-power-of-two zeros operator */ - /* degenerate case */ if (len2 == 0) return crc1; + if (crc1 == 0) + return crc2; + if (len2 < 0) + throw new ArgumentException("crc.Combine length cannot be negative", "len2"); - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; + fixed (uint* ct = &combineTable[0, 0]) + { + int n = 3; + do + { + /* apply zeros operator for this bit of len2 */ + if ((len2 & 1) != 0) + crc1 = gf2_matrix_times(ct + 32 * n, crc1); + len2 >>= 1; + n = (n + 1) & (GF2_DIM - 1); + /* if no more bits set, then done */ + } while (len2 != 0); } - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if ((len2 & 1) != 0) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if ((len2 & 1) != 0) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - /* return combined crc */ crc1 ^= crc2; return crc1; } + + public static unsafe uint Substract(uint crc1, uint crc2, long len2) + { + /* degenerate case */ + if (len2 == 0) + return crc1; + if (len2 < 0) + throw new ArgumentException("crc.Combine length cannot be negative", "len2"); + + crc1 ^= crc2; + + fixed (uint* st = &substractTable[0, 0]) + { + int n = 3; + do + { + /* apply zeros operator for this bit of len2 */ + if ((len2 & 1) != 0) + crc1 = gf2_matrix_times(st + 32 * n, crc1); + len2 >>= 1; + n = (n + 1) & (GF2_DIM - 1); + /* if no more bits set, then done */ + } while (len2 != 0); + } + + /* return combined crc */ + return crc1; + } } } diff --git a/CUETools.Codecs/Codecs.cs b/CUETools.Codecs/Codecs.cs index 41e14a3..a1b7c65 100644 --- a/CUETools.Codecs/Codecs.cs +++ b/CUETools.Codecs/Codecs.cs @@ -2134,7 +2134,7 @@ namespace CUETools.Codecs _bufferPos = 0; _haveData = false; _close = false; - Go(); + //Go(); //throw new Exception("not supported"); } } diff --git a/CUETools.Processor/Processor.cs b/CUETools.Processor/Processor.cs index c240721..3974774 100644 --- a/CUETools.Processor/Processor.cs +++ b/CUETools.Processor/Processor.cs @@ -742,7 +742,7 @@ namespace CUETools.Processor { return name; } - public string name; + public string name { get; set; } public bool builtin; public List conditions; public string code; @@ -1562,8 +1562,7 @@ string status = processor.Go(); public class CUEToolsProgressEventArgs : EventArgs { public string status = string.Empty; - public double percentTrck = 0; - public double percentDisk = 0.0; + public double percent = 0.0; public int offset = 0; public string input = string.Empty; public string output = string.Empty; @@ -1601,8 +1600,8 @@ string status = processor.Go(); private bool _paddedToFrame, _truncated4608, _usePregapForFirstTrackInSingleFile; private int _writeOffset; private CUEAction _action; - private bool _useAccurateRip = false; - private bool _useCUEToolsDB = false; + internal bool _useAccurateRip = false; + internal bool _useCUEToolsDB = false; private bool _useCUEToolsDBFix = false; private bool _useCUEToolsDBSibmit = false; private bool _processed = false; @@ -1790,7 +1789,7 @@ string status = processor.Go(); if (useFreedb) { - ShowProgress("Looking up album via Freedb...", 0.0, 0.0, null, null); + ShowProgress("Looking up album via Freedb...", 0.0, null, null); FreedbHelper m_freedb = new FreedbHelper(); @@ -1809,7 +1808,7 @@ string status = processor.Go(); code = m_freedb.Query(AccurateRipVerify.CalculateCDDBQuery(_toc), out queryResult, out coll); if (code == FreedbHelper.ResponseCodes.CODE_200) { - ShowProgress("Looking up album via Freedb... " + queryResult.Discid, 0.5, 0.0, null, null); + ShowProgress("Looking up album via Freedb... " + queryResult.Discid, 0.5, null, null); code = m_freedb.Read(queryResult, out cdEntry); if (code == FreedbHelper.ResponseCodes.CODE_210) Releases.Add(cdEntry); @@ -1821,7 +1820,7 @@ string status = processor.Go(); int i = 0; foreach (QueryResult qr in coll) { - ShowProgress("Looking up album via freedb... " + qr.Discid, 0.0, (++i + 0.0) / coll.Count, null, null); + ShowProgress("Looking up album via freedb... " + qr.Discid, (++i + 0.0) / coll.Count, null, null); CheckStop(); code = m_freedb.Read(qr, out cdEntry); if (code == FreedbHelper.ResponseCodes.CODE_210) @@ -1838,7 +1837,7 @@ string status = processor.Go(); if (useMusicBrainz) { - ShowProgress("Looking up album via MusicBrainz...", 0.0, 0.0, null, null); + ShowProgress("Looking up album via MusicBrainz...", 0.0, null, null); StringCollection DiscIds = new StringCollection(); DiscIds.Add(_toc.MusicBrainzId); @@ -2672,20 +2671,20 @@ string status = processor.Go(); public void UseCUEToolsDB(bool submit, string userAgent) { - ShowProgress((string)"Contacting CUETools database...", 0, 0, null, null); + ShowProgress((string)"Contacting CUETools database...", 0, null, null); _CUEToolsDB = new CUEToolsDB(_toc, proxy); _CUEToolsDB.UploadHelper.onProgress += new EventHandler(UploadProgress); _CUEToolsDB.ContactDB(userAgent); - ShowProgress("", 0.0, 0.0, null, null); + ShowProgress("", 0.0, null, null); _useCUEToolsDB = true; _useCUEToolsDBSibmit = submit; } public void UseAccurateRip() { - ShowProgress((string)"Contacting AccurateRip database...", 0, 0, null, null); + ShowProgress((string)"Contacting AccurateRip database...", 0, null, null); if (!_toc[_toc.TrackCount].IsAudio && DataTrackLength == 0 && _minDataTrackLength.HasValue && _accurateRipId == null && _config.bruteForceDTL) { uint minDTL = _minDataTrackLength.Value; @@ -2699,7 +2698,7 @@ string status = processor.Go(); DataTrackLength = dtl; break; } - ShowProgress((string)"Contacting AccurateRip database...", 0, (dtl - minDTL) / 75.0, null, null); + ShowProgress((string)"Contacting AccurateRip database...", (dtl - minDTL) / 75.0, null, null); CheckStop(); lock (this) { @@ -2764,26 +2763,24 @@ string status = processor.Go(); return _archive.Decompress(fileName); } - private void ShowProgress(string status, double percentTrack, double percentDisk, string input, string output) + private void ShowProgress(string status, double percent, string input, string output) { if (this.CUEToolsProgress == null) return; _progress.status = status; - _progress.percentTrck = percentTrack; - _progress.percentDisk = percentDisk; + _progress.percent = percent; _progress.offset = 0; _progress.input = input; _progress.output = output; this.CUEToolsProgress(this, _progress); } - private void ShowProgress(string status, double percentTrack, int diskOffset, int diskLength, string input, string output) + private void ShowProgress(string status, int diskOffset, int diskLength, string input, string output) { if (this.CUEToolsProgress == null) return; _progress.status = status; - _progress.percentTrck = percentTrack; - _progress.percentDisk = (double)diskOffset / diskLength; + _progress.percent = (double)diskOffset / diskLength; _progress.offset = diskOffset; _progress.input = input; _progress.output = output; @@ -2795,35 +2792,33 @@ string status = processor.Go(); CheckStop(); if (this.CUEToolsProgress == null) return; - _progress.percentDisk = 0; - _progress.percentTrck = e.percent; + _progress.percent = e.percent; _progress.offset = 0; _progress.status = e.uri; this.CUEToolsProgress(this, _progress); } - private void CDReadProgress(object sender, ReadProgressArgs e) - { - CheckStop(); - if (this.CUEToolsProgress == null) - return; - ICDRipper audioSource = (ICDRipper)sender; - int processed = e.Position - e.PassStart; - TimeSpan elapsed = DateTime.Now - e.PassTime; - double speed = elapsed.TotalSeconds > 0 ? processed / elapsed.TotalSeconds / 75 : 1.0; - _progress.percentDisk = (double)(e.PassStart + (processed + e.Pass * (e.PassEnd - e.PassStart)) / (audioSource.CorrectionQuality + 1)) / audioSource.TOC.AudioLength; - _progress.percentTrck = (double) (e.Position - e.PassStart) / (e.PassEnd - e.PassStart); - _progress.offset = 0; - _progress.status = string.Format("Ripping @{0:00.00}x {1}", speed, e.Pass > 0 ? " (Retry " + e.Pass.ToString() + ")" : ""); - this.CUEToolsProgress(this, _progress); - } + //private void CDReadProgress(object sender, ReadProgressArgs e) + //{ + // CheckStop(); + // if (this.CUEToolsProgress == null) + // return; + // ICDRipper audioSource = (ICDRipper)sender; + // int processed = e.Position - e.PassStart; + // TimeSpan elapsed = DateTime.Now - e.PassTime; + // double speed = elapsed.TotalSeconds > 0 ? processed / elapsed.TotalSeconds / 75 : 1.0; + // _progress.percentDisk = (double)(e.PassStart + (processed + e.Pass * (e.PassEnd - e.PassStart)) / (audioSource.CorrectionQuality + 1)) / audioSource.TOC.AudioLength; + // _progress.percentTrck = (double) (e.Position - e.PassStart) / (e.PassEnd - e.PassStart); + // _progress.offset = 0; + // _progress.status = string.Format("Ripping @{0:00.00}x {1}", speed, e.Pass > 0 ? " (Retry " + e.Pass.ToString() + ")" : ""); + // this.CUEToolsProgress(this, _progress); + //} private void MusicBrainz_LookupProgress(object sender, XmlRequestEventArgs e) { if (this.CUEToolsProgress == null) return; - _progress.percentDisk = (1.0 + _progress.percentDisk) / 2; - _progress.percentTrck = 0; + _progress.percent = (1.0 + _progress.percent) / 2; _progress.offset = 0; _progress.input = e.Uri.ToString(); _progress.output = null; @@ -2836,7 +2831,7 @@ string status = processor.Go(); CheckStop(); if (this.CUEToolsProgress == null) return; - _progress.percentTrck = e.PercentComplete / 100; + _progress.percent = e.PercentComplete / 100; this.CUEToolsProgress(this, _progress); } @@ -3128,7 +3123,7 @@ string status = processor.Go(); private int GetSampleLength(string path, out TagLib.File fileInfo) { - ShowProgress("Analyzing input file...", 0.0, 0.0, path, null); + ShowProgress("Analyzing input file...", 0.0, path, null); if (Path.GetExtension(path) == ".dummy" || Path.GetExtension(path) == ".bin") { @@ -3581,8 +3576,9 @@ string status = processor.Go(); entry.toc.Pregap != _toc.Pregap ? string.Format("Has pregap length {0}", CDImageLayout.TimeToString(entry.toc.Pregap)) : entry.toc.AudioLength != _toc.AudioLength ? string.Format("Has audio length {0}", CDImageLayout.TimeToString(entry.toc.AudioLength)) : ((entry.toc.TrackOffsets != _toc.TrackOffsets) ? dataTrackInfo + ", " : "") + - ((!entry.hasErrors) ? "Accurately ripped" : - entry.canRecover ? string.Format("Differs in {0} samples", entry.repair.CorrectableErrors) : + //((!entry.hasErrors) ? "Accurately ripped" : + ((!entry.hasErrors) ? string.Format("Accurately ripped, offset {0}", -entry.offset) : + entry.canRecover ? string.Format("Differs in {0} samples @{1}", entry.repair.CorrectableErrors, entry.repair.AffectedSectors) : (entry.httpStatus == 0 || entry.httpStatus == HttpStatusCode.OK) ? "No match" : entry.httpStatus.ToString()); sw.WriteLine(" [{0:x8}] ({1}) {2}", entry.crc, conf, status); @@ -4067,7 +4063,7 @@ string status = processor.Go(); { if (_useAccurateRip) { - ShowProgress((string)"Generating AccurateRip report...", 0, 0, null, null); + ShowProgress((string)"Generating AccurateRip report...", 0, null, null); if (_action == CUEAction.Verify && _config.writeArTagsOnVerify && _writeOffset == 0 && !_isArchive && !_isCD) { uint tracksMatch; @@ -4354,9 +4350,9 @@ string status = processor.Go(); if (_useAccurateRip) _arVerify.Init(); if (_useCUEToolsDB && !_useCUEToolsDBFix) - _CUEToolsDB.Init(_useCUEToolsDBSibmit); + _CUEToolsDB.Init(_useCUEToolsDBSibmit, _arVerify); - ShowProgress(String.Format("{2} track {0:00} ({1:00}%)...", 0, 0, noOutput ? "Verifying" : "Writing"), 0, 0.0, null, null); + ShowProgress(String.Format("{2} track {0:00} ({1:00}%)...", 0, 0, noOutput ? "Verifying" : "Writing"), 0.0, null, null); #if !DEBUG try @@ -4431,8 +4427,8 @@ string status = processor.Go(); if (trackLength > 0 && !_isCD) { double trackPercent = (double)currentOffset / trackLength; - ShowProgress(String.Format("{2} track {0:00} ({1:00}%)...", iIndex > 0 ? iTrack + 1 : iTrack, (uint)(100 * trackPercent), - noOutput ? "Verifying" : "Writing"), trackPercent, (int)diskOffset, (int)diskLength, + ShowProgress(String.Format("{2} track {0:00} ({1:00}%)...", iIndex > 0 ? iTrack + 1 : iTrack, (int)(100*trackPercent), + noOutput ? "Verifying" : "Writing"), (int)diskOffset, (int)diskLength, _isCD ? string.Format("{0}: {1:00} - {2}", audioSource.Path, iTrack + 1, _tracks[iTrack].Title) : audioSource.Path, discardOutput ? null : audioDest.Path); } @@ -4512,93 +4508,98 @@ string status = processor.Go(); ApplyWriteOffset(); hdcdDecoder = null; - if (_config.detectHDCD && CUEProcessorPlugins.hdcd != null) - { - try { hdcdDecoder = Activator.CreateInstance(CUEProcessorPlugins.hdcd, 2, 44100, 20, false) as IAudioDest; } - catch { } - } if (_useAccurateRip) _arVerify.Init(); if (_useCUEToolsDB && !_useCUEToolsDBFix) - _CUEToolsDB.Init(_useCUEToolsDBSibmit); + _CUEToolsDB.Init(_useCUEToolsDBSibmit, _arVerify); - ShowProgress(String.Format("{2} track {0:00} ({1:00}%)...", 0, 0, "Verifying"), 0, 0.0, null, null); + ShowProgress(String.Format("Verifying ({0:00}%)...", 0), 0.0, null, null); AudioBuffer sampleBuffer = new AudioBuffer(AudioPCMConfig.RedBook, 0x10000); - IAudioSource audioSource = new CUESheetAudio(this); - if (_isCD || _config.separateDecodingThread) - audioSource = new AudioPipe(audioSource, 0x10000); + + List tasks = new List(); + // also make sure all sources are seekable!!! + // use overlapped io with large buffers? + // ar.verify in each thread? + int nThreads = 1;// _isCD || !_config.separateDecodingThread || _useCUEToolsDB || _config.detectHDCD ? 1 : Environment.ProcessorCount; + + int diskLength = 588 * (int)_toc.AudioLength; + tasks.Add(new CUEToolsVerifyTask(this, 0, diskLength / nThreads, _arVerify, _CUEToolsDB)); + for (int iThread = 1; iThread < nThreads; iThread++) + tasks.Add(new CUEToolsVerifyTask(this, iThread * diskLength / nThreads, (iThread + 1) * diskLength / nThreads)); #if !DEBUG try #endif { int lastProgress = -588 * 75; + int diskOffset = 0; + int sourcesActive; do { - if (audioSource.Position - lastProgress >= 588 * 75) + sourcesActive = 0; + for (int iSource = 0; iSource < tasks.Count; iSource++) { - lastProgress = (int)audioSource.Position; - int pos = 0; - int trackStart = 0; - int trackLength = (int)_toc.Pregap * 588; - for (int iTrack = 0; iTrack < TrackCount; iTrack++) - for (int iIndex = 0; iIndex <= _toc[_toc.FirstAudio + iTrack].LastIndex; iIndex++) - { - int indexLen = (int)_toc.IndexLength(_toc.FirstAudio + iTrack, iIndex) * 588; - if (iIndex == 1) + CUEToolsVerifyTask task = tasks[iSource]; + if (task.Remaining == 0) + continue; + sourcesActive++; + if (tasks.Count == 1 && task.source.Position - lastProgress >= 588 * 75) + { + lastProgress = (int)task.source.Position; + int pos = 0; + int trackStart = 0; + int trackLength = (int)_toc.Pregap * 588; + for (int iTrack = 0; iTrack < TrackCount; iTrack++) + for (int iIndex = 0; iIndex <= _toc[_toc.FirstAudio + iTrack].LastIndex; iIndex++) { - trackStart = pos; - trackLength = (int)_toc[_toc.FirstAudio + iTrack].Length * 588; - } - if (audioSource.Position < pos + indexLen) - { - if (trackLength > 0 && !_isCD) + int indexLen = (int)_toc.IndexLength(_toc.FirstAudio + iTrack, iIndex) * 588; + if (iIndex == 1) { - double trackPercent = (double)(audioSource.Position - trackStart) / trackLength; - int diskLength = 588 * (int)_toc.AudioLength; - int diskOffset = (int)audioSource.Position; - ShowProgress(String.Format("{2} track {0:00} ({1:00}%)...", iIndex > 0 ? iTrack + 1 : iTrack, (uint)(100 * trackPercent), - "Verifying"), trackPercent, diskOffset, diskLength, audioSource.Path, null); + trackStart = pos; + trackLength = (int)_toc[_toc.FirstAudio + iTrack].Length * 588; } - iTrack = TrackCount; - break; + if (task.source.Position < pos + indexLen) + { + if (trackLength > 0 && !_isCD) + { + double trackPercent = (double)(task.source.Position - trackStart) / trackLength; + ShowProgress(String.Format("{2} track {0:00} ({1:00}%)...", iIndex > 0 ? iTrack + 1 : iTrack, (int)(100*trackPercent), + "Verifying"), diskOffset, diskLength, task.source.Path, null); + } + iTrack = TrackCount; + break; + } + pos += indexLen; } - pos += indexLen; - } + } + else if (tasks.Count > 1) + { + ShowProgress(String.Format("Verifying ({0:00}%)...", (uint)(100.0 * diskOffset / diskLength)), + diskOffset, diskLength, InputPath, null); + } + + int copyCount = task.Step(sampleBuffer); + + diskOffset += copyCount; + + CheckStop(); } - - int copyCount = audioSource.Read(sampleBuffer, -1); - if (copyCount == 0) - break; - - if (_useCUEToolsDB) // !_useCUEToolsDBFix - _CUEToolsDB.Verify.Write(sampleBuffer); - if (_useAccurateRip) - _arVerify.Write(sampleBuffer); - if (hdcdDecoder != null) - { - hdcdDecoder.Write(sampleBuffer); - if (_config.wait750FramesForHDCD && audioSource.Position > 750 * 588 && string.Format("{0:s}", hdcdDecoder) == "") - hdcdDecoder = null; - } - - CheckStop(); - } while (true); + } while (sourcesActive > 0); } #if !DEBUG catch (Exception ex) { - hdcdDecoder = null; - if (audioSource != null) - try { audioSource.Close(); } - catch { } - audioSource = null; + tasks.ForEach(t => t.TryClose()); + tasks.Clear(); throw ex; } #endif - if (audioSource != null) - audioSource.Close(); + hdcdDecoder = tasks[0].hdcd; + for (int iThread = 1; iThread < nThreads; iThread++) + tasks[0].Combine(tasks[iThread]); + tasks.ForEach(t => t.Close()); + tasks.Clear(); } private void DetectGaps() @@ -4632,8 +4633,8 @@ string status = processor.Go(); { pathIn = Path.GetFullPath(pathIn); List fileGroups = CUESheet.ScanFolder(_config, Path.GetDirectoryName(pathIn)); - FileGroupInfo fileGroup = FileGroupInfo.WhichContains(fileGroups, pathIn, FileGroupInfoType.TrackFiles) - ?? FileGroupInfo.WhichContains(fileGroups, pathIn, FileGroupInfoType.FileWithCUE); + FileGroupInfo fileGroup = fileGroups.Find(f => f.type == FileGroupInfoType.TrackFiles && f.Contains(pathIn)) ?? + fileGroups.Find(f => f.type == FileGroupInfoType.FileWithCUE && f.Contains(pathIn)); return fileGroup == null ? null : CreateDummyCUESheet(_config, fileGroup); } @@ -4832,7 +4833,7 @@ string status = processor.Go(); throw new StopException(); if (_pause) { - ShowProgress("Paused...", 0, 0, null, null); + ShowProgress("Paused...", 0, null, null); Monitor.Wait(this); } } @@ -5474,14 +5475,22 @@ string status = processor.Go(); if (CTDB.DBStatus != null) return CTDB.DBStatus; bool useAR = _useAccurateRip; - _useAccurateRip = false; + _useAccurateRip = true; Go(); _useAccurateRip = useAR; List choices = new List(); foreach (DBEntry entry in CTDB.Entries) if (!entry.hasErrors || entry.canRecover) { - CUEToolsSourceFile choice = new CUEToolsSourceFile(entry.Status, new StringReader("")); + StringBuilder sb = new StringBuilder(); + if (entry.hasErrors) + { + sb.AppendFormat("Affected positions:\n"); + for (int sec = 0; sec < entry.repair.AffectedSectorArray.Length; sec++) + if (entry.repair.AffectedSectorArray[sec]) + sb.AppendFormat("{0}\n", CDImageLayout.TimeToString((uint)sec)); + } + CUEToolsSourceFile choice = new CUEToolsSourceFile(entry.Status, new StringReader(sb.ToString())); choice.data = entry; choices.Add(choice); } @@ -5597,21 +5606,7 @@ string status = processor.Go(); { if (type != FileGroupInfoType.TrackFiles) return main.FullName.ToLower() == pathIn.ToLower(); - bool found = false; - foreach (FileSystemInfo file in files) - if (file.FullName.ToLower() == pathIn.ToLower()) - found = true; - return found; - } - - public static FileGroupInfo WhichContains(IEnumerable fileGroups, string pathIn, FileGroupInfoType type) - { - foreach (FileGroupInfo fileGroup in fileGroups) - { - if (fileGroup.type == type && fileGroup.Contains(pathIn)) - return fileGroup; - } - return null; + return null != files.Find(file => file.FullName.ToLower() == pathIn.ToLower()); } } @@ -5782,6 +5777,7 @@ string status = processor.Go(); CUESheet cueSheet; IAudioSource currentAudio; int currentSource; + long nextPos; long _samplePos, _sampleLen; public CUESheetAudio(CUESheet cueSheet) @@ -5790,10 +5786,9 @@ string status = processor.Go(); this.currentAudio = null; this._samplePos = 0; this._sampleLen = 0; - this.currentSource = 0; - for (int iSource = 0; iSource < cueSheet._sources.Count; iSource++) - this._sampleLen += cueSheet._sources[iSource].Length; - this.currentAudio = cueSheet.GetAudioSource(0, false); + this.currentSource = -1; + this.nextPos = 0; + cueSheet._sources.ForEach(s => this._sampleLen += s.Length); } public void Close() @@ -5813,6 +5808,8 @@ string status = processor.Go(); } set { + if (value == _samplePos) + return; long sourceStart = 0; for (int iSource = 0; iSource < cueSheet._sources.Count; iSource++) { @@ -5820,11 +5817,12 @@ string status = processor.Go(); { if (iSource != currentSource) { - currentAudio.Close(); + if (currentAudio != null) currentAudio.Close(); currentSource = iSource; currentAudio = cueSheet.GetAudioSource(currentSource, false); + nextPos = sourceStart + cueSheet._sources[currentSource].Length; } - currentAudio.Position = value - sourceStart; + currentAudio.Position = value - sourceStart + cueSheet._sources[currentSource].Offset; _samplePos = value; return; } @@ -5869,8 +5867,7 @@ string status = processor.Go(); public int Read(AudioBuffer buff, int maxLength) { buff.Prepare(this, maxLength); - - if (currentAudio.Remaining == 0) + while (_samplePos >= nextPos) { currentSource++; if (currentSource >= cueSheet._sources.Count) @@ -5878,13 +5875,112 @@ string status = processor.Go(); buff.Length = 0; return 0; } - currentAudio.Close(); + if (currentAudio != null) + currentAudio.Close(); currentAudio = cueSheet.GetAudioSource(currentSource, false); + int offset = (int)(_samplePos - nextPos); + if (offset != 0) + currentAudio.Position += offset; + nextPos += cueSheet._sources[currentSource].Length; } - - int res = currentAudio.Read(buff, maxLength); - _samplePos += res; - return res; + int count = (int)(nextPos - _samplePos); + if (maxLength >= 0) + count = Math.Min(count, maxLength); + count = currentAudio.Read(buff, count); + _samplePos += count; + return count; } } + + internal class CUEToolsVerifyTask + { + private CUESheet cueSheet; + public IAudioSource source { get; private set; } + public int start { get; private set; } + public int end { get; private set; } + public AccurateRipVerify ar { get; private set; } + public CUEToolsDB ctdb { get; private set; } + public IAudioDest hdcd { get; private set; } + + public CUEToolsVerifyTask(CUESheet cueSheet, int start, int end) + : this(cueSheet, start, end, cueSheet._useAccurateRip ? new AccurateRipVerify(cueSheet.TOC, null) : null, null, null) + { + } + + public CUEToolsVerifyTask(CUESheet cueSheet, int start, int end, AccurateRipVerify ar, CUEToolsDB ctdb) + : this(cueSheet, start, end, ar, ctdb, null) + { + if (cueSheet.Config.detectHDCD && CUEProcessorPlugins.hdcd != null) + { + try { this.hdcd = Activator.CreateInstance(CUEProcessorPlugins.hdcd, 2, 44100, 20, false) as IAudioDest; } + catch { this.hdcd = null; } + } + } + + private CUEToolsVerifyTask(CUESheet cueSheet, int start, int end, AccurateRipVerify ar, CUEToolsDB ctdb, IAudioDest hdcd) + { + this.cueSheet = cueSheet; + this.start = start; + this.end = end; + this.source = new CUESheetAudio(cueSheet); + if (cueSheet.IsCD || cueSheet.Config.separateDecodingThread) + this.source = new AudioPipe(this.source, 0x10000); + this.source.Position = start; + this.ar = cueSheet._useAccurateRip ? ar : null; + this.ctdb = cueSheet._useCUEToolsDB ? ctdb : null; + this.hdcd = hdcd; + if (this.ar != null) + this.ar.Position = start; + } + + public bool TryClose() + { + try { Close(); } + catch { return false; } + return true; + } + + public void Close() + { + if (this.source != null) + { + this.source.Close(); + this.source = null; + } + if (this.ar != null) + { + //this.ar.Close(); can't! throws + this.ar = null; + } + } + + public int Step(AudioBuffer sampleBuffer) + { + if (Remaining == 0) + return 0; + int copyCount = source.Read(sampleBuffer, Remaining); + if (copyCount == 0) + return 0; + + if (ctdb != null) // !_useCUEToolsDBFix + ctdb.Verify.Write(sampleBuffer); + if (ar != null) + ar.Write( sampleBuffer); + if (hdcd != null) + { + hdcd.Write(sampleBuffer); + if (cueSheet.Config.wait750FramesForHDCD && source.Position > start + 750 * 588 && string.Format("{0:s}", hdcd) == "") + hdcd = null; + } + return copyCount; + } + + public void Combine(CUEToolsVerifyTask task) + { + if (ar != null) + ar.Combine(task.ar, task.start, task.end); + } + + public int Remaining { get { return end - (int)source.Position; } } + } } diff --git a/CUETools/CUETools.TestCodecs/Crc32Test.cs b/CUETools/CUETools.TestCodecs/Crc32Test.cs index 76c32e0..b49408f 100644 --- a/CUETools/CUETools.TestCodecs/Crc32Test.cs +++ b/CUETools/CUETools.TestCodecs/Crc32Test.cs @@ -69,15 +69,15 @@ namespace CUETools.TestCodecs [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."); + 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."); + Assert.AreEqual(crcA, Crc32.Substract(crcAB, crcB, lenB), "CRC32 was not substracted correctly."); } /// @@ -86,8 +86,7 @@ namespace CUETools.TestCodecs [TestMethod()] public void ComputeChecksumTest() { - Crc32 crc32 = new Crc32(); - uint actual = crc32.ComputeChecksum(0xffffffff, testBytes, 0, testBytes.Length) ^ 0xffffffff; + uint actual = Crc32.ComputeChecksum(0xffffffff, testBytes, 0, testBytes.Length) ^ 0xffffffff; Assert.AreEqual(2028688632, actual, "CRC32 was not combined correctly."); } } diff --git a/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs b/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs index 38b758f..55b4754 100644 --- a/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs +++ b/CUETools/CUETools.TestParity/CDRepairDecodeTest.cs @@ -2,6 +2,8 @@ using CUETools.CDRepair; using Microsoft.VisualStudio.TestTools.UnitTesting; using CUETools.Codecs; +using CUETools.CDImage; +using CUETools.AccurateRip; namespace CUETools.TestParity { @@ -15,7 +17,7 @@ namespace CUETools.TestParity public class CDRepairDecodeTest { - const int finalSampleCount = 44100 * 60 * 10 + 20; // 10 minutes long + const int finalSampleCount = 44100 * 60 * 10; // 10 minutes long //const int stride = finalSampleCount * 2 / 32768; const int stride = 10 * 588 * 2; const int npar = 8; @@ -25,6 +27,8 @@ namespace CUETools.TestParity static byte[] parity; static uint crc; const int offset = 48; + static AccurateRipVerify ar; + static CDImageLayout toc; //const int offset = 5 * 588 - 5; //const int offset = 2000; @@ -54,6 +58,9 @@ namespace CUETools.TestParity [ClassInitialize()] public static void MyClassInitialize(TestContext testContext) { + toc = new CDImageLayout(1, 1, 1, string.Format("0 {0}", (finalSampleCount / 588).ToString())); + ar = new AccurateRipVerify(toc, null); + new Random(2423).NextBytes(wav); new Random(2423).NextBytes(wav2); Random rnd = new Random(987); @@ -61,10 +68,12 @@ namespace CUETools.TestParity wav2[(int)(rnd.NextDouble() * (wav2.Length - 1))] = (byte)(rnd.NextDouble() * 255); AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); - CDRepairEncode encode = new CDRepairEncode(finalSampleCount, stride, npar, false, true); + CDRepairEncode encode = new CDRepairEncode(finalSampleCount, stride, npar, false, true, ar); buff.Prepare(wav, finalSampleCount); encode.Write(buff); encode.Close(); + ar.Init(); + ar.Write(buff); parity = encode.Parity; crc = encode.CRC; } @@ -97,10 +106,12 @@ namespace CUETools.TestParity public void CDRepairDecodeOriginalTest() { AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); - CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false); + CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false, ar); buff.Prepare(wav, finalSampleCount); decode.Write(buff); decode.Close(); + ar.Init(); + ar.Write(buff); int actualOffset; bool hasErrors; Assert.IsTrue(decode.FindOffset(npar, parity, 0, crc, out actualOffset, out hasErrors)); @@ -115,10 +126,12 @@ namespace CUETools.TestParity public void CDRepairDecodeModifiedTest() { AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); - CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false); + CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false, ar); buff.Prepare(wav2, finalSampleCount); decode.Write(buff); decode.Close(); + ar.Init(); + ar.Write(buff); int actualOffset; bool hasErrors; Assert.IsTrue(decode.FindOffset(npar, parity, 0, crc, out actualOffset, out hasErrors)); @@ -136,9 +149,11 @@ namespace CUETools.TestParity public void CDRepairDecodePositiveOffsetTest() { AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); - CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false); + CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false, ar); Array.Copy(wav, offset * 4, wav3, 0, (finalSampleCount - offset) * 4); buff.Prepare(wav3, finalSampleCount); + ar.Init(); + ar.Write(buff); decode.Write(buff); decode.Close(); int actualOffset; @@ -155,10 +170,13 @@ namespace CUETools.TestParity public void CDRepairDecodeNegativeOffsetTest() { AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); - CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false); + CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false, ar); + ar.Init(); buff.Prepare(new byte[offset * 4], offset); + ar.Write(buff); decode.Write(buff); buff.Prepare(wav, finalSampleCount - offset); + ar.Write(buff); decode.Write(buff); decode.Close(); int actualOffset; @@ -175,9 +193,11 @@ namespace CUETools.TestParity public void CDRepairDecodePositiveOffsetErrorsTest() { AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); - CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false); + CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false, ar); Array.Copy(wav2, offset * 4, wav3, 0, (finalSampleCount - offset) * 4); buff.Prepare(wav3, finalSampleCount); + ar.Init(); + ar.Write(buff); decode.Write(buff); decode.Close(); int actualOffset; @@ -197,10 +217,13 @@ namespace CUETools.TestParity public void CDRepairDecodeNegativeOffsetErrorsTest() { AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); - CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false); + CDRepairEncode decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false, ar); buff.Prepare(new byte[offset * 4], offset); + ar.Init(); + ar.Write(buff); decode.Write(buff); buff.Prepare(wav2, finalSampleCount - offset); + ar.Write(buff); decode.Write(buff); decode.Close(); int actualOffset; diff --git a/CUETools/CUETools.TestParity/CDRepairEncodeTest.cs b/CUETools/CUETools.TestParity/CDRepairEncodeTest.cs index 51139a3..3a29568 100644 --- a/CUETools/CUETools.TestParity/CDRepairEncodeTest.cs +++ b/CUETools/CUETools.TestParity/CDRepairEncodeTest.cs @@ -1,6 +1,8 @@ using System; using CUETools.CDRepair; using Microsoft.VisualStudio.TestTools.UnitTesting; +using CUETools.AccurateRip; +using CUETools.CDImage; using CUETools.Codecs; namespace CUETools.TestParity @@ -32,6 +34,8 @@ namespace CUETools.TestParity const int npar = 8; static byte[] wav = new byte[finalSampleCount * 4]; + static AccurateRipVerify ar; + static CDImageLayout toc; private TestContext testContextInstance; @@ -59,6 +63,8 @@ namespace CUETools.TestParity [ClassInitialize()] public static void MyClassInitialize(TestContext testContext) { + toc = new CDImageLayout(1, 1, 1, string.Format("0 {0}", (finalSampleCount / 588).ToString())); + ar = new AccurateRipVerify(toc, null); new Random(2423).NextBytes(wav); } @@ -90,8 +96,10 @@ namespace CUETools.TestParity public void CDRepairEncodeWriteTest() { AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); - CDRepairEncode encode = new CDRepairEncode(finalSampleCount, stride, npar, false, true); + CDRepairEncode encode = new CDRepairEncode(finalSampleCount, stride, npar, false, true, ar); buff.Prepare(wav, finalSampleCount); + ar.Init(); + ar.Write(buff); encode.Write(buff); encode.Close(); Assert.AreEqual(8, encode.Parity[0]); diff --git a/CUETools/CUETools.TestParity/CDRepairTest.cs b/CUETools/CUETools.TestParity/CDRepairTest.cs index dd81ef0..53f2b10 100644 --- a/CUETools/CUETools.TestParity/CDRepairTest.cs +++ b/CUETools/CUETools.TestParity/CDRepairTest.cs @@ -1,6 +1,8 @@ using System; using CUETools.Codecs; using CUETools.CDRepair; +using CUETools.AccurateRip; +using CUETools.CDImage; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace CUETools.TestParity { @@ -30,6 +32,8 @@ namespace CUETools.TestParity static CDRepairFix fix; static CDRepairFix fix2; const int offset = 48; + static AccurateRipVerify ar, ar2; + static CDImageLayout toc; /// ///Gets or sets the test context which provides @@ -55,6 +59,10 @@ namespace CUETools.TestParity [ClassInitialize()] public static void MyClassInitialize(TestContext testContext) { + toc = new CDImageLayout(1, 1, 1, string.Format("0 {0}", (finalSampleCount / 588).ToString())); + ar = new AccurateRipVerify(toc, null); + ar2 = new AccurateRipVerify(toc, null); + new Random(2423).NextBytes(wav); new Random(2423).NextBytes(wav2); Random rnd = new Random(987); @@ -62,14 +70,16 @@ namespace CUETools.TestParity wav2[(int)(rnd.NextDouble() * (wav2.Length - 1))] = (byte)(rnd.NextDouble() * 255); AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0); - CDRepairEncode encode = new CDRepairEncode(finalSampleCount, stride, npar, false, true); + CDRepairEncode encode = new CDRepairEncode(finalSampleCount, stride, npar, false, true, ar); buff.Prepare(wav, finalSampleCount); + ar.Init(); + ar.Write(buff); encode.Write(buff); encode.Close(); parity = encode.Parity; crc = encode.CRC; - decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false); + decode = new CDRepairEncode(finalSampleCount, stride, npar, true, false, ar); buff.Prepare(wav2, finalSampleCount); decode.Write(buff); decode.Close(); @@ -79,10 +89,13 @@ namespace CUETools.TestParity decode.FindOffset(npar, parity, 0, crc, out actualOffset, out hasErrors); fix = decode.VerifyParity(parity, actualOffset); - decode2 = new CDRepairEncode(finalSampleCount, stride, npar, true, false); + decode2 = new CDRepairEncode(finalSampleCount, stride, npar, true, false, ar2); buff.Prepare(new byte[offset * 4], offset); + ar2.Init(); + ar2.Write(buff); decode2.Write(buff); buff.Prepare(wav2, finalSampleCount - offset); + ar2.Write(buff); decode2.Write(buff); decode2.Close(); decode2.FindOffset(npar, parity, 0, crc, out actualOffset, out hasErrors); diff --git a/CUETools/CUETools.TestParity/CUETools.TestParity.csproj b/CUETools/CUETools.TestParity/CUETools.TestParity.csproj index 38f5795..1977af5 100644 --- a/CUETools/CUETools.TestParity/CUETools.TestParity.csproj +++ b/CUETools/CUETools.TestParity/CUETools.TestParity.csproj @@ -50,9 +50,14 @@ - - - + + {5802C7E9-157E-4124-946D-70B5AE48A5A1} + CUETools.AccurateRip + + + {1DD41038-D885-46C5-8DDE-E0B82F066584} + CUETools.CDImage + {C4869B37-EBB1-47BB-9406-B1209BEAB84B} CUETools.CDRepair diff --git a/CUETools/frmBatch.Designer.cs b/CUETools/frmBatch.Designer.cs index ab319ea..2db3446 100644 --- a/CUETools/frmBatch.Designer.cs +++ b/CUETools/frmBatch.Designer.cs @@ -33,13 +33,12 @@ namespace JDP this.txtInputFile = new System.Windows.Forms.TextBox(); this.txtOutputFile = new System.Windows.Forms.TextBox(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.tableLayoutPanel1.SuspendLayout(); this.SuspendLayout(); // // progressBar2 // - this.progressBar2.Location = new System.Drawing.Point(3, 29); + this.progressBar2.Location = new System.Drawing.Point(3, 3); this.progressBar2.MinimumSize = new System.Drawing.Size(440, 20); this.progressBar2.Name = "progressBar2"; this.progressBar2.Size = new System.Drawing.Size(609, 20); @@ -49,7 +48,7 @@ namespace JDP // this.textBox1.BackColor = System.Drawing.SystemColors.Control; this.textBox1.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.textBox1.Location = new System.Drawing.Point(3, 115); + this.textBox1.Location = new System.Drawing.Point(3, 75); this.textBox1.MaxLength = 0; this.textBox1.MinimumSize = new System.Drawing.Size(600, 200); this.textBox1.Multiline = true; @@ -63,7 +62,7 @@ namespace JDP // txtInputFile // this.txtInputFile.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.txtInputFile.Location = new System.Drawing.Point(5, 57); + this.txtInputFile.Location = new System.Drawing.Point(5, 31); this.txtInputFile.Margin = new System.Windows.Forms.Padding(5); this.txtInputFile.Name = "txtInputFile"; this.txtInputFile.ReadOnly = true; @@ -74,7 +73,7 @@ namespace JDP // txtOutputFile // this.txtOutputFile.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.txtOutputFile.Location = new System.Drawing.Point(5, 87); + this.txtOutputFile.Location = new System.Drawing.Point(5, 54); this.txtOutputFile.Margin = new System.Windows.Forms.Padding(5); this.txtOutputFile.Name = "txtOutputFile"; this.txtOutputFile.ReadOnly = true; @@ -91,30 +90,20 @@ namespace JDP this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.tableLayoutPanel1.ColumnCount = 1; this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.Controls.Add(this.textBox1, 0, 4); - this.tableLayoutPanel1.Controls.Add(this.progressBar1, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.progressBar2, 0, 1); - this.tableLayoutPanel1.Controls.Add(this.txtOutputFile, 0, 3); - this.tableLayoutPanel1.Controls.Add(this.txtInputFile, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.textBox1, 0, 3); + this.tableLayoutPanel1.Controls.Add(this.progressBar2, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.txtOutputFile, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.txtInputFile, 0, 1); this.tableLayoutPanel1.Location = new System.Drawing.Point(13, 13); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 5; + this.tableLayoutPanel1.RowCount = 4; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(619, 333); + this.tableLayoutPanel1.Size = new System.Drawing.Size(619, 293); this.tableLayoutPanel1.TabIndex = 7; // - // progressBar1 - // - this.progressBar1.Location = new System.Drawing.Point(3, 3); - this.progressBar1.MinimumSize = new System.Drawing.Size(440, 20); - this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(609, 20); - this.progressBar1.TabIndex = 0; - // // frmBatch // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -146,6 +135,5 @@ namespace JDP private System.Windows.Forms.TextBox txtInputFile; private System.Windows.Forms.TextBox txtOutputFile; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.ProgressBar progressBar1; } } \ No newline at end of file diff --git a/CUETools/frmBatch.cs b/CUETools/frmBatch.cs index bacfb6c..959990a 100644 --- a/CUETools/frmBatch.cs +++ b/CUETools/frmBatch.cs @@ -59,20 +59,20 @@ namespace JDP { this.BeginInvoke((MethodInvoker)delegate() { - if (e.percentDisk == 0) + if (e.percent == 0) { _startedAt = DateTime.Now; Text = e.status; } - else if (e.percentDisk > 0.02) + else if (e.percent > 0.02) { TimeSpan span = DateTime.Now - _startedAt; - TimeSpan eta = new TimeSpan ((long) (span.Ticks/e.percentDisk)); + TimeSpan eta = new TimeSpan ((long) (span.Ticks/e.percent)); Text = String.Format("{0}, ETA {1}:{2:00}.", e.status, (int)eta.TotalMinutes, eta.Seconds); } else Text = e.status; - progressBar1.Value = Math.Max(0,Math.Min(100,(int)(e.percentTrck*100))); - progressBar2.Value = Math.Max(0,Math.Min(100,(int)(e.percentDisk*100))); + //progressBar1.Value = Math.Max(0,Math.Min(100,(int)(e.percentTrck*100))); + progressBar2.Value = Math.Max(0,Math.Min(100,(int)(e.percent*100))); string inputSuffix = e.output != null ? "=>" : ""; if (e.input == null) txtInputFile.Text = inputSuffix; @@ -159,7 +159,6 @@ namespace JDP Text = "Done."; //TimeSpan span = DateTime.Now - _startedAt; - progressBar1.Value = 0; progressBar2.Value = 0; if (cueSheet.IsCD) { @@ -185,7 +184,6 @@ namespace JDP { Text = "Aborted."; textBox1.Text += "Aborted."; - progressBar1.Value = 0; progressBar2.Value = 0; }); } diff --git a/CUETools/frmCUETools.Designer.cs b/CUETools/frmCUETools.Designer.cs index 04cc7d9..1b5c09e 100644 --- a/CUETools/frmCUETools.Designer.cs +++ b/CUETools/frmCUETools.Designer.cs @@ -31,7 +31,6 @@ namespace JDP { this.toolStripStatusLabelProcessed = new System.Windows.Forms.ToolStripStatusLabel(); this.toolStripStatusLabelCTDB = new System.Windows.Forms.ToolStripStatusLabel(); this.toolStripStatusLabelAR = new System.Windows.Forms.ToolStripStatusLabel(); - this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar(); this.toolStripProgressBar2 = new System.Windows.Forms.ToolStripProgressBar(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.textBatchReport = new System.Windows.Forms.TextBox(); @@ -184,7 +183,6 @@ namespace JDP { this.toolStripStatusLabelProcessed, this.toolStripStatusLabelCTDB, this.toolStripStatusLabelAR, - this.toolStripProgressBar1, this.toolStripProgressBar2}); this.statusStrip1.Name = "statusStrip1"; this.statusStrip1.ShowItemToolTips = true; @@ -225,13 +223,6 @@ namespace JDP { this.toolStripStatusLabelAR.Name = "toolStripStatusLabelAR"; this.toolStripStatusLabelAR.Padding = new System.Windows.Forms.Padding(0, 0, 5, 0); // - // toolStripProgressBar1 - // - this.toolStripProgressBar1.AutoToolTip = true; - this.toolStripProgressBar1.Name = "toolStripProgressBar1"; - resources.ApplyResources(this.toolStripProgressBar1, "toolStripProgressBar1"); - this.toolStripProgressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous; - // // toolStripProgressBar2 // this.toolStripProgressBar2.AutoToolTip = true; @@ -1117,7 +1108,6 @@ namespace JDP { private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelProcessed; private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelAR; - private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1; private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar2; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; private System.Windows.Forms.ToolStripDropDownButton toolStripDropDownButtonProfile; diff --git a/CUETools/frmCUETools.cs b/CUETools/frmCUETools.cs index 68b5400..c700b0e 100644 --- a/CUETools/frmCUETools.cs +++ b/CUETools/frmCUETools.cs @@ -485,10 +485,7 @@ namespace JDP { { if (_profile._config.checkForUpdates && DateTime.UtcNow - lastMOTD > TimeSpan.FromDays(1) && _batchReport.Length == 0) { - this.Invoke((MethodInvoker)delegate() - { - toolStripStatusLabel1.Text = "Checking for updates..."; - }); + this.Invoke((MethodInvoker)(() => toolStripStatusLabel1.Text = "Checking for updates...")); HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://cuetools.net/motd/motd.jpg"); req.Method = "GET"; try @@ -595,8 +592,8 @@ namespace JDP { { pathIn = Path.GetFullPath(pathIn); List fileGroups = CUESheet.ScanFolder(_profile._config, Path.GetDirectoryName(pathIn)); - FileGroupInfo fileGroup = FileGroupInfo.WhichContains(fileGroups, pathIn, FileGroupInfoType.TrackFiles) - ?? FileGroupInfo.WhichContains(fileGroups, pathIn, FileGroupInfoType.FileWithCUE); + FileGroupInfo fileGroup = fileGroups.Find(f => f.type == FileGroupInfoType.TrackFiles && f.Contains(pathIn)) ?? + fileGroups.Find(f => f.type == FileGroupInfoType.FileWithCUE && f.Contains(pathIn)); if (fileGroup == null) throw new Exception("doesn't seem to be part of an album"); string cueSheetContents; @@ -964,33 +961,28 @@ namespace JDP { public void SetStatus(object sender, CUEToolsProgressEventArgs e) { this.BeginInvoke((MethodInvoker)delegate() { - if (e.percentDisk == 0) + if (e.percent == 0) { _startedAt = DateTime.Now; toolStripStatusLabelProcessed.Visible = false; - toolStripProgressBar1.ToolTipText = ""; toolStripProgressBar2.ToolTipText = ""; } - else if (e.percentDisk > 0.02) + else if (e.percent > 0.02) { TimeSpan span = DateTime.Now - _startedAt; - TimeSpan eta = new TimeSpan((long)(span.Ticks / e.percentDisk)); + TimeSpan eta = new TimeSpan((long)(span.Ticks / e.percent)); + string speedStr = ""; if (span.TotalSeconds > 0 && e.offset > 0) { double speed = e.offset / span.TotalSeconds / 44100; - toolStripProgressBar1.ToolTipText = String.Format("{0:00.00}x", speed); - } else - toolStripProgressBar1.ToolTipText = ""; + speedStr = String.Format("{0:00.00}x", speed); + } toolStripProgressBar2.ToolTipText = String.Format("{0}:{1:00}/{2}:{3:00}", (int)span.TotalMinutes, span.Seconds, (int)eta.TotalMinutes, eta.Seconds); - if (FileBrowserState != FileBrowserStateEnum.Hidden) - { - toolStripStatusLabelProcessed.Text = String.Format("{0}@{1}", toolStripProgressBar2.ToolTipText, toolStripProgressBar1.ToolTipText); - toolStripStatusLabelProcessed.Visible = true; - } + toolStripStatusLabelProcessed.Text = String.Format("{0}@{1}", toolStripProgressBar2.ToolTipText, speedStr); + toolStripStatusLabelProcessed.Visible = true; } toolStripStatusLabel1.Text = e.status; - toolStripProgressBar1.Value = Math.Max(0,Math.Min(100,(int)(e.percentTrck*100))); - toolStripProgressBar2.Value = Math.Max(0,Math.Min(100,(int)(e.percentDisk*100))); + toolStripProgressBar2.Value = Math.Max(0,Math.Min(100,(int)(e.percent*100))); }); } @@ -1023,7 +1015,6 @@ namespace JDP { btnStop.Visible = btnPause.Visible = running; btnResume.Visible = false; toolStripStatusLabel1.Text = String.Empty; - toolStripProgressBar1.Value = 0; toolStripProgressBar2.Value = 0; toolStripStatusLabelAR.Visible = false; toolStripStatusLabelCTDB.Visible = false; diff --git a/CUETools/frmCUETools.resx b/CUETools/frmCUETools.resx index e9f23f3..b0ce7f7 100644 --- a/CUETools/frmCUETools.resx +++ b/CUETools/frmCUETools.resx @@ -126,7 +126,7 @@ - 381, 21 + 503, 21 MiddleLeft @@ -168,12 +168,6 @@ Album found in AccurateRip database. - - 120, 20 - - - Track progress - 120, 20 @@ -258,21 +252,6 @@ 0 - - Top, Bottom, Left, Right - - - 19 - - - 3, 17 - - - 192, 304 - - - 1 - fileSystemTreeView1 @@ -318,9 +297,1032 @@ 3 + + 3, 17 + + + tableLayoutPanelCUEStyle + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + groupBoxMode + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="checkBoxUseAccurateRip" Row="4" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="checkBoxUseFreeDb" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="rbTracks" Row="2" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbEmbedCUE" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbSingleFile" Row="1" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="checkBoxUseMusicBrainz" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,33,33332,Percent,33,33334,Percent,33,33334" /><Rows Styles="Percent,18,18229,Percent,18,18229,Percent,18,18229,Percent,22,72658,Percent,22,72658" /></TableLayoutSettings> + + + toolStripCorrectorFormat + + + System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + groupBoxMode + + + 1 + + + tableLayoutPanelVerifyMode + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + groupBoxMode + + + 2 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="checkBoxVerifyUseCDRepair" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,36,11111,Percent,63,88889" /><Rows Styles="Percent,32,72727,Percent,67,27273" /></TableLayoutSettings> + + + Fill + + + 173, 101 + + + 150, 130 + + + 12 + + + Mode + + + groupBoxMode + + + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 0 + + + labelEncoderMaxMode + + + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 0 + + + labelEncoderMinMode + + + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 1 + + + labelEncoderMode + + + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 2 + + + trackBarEncoderMode + + + System.Windows.Forms.TrackBar, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 3 + + + comboBoxEncoder + + + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 4 + + + radioButtonAudioNone + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 5 + + + radioButtonAudioLossy + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 6 + + + radioButtonAudioHybrid + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 7 + + + radioButtonAudioLossless + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 8 + + + labelFormat + + + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 9 + + + comboBoxAudioFormat + + + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAudioOutput + + + 10 + + + Fill + + + 329, 101 + + + 148, 194 + + + 2 + + + Audio Output + + + grpAudioOutput + + + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 1 + + + Fill + + + NoControl + + + 3, 237 + + + 164, 90 + + + Zoom + + + 15 + + + pictureBoxMotd + + + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 2 + + + 2 + + + Fill + + + NoControl + + + 0, 48 + + + 0, 0, 0, 0 + + + 97, 24 + + + 13 + + + Template: + + + MiddleLeft + + + labelOutputTemplate + + + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelPaths + + + 0 + + + Fill + + + 100, 51 + + + 365, 21 + + + 9 + + + 153, 8 + + + Template for output files (foobar2000 format) + + + comboBoxOutputFormat + + + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelPaths + + + 1 + + + Fill + + + 100, 3 + + + 365, 21 + + + 0 + + + Input file + + + txtInputPath + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelPaths + + + 2 + + + Fill + + + 100, 27 + + + 365, 21 + + + 0 + + + Output file + + + txtOutputPath + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelPaths + + + 3 + + + 0, 0 + + + Fill + + + 0, 0 + + + 0, 0, 0, 0 + + + 97, 24 + + + 14 + + + toolStripInput + + + toolStripInput + + + System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelPaths + + + 4 + + + 0, 24 + + + Fill + + + 0, 24 + + + 0, 0, 0, 0 + + + 97, 24 + + + 15 + + + toolStripOutput + + + toolStripOutput + + + System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelPaths + + + 5 + + + Fill + + + 3, 17 + + + 0, 0, 0, 0 + + + 3 + + + 468, 72 + + + 14 + + + tableLayoutPanelPaths + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpOutputPathGeneration + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelOutputTemplate" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="comboBoxOutputFormat" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtInputPath" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtOutputPath" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="toolStripInput" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="toolStripOutput" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,20,94017,Percent,79,05983" /><Rows Styles="Percent,33,33333,Percent,33,33333,Percent,33,33333" /></TableLayoutSettings> + + + Fill + + + 3, 3 + + + 474, 92 + + + 1 + + + CUE Paths + + + grpOutputPathGeneration + + + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 3 + + + comboBoxScript + + + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAction + + + 0 + + + rbActionCorrectFilenames + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAction + + + 1 + + + rbActionCreateCUESheet + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAction + + + 2 + + + rbActionVerify + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAction + + + 3 + + + rbActionEncode + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpAction + + + 4 + + + Fill + + + 3, 101 + + + 164, 130 + + + 4 + + + Action + + + grpAction + + + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 4 + + + tableLayoutPanel4 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpExtra + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelPregap" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="lblWriteOffset" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="numericWriteOffset" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtPreGapLength" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="labelDataTrack" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="txtDataTrackLength" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,56,75676,Percent,43,24324" /><Rows Styles="Percent,33,33333,Percent,33,33333,Percent,33,33333" /></TableLayoutSettings> + + + Fill + + + 173, 237 + + + 150, 90 + + + 6 + + + Extra + + + grpExtra + + + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 5 + + + btnConvert + + + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panelGo + + + 0 + + + btnStop + + + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panelGo + + + 1 + + + btnResume + + + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panelGo + + + 2 + + + btnPause + + + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panelGo + + + 3 + + + Fill + + + 338, 301 + + + 12, 3, 12, 3 + + + 130, 26 + + + 14 + + + panelGo + + + System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel2 + + + 6 + + + Fill + + + 204, 0 + + + 0, 0, 0, 0 + + + 4 + + + 480, 330 + + + 1 + + + tableLayoutPanel2 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 2 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="groupBoxMode" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="grpAudioOutput" Row="1" RowSpan="2" Column="2" ColumnSpan="1" /><Control Name="pictureBoxMotd" Row="2" RowSpan="2" Column="0" ColumnSpan="1" /><Control Name="grpOutputPathGeneration" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="grpAction" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="grpExtra" Row="2" RowSpan="2" Column="1" ColumnSpan="1" /><Control Name="panelGo" Row="3" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="Percent,35,41667,Percent,32,70833,Percent,31,875" /><Rows Styles="Percent,29,69697,Percent,41,51515,Percent,19,39394,Percent,9,393939" /></TableLayoutSettings> + + + Fill + + + 0, 0 + + + 0, 0, 0, 0 + + + 2 + + + 684, 451 + + + 17 + + + tableLayoutPanel1 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + toolStripContainer1.ContentPanel + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="textBatchReport" Row="1" RowSpan="1" Column="0" ColumnSpan="2" /><Control Name="grpInput" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="tableLayoutPanel2" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,100,Absolute,480" /><Rows Styles="Absolute,330,Percent,100" /></TableLayoutSettings> + + + 0, 0, 0, 0 + + + 684, 451 + + + toolStripContainer1.ContentPanel + + + System.Windows.Forms.ToolStripContentPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + toolStripContainer1 + + + 0 + + + Fill + + + toolStripContainer1.LeftToolStripPanel + + + System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + toolStripContainer1 + + + 1 + + + 0, 0 + + + toolStripContainer1.RightToolStripPanel + + + System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + toolStripContainer1 + + + 2 + + + 684, 502 + + + 17 + + + toolStripContainer1 + + + 0, 0 + + + None + + + 0, 0 + + + 684, 25 + + + 0 + + + toolStripMenu + + + System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + toolStripContainer1.TopToolStripPanel + + + 0 + + + toolStripContainer1.TopToolStripPanel + + + System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + toolStripContainer1 + + + 3 + + + toolStripContainer1 + + + System.Windows.Forms.ToolStripContainer, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + Top, Bottom, Left, Right + + + 19 + + + 3, 17 + + + 192, 304 + + + 1 + + + fileSystemTreeView1 + + + CUEControls.FileSystemTreeView, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null + + + grpInput + + + 0 + 3 + + checkBoxUseAccurateRip + + + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelCUEStyle + + + 0 + + + checkBoxUseFreeDb + + + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelCUEStyle + + + 1 + + + rbTracks + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelCUEStyle + + + 2 + + + rbEmbedCUE + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelCUEStyle + + + 3 + + + rbSingleFile + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelCUEStyle + + + 4 + + + checkBoxUseMusicBrainz + + + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanelCUEStyle + + + 5 + + + Fill + + + 3, 17 + + + 0, 0, 0, 0 + + + 5 + + + 144, 110 + + + 11 + + + tableLayoutPanelCUEStyle + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + groupBoxMode + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="checkBoxUseAccurateRip" Row="4" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="checkBoxUseFreeDb" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="rbTracks" Row="2" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbEmbedCUE" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbSingleFile" Row="1" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="checkBoxUseMusicBrainz" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,33,33332,Percent,33,33334,Percent,33,33334" /><Rows Styles="Percent,18,18229,Percent,18,18229,Percent,18,18229,Percent,22,72658,Percent,22,72658" /></TableLayoutSettings> + + + 153, 8 + True @@ -342,9 +1344,6 @@ 5 - - 153, 8 - Use AccurateRip @@ -549,39 +1548,6 @@ 5 - - Fill - - - 3, 17 - - - 0, 0, 0, 0 - - - 5 - - - 144, 110 - - - 11 - - - tableLayoutPanelCUEStyle - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - groupBoxMode - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="checkBoxUseAccurateRip" Row="4" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="checkBoxUseFreeDb" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="rbTracks" Row="2" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbEmbedCUE" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbSingleFile" Row="1" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="checkBoxUseMusicBrainz" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,33,33332,Percent,33,33334,Percent,33,33334" /><Rows Styles="Percent,18,18229,Percent,18,18229,Percent,18,18229,Percent,22,72658,Percent,22,72658" /></TableLayoutSettings> - 3, 17 @@ -591,51 +1557,6 @@ Fill - - Magenta - - - 78, 20 - - - Overwrite - - - 168, 22 - - - Locate files - - - Try to locate missing files automatically - - - 168, 22 - - - Change extension - - - Replace extension for audio files with this: - - - Magenta - - - 79, 19 - - - Locate files - - - Magenta - - - 39, 19 - - - flac - 3, 17 @@ -660,27 +1581,54 @@ 1 + + Magenta + + + 78, 20 + + + Overwrite + + + Magenta + + + 79, 19 + + + Locate files + + + 168, 22 + + + Locate files + + + Try to locate missing files automatically + + + 168, 22 + + + Change extension + + + Replace extension for audio files with this: + + + Magenta + + + 39, 19 + + + flac + 2 - - True - - - Fill - - - NoControl - - - 3, 3 - - - 45, 29 - - - 0 - checkBoxVerifyUseCDRepair @@ -726,31 +1674,34 @@ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="checkBoxVerifyUseCDRepair" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,36,11111,Percent,63,88889" /><Rows Styles="Percent,32,72727,Percent,67,27273" /></TableLayoutSettings> - + + True + + Fill - - 173, 101 + + NoControl - - 150, 130 + + 3, 3 - - 12 + + 45, 29 - - Mode + + 0 - - groupBoxMode + + checkBoxVerifyUseCDRepair - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - tableLayoutPanel2 + + tableLayoutPanelVerifyMode - + 0 @@ -1113,195 +2064,21 @@ 10 - - Fill - - - 329, 101 - - - 148, 194 - - - 2 - - - Audio Output - - - grpAudioOutput - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel2 - - - 1 - - - Fill - - - NoControl - - - 3, 237 - - - 164, 90 - - - Zoom - - - 15 - - - pictureBoxMotd - - - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel2 - - - 2 - - - 2 - - - Fill - - - NoControl - - - 0, 48 - - - 0, 0, 0, 0 - - - 97, 24 - - - 13 - - - Template: - - - MiddleLeft - - - labelOutputTemplate - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanelPaths - - - 0 - - - Fill - - - 100, 51 - - - 365, 21 - - - 9 - - - Template for output files (foobar2000 format) - - - comboBoxOutputFormat - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanelPaths - - - 1 - - - Fill - - - 100, 3 - - - 365, 21 - - - 0 - - - Input file - - - txtInputPath - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanelPaths - - - 2 - - - Fill - - - 100, 27 - - - 365, 21 - - - 0 - - - Output file - - - txtOutputPath - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanelPaths - - - 3 - - - 0, 0 - - - Fill - 38, 21 Input: + + Magenta + + + 32, 21 + + + Open/close input browser + 177, 22 @@ -1326,54 +2103,21 @@ Hide browser - - Magenta - - - 32, 21 - - - Open/close input browser - - - 0, 0 - - - 0, 0, 0, 0 - - - 97, 24 - - - 14 - - - toolStripInput - - - toolStripInput - - - System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanelPaths - - - 4 - - - 0, 24 - - - Fill - 48, 24 Output: + + Magenta + + + 32, 21 + + + toolStripSplitButtonOutputBrowser + 143, 22 @@ -1392,102 +2136,6 @@ Use template - - Magenta - - - 32, 21 - - - toolStripSplitButtonOutputBrowser - - - 0, 24 - - - 0, 0, 0, 0 - - - 97, 24 - - - 15 - - - toolStripOutput - - - toolStripOutput - - - System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanelPaths - - - 5 - - - Fill - - - 3, 17 - - - 0, 0, 0, 0 - - - 3 - - - 468, 72 - - - 14 - - - tableLayoutPanelPaths - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - grpOutputPathGeneration - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelOutputTemplate" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="comboBoxOutputFormat" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtInputPath" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtOutputPath" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="toolStripInput" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="toolStripOutput" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,20,94017,Percent,79,05983" /><Rows Styles="Percent,33,33333,Percent,33,33333,Percent,33,33333" /></TableLayoutSettings> - - - Fill - - - 3, 3 - - - 474, 92 - - - 1 - - - CUE Paths - - - grpOutputPathGeneration - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel2 - - - 3 - Top, Left, Right @@ -1647,36 +2295,114 @@ 4 - - Fill - - - 3, 101 - - - 164, 130 - - - 4 - - - Action - - - grpAction - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel2 - - - 4 - 2 + + labelPregap + + + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel4 + + + 0 + + + lblWriteOffset + + + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel4 + + + 1 + + + numericWriteOffset + + + System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel4 + + + 2 + + + txtPreGapLength + + + System.Windows.Forms.MaskedTextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel4 + + + 3 + + + labelDataTrack + + + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel4 + + + 4 + + + txtDataTrackLength + + + System.Windows.Forms.MaskedTextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel4 + + + 5 + + + Fill + + + 3, 17 + + + 0, 0, 0, 0 + + + 3 + + + 144, 70 + + + 6 + + + tableLayoutPanel4 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + grpExtra + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelPregap" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="lblWriteOffset" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="numericWriteOffset" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtPreGapLength" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="labelDataTrack" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="txtDataTrackLength" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,56,75676,Percent,43,24324" /><Rows Styles="Percent,33,33333,Percent,33,33333,Percent,33,33333" /></TableLayoutSettings> + True @@ -1881,66 +2607,6 @@ 5 - - Fill - - - 3, 17 - - - 0, 0, 0, 0 - - - 3 - - - 144, 70 - - - 6 - - - tableLayoutPanel4 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - grpExtra - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelPregap" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="lblWriteOffset" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="numericWriteOffset" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtPreGapLength" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="labelDataTrack" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="txtDataTrackLength" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,56,75676,Percent,43,24324" /><Rows Styles="Percent,33,33333,Percent,33,33333,Percent,33,33333" /></TableLayoutSettings> - - - Fill - - - 173, 237 - - - 150, 90 - - - 6 - - - Extra - - - grpExtra - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel2 - - - 5 - Fill @@ -2079,161 +2745,17 @@ 3 - - Fill + + Magenta - - 338, 301 + + 73, 22 - - 12, 3, 12, 3 + + default - - 130, 26 - - - 14 - - - panelGo - - - System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel2 - - - 6 - - - Fill - - - 204, 0 - - - 0, 0, 0, 0 - - - 4 - - - 480, 330 - - - 1 - - - tableLayoutPanel2 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 2 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="groupBoxMode" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="grpAudioOutput" Row="1" RowSpan="2" Column="2" ColumnSpan="1" /><Control Name="pictureBoxMotd" Row="2" RowSpan="2" Column="0" ColumnSpan="1" /><Control Name="grpOutputPathGeneration" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="grpAction" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="grpExtra" Row="2" RowSpan="2" Column="1" ColumnSpan="1" /><Control Name="panelGo" Row="3" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="Percent,35,41667,Percent,32,70833,Percent,31,875" /><Rows Styles="Percent,29,69697,Percent,41,51515,Percent,19,39394,Percent,9,393939" /></TableLayoutSettings> - - - Fill - - - 0, 0 - - - 0, 0, 0, 0 - - - 2 - - - 684, 451 - - - 17 - - - tableLayoutPanel1 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - toolStripContainer1.ContentPanel - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="textBatchReport" Row="1" RowSpan="1" Column="0" ColumnSpan="2" /><Control Name="grpInput" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="tableLayoutPanel2" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,100,Absolute,480" /><Rows Styles="Absolute,330,Percent,100" /></TableLayoutSettings> - - - 0, 0, 0, 0 - - - 684, 451 - - - toolStripContainer1.ContentPanel - - - System.Windows.Forms.ToolStripContentPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - toolStripContainer1 - - - 0 - - - Fill - - - toolStripContainer1.LeftToolStripPanel - - - System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - toolStripContainer1 - - - 1 - - - 0, 0 - - - toolStripContainer1.RightToolStripPanel - - - System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - toolStripContainer1 - - - 2 - - - 684, 502 - - - 17 - - - toolStripContainer1 - - - 0, 0 - - - None + + Profile 100, 23 @@ -2259,18 +2781,6 @@ default - - Magenta - - - 73, 22 - - - default - - - Profile - 6, 25 @@ -2313,54 +2823,18 @@ Batch log - - 0, 0 - - - 684, 25 - - - 0 - - - toolStripMenu - - - System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - toolStripContainer1.TopToolStripPanel - - - 0 - - - toolStripContainer1.TopToolStripPanel - - - System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - toolStripContainer1 - - - 3 - - - toolStripContainer1 - - - System.Windows.Forms.ToolStripContainer, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - 424, 8 + + 206, 76 + + + contextMenuStripFileTree + + + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + False @@ -2385,15 +2859,6 @@ Reset to original location - - 206, 76 - - - contextMenuStripFileTree - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - True @@ -2836,12 +3301,6 @@ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - toolStripProgressBar1 - - - System.Windows.Forms.ToolStripProgressBar, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - toolStripProgressBar2