* LocalDB merged with file browser

* fixed hangup on truncated flac files
* optimized CRC32 calculations
This commit is contained in:
chudov
2011-04-10 18:16:26 +00:00
parent 89caa7858e
commit c4a5a465ef
14 changed files with 1661 additions and 1196 deletions

View File

@@ -27,9 +27,9 @@ namespace CUETools.AccurateRip
{
int offset = 64 * 64;
for (int i = 0; i < 64; i++)
this.val[i] = ar.CTDBCRC(offset + i * 64 + 64, 2 * offset - 64 - i * 64);
this.val[i] = ar.CTDBCRC(0, (i + 1) * 64, offset, 2 * offset);
for (int i = 0; i < 64; i++)
this.val[i + 64] = ar.CTDBCRC(offset + 64 - 1 - i, 2 * offset - 64 + 1 + i);
this.val[i + 64] = ar.CTDBCRC(0, 63 - i, offset, 2 * offset);
}
public OffsetSafeCRCRecord(uint[] val)
@@ -287,10 +287,10 @@ namespace CUETools.AccurateRip
public uint CRC450(int iTrack, int oi)
{
uint crca = _CRCAR[iTrack + 1, 2 * maxOffset + 5 * 588 + oi];
uint crcb = _CRCAR[iTrack + 1, 2 * maxOffset + 6 * 588 + oi];
uint suma = _CRCSM[iTrack + 1, 2 * maxOffset + 5 * 588 + oi];
uint sumb = _CRCSM[iTrack + 1, 2 * maxOffset + 6 * 588 + oi];
uint crca = _CRCAR[iTrack + 1, 2 * maxOffset + 1 + 5 * 588 + oi];
uint crcb = _CRCAR[iTrack + 1, 2 * maxOffset + 1 + 6 * 588 + oi];
uint suma = _CRCSM[iTrack + 1, 2 * maxOffset + 1 + 5 * 588 + oi];
uint sumb = _CRCSM[iTrack + 1, 2 * maxOffset + 1 + 6 * 588 + oi];
uint offs = 450 * 588 + (uint)oi;
return crcb - crca - offs * (sumb - suma);
}
@@ -329,63 +329,21 @@ namespace CUETools.AccurateRip
uint crc = 0;
if (iTrack == 0)
{
// New idea:
// _CRC32[x, maxOffset] keeps crc state at track x boundary
// _CRC32[x, maxOffset +- offs] keeps crc state around track x boundary
// _CRC32[0, maxOffset] keeps crc state at disc end
// _CRC32[0, maxOffset + offs] keeps crc state around disc start
// _CRC32[0, maxOffset - offs] keeps crc state around disc end
//int t0len = (int)_toc[_toc.FirstAudio].Pregap * 588;
//int dlen = (int)_toc.AudioLength * 588;
//if (oi == 0)
//{
// // whole disc crc
// crc = _CRC32[0, maxOffset];
//}
//if (oi > 0)
//{
// // whole disc crc
// crc = _CRC32[0, maxOffset];
// // substract prefix
// // IDEA: copy _CRC32[1, maxOffset + oi - t0len] so we can always use _CRC32[0, maxOffset + oi] even if pregap is short
// if (oi >= t0len)
// crc = Crc32.Combine(_CRC32[1, maxOffset + oi - t0len], crc, (dlen - oi) * 4);
// else
// crc = Crc32.Combine(_CRC32[0, maxOffset + oi], crc, (dlen - oi) * 4);
// // add zero suffix
// crc = Crc32.Combine(crc, 0, oi * 4); // TODO: is crc(0) really 0?
//}
//if (oi < 0)
//{
// crc = _CRC32[0, maxOffset + oi];
// crc = Crc32.Combine(crc, 0, -oi * 4); // TODO: is crc(0) really 0?
//}
for (iTrack = 0; iTrack <= _toc.AudioTracks; iTrack++)
int dlen = (int)_toc.AudioLength * 588;
if (oi > 0)
{
int trackLength = (int)(iTrack > 0 ? _toc[iTrack + _toc.FirstAudio - 1].Length : _toc[_toc.FirstAudio].Pregap) * 588 * 4;
if (oi < 0 && iTrack == 0)
crc = Crc32.Combine(crc, 0, -oi * 4);
if (trackLength == 0)
continue;
if (oi > 0 && (iTrack == 0 || (iTrack == 1 && _toc[_toc.FirstAudio].Pregap == 0)))
{
// Calculate track CRC skipping first oi samples by 'subtracting' their CRC
crc = Crc32.Combine(_CRC32[iTrack, oi], _CRC32[iTrack, 0], trackLength - oi * 4);
}
else if (oi < 0 && iTrack == _toc.AudioTracks)
{
crc = Crc32.Combine(crc, _CRC32[iTrack, 2 * maxOffset + oi], trackLength + oi * 4);
}
else
{
crc = Crc32.Combine(crc, _CRC32[iTrack, 0], trackLength);
}
if (oi > 0 && iTrack == _toc.AudioTracks)
crc = Crc32.Combine(crc, 0, oi * 4);
// whole disc crc
crc = _CRC32[_toc.AudioTracks, 2 * maxOffset];
// - prefix
crc = Crc32.Combine(_CRC32[0, oi], crc, (dlen - oi) * 4);
// + zero suffix
crc = Crc32.Combine(crc, 0, oi * 4);
}
iTrack = 0;
else // if (oi <= 0)
{
crc = _CRC32[_toc.AudioTracks, 2 * maxOffset + oi];
}
// Use 0xffffffff as an initial state
crc ^= _CRCMASK[0];
}
@@ -394,23 +352,13 @@ namespace CUETools.AccurateRip
int trackLength = (int)(iTrack > 0 ? _toc[iTrack + _toc.FirstAudio - 1].Length : _toc[_toc.FirstAudio].Pregap) * 588 * 4;
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);
// Add oi samples from next track CRC
crc = Crc32.Combine(crc, 0, oi * 4);
if (iTrack < _toc.AudioTracks)
crc ^= _CRC32[iTrack + 1, oi];
crc = iTrack < _toc.AudioTracks ? _CRC32[iTrack + 1, oi]
: Crc32.Combine(_CRC32[iTrack, 2 * maxOffset], 0, oi * 4);
crc = Crc32.Combine(_CRC32[iTrack, oi], crc, trackLength);
}
else if (oi < 0)
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, 2 * maxOffset + oi], _CRC32[iTrack - 1, 0], -oi * 4);
// Add this track's CRC without last oi samples
crc = Crc32.Combine(crc, _CRC32[iTrack, 2 * maxOffset + oi], trackLength + oi * 4);
}
else // oi == 0
{
crc = _CRC32[iTrack, 0];
crc = Crc32.Combine(_CRC32[iTrack - 1, 2 * maxOffset + oi], _CRC32[iTrack, 2 * maxOffset + oi], trackLength);
}
// Use 0xffffffff as an initial state
crc ^= _CRCMASK[iTrack];
@@ -429,59 +377,47 @@ namespace CUETools.AccurateRip
{
if (_CacheCRCWN[iTrack, _arOffsetRange + oi] == 0)
{
uint crc = 0xffffffff;
uint crc;
int cnt;
if (iTrack == 0)
{
for (iTrack = 0; iTrack <= _toc.AudioTracks; iTrack++)
if (oi > 0)
{
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);
// whole disc crc
cnt = _CRCNL[_toc.AudioTracks, 2 * maxOffset] * 2;
crc = _CRCWN[_toc.AudioTracks, 2 * maxOffset];
// - prefix
cnt -= _CRCNL[0, oi] * 2;
crc = Crc32.Combine(_CRCWN[0, oi], crc, cnt);
}
iTrack = 0;
else // if (oi <= 0)
{
cnt = _CRCNL[_toc.AudioTracks, 2 * maxOffset + oi] * 2;
crc = _CRCWN[_toc.AudioTracks, 2 * maxOffset + oi];
}
}
else
{
int trackLength = (int)(iTrack > 0 ? _toc[iTrack + _toc.FirstAudio - 1].Length : _toc[_toc.FirstAudio].Pregap) * 588 * 4;
if (oi > 0)
{
int nonzeroPrevLength = trackLength - oi * 4 -
(_CRCNL[iTrack, 0] - _CRCNL[iTrack, oi]) * 2;
// Calculate track CRC skipping first oi samples by 'subtracting' their CRC
crc = Crc32.Combine(
_CRCWN[iTrack, oi],
_CRCWN[iTrack, 0],
nonzeroPrevLength);
// Use 0xffffffff as an initial state
crc = Crc32.Combine(0xffffffff, crc, nonzeroPrevLength);
// Add oi samples from next track CRC
if (iTrack < _toc.AudioTracks)
crc = Crc32.Combine(crc,
_CRCWN[iTrack + 1, oi],
oi * 4 - _CRCNL[iTrack + 1, oi] * 2);
cnt = (iTrack < _toc.AudioTracks ? _CRCNL[iTrack + 1, oi] : _CRCNL[iTrack, 2 * maxOffset]) * 2;
crc = iTrack < _toc.AudioTracks ? _CRCWN[iTrack + 1, oi] : _CRCWN[iTrack, 2 * maxOffset];
cnt -= _CRCNL[iTrack, oi] * 2;
crc = Crc32.Combine(_CRCWN[iTrack, oi], crc, cnt);
}
else if (oi < 0)
else //if (oi <= 0)
{
int nonzeroPrevLength = -oi * 4 -
(_CRCNL[iTrack - 1, 0] - _CRCNL[iTrack - 1, 2 * maxOffset + oi]) * 2;
// Calculate CRC of previous track's last oi samples by 'subtracting' it's last CRCs
crc = Crc32.Combine(
_CRCWN[iTrack - 1, 2 * maxOffset + oi],
_CRCWN[iTrack - 1, 0],
nonzeroPrevLength);
// Use 0xffffffff as an initial state
crc = Crc32.Combine(0xffffffff, crc, nonzeroPrevLength);
// Add this track's CRC without last oi samples
crc = Crc32.Combine(crc,
_CRCWN[iTrack, 2 * maxOffset + oi],
trackLength + oi * 4 - _CRCNL[iTrack, 2 * maxOffset + oi] * 2);
}
else // oi == 0
{
// Use 0xffffffff as an initial state
crc = Crc32.Combine(0xffffffff, _CRCWN[iTrack, 0], trackLength - _CRCNL[iTrack, 0] * 2);
cnt = _CRCNL[iTrack, 2 * maxOffset + oi] * 2;
crc = _CRCWN[iTrack, 2 * maxOffset + oi];
cnt -= _CRCNL[iTrack - 1, 2 * maxOffset + oi] * 2;
crc = Crc32.Combine(_CRCWN[iTrack - 1, 2 * maxOffset + oi], crc, cnt);
}
}
// Use 0xffffffff as an initial state
crc = Crc32.Combine(0xffffffff, crc, cnt);
_CacheCRCWN[iTrack, _arOffsetRange + oi] = crc ^ 0xffffffff;
}
return _CacheCRCWN[iTrack, _arOffsetRange + oi];
@@ -503,7 +439,6 @@ namespace CUETools.AccurateRip
private int maxOffset;
internal ushort[] leadin;
internal ushort[] leadout;
private uint preLeadoutCrc;
private int stride = 1, laststride = 1, stridecount = 1, npar = 1;
private bool calcSyn = false;
private bool calcParity = false;
@@ -523,38 +458,56 @@ namespace CUETools.AccurateRip
Init(_toc);
}
public unsafe uint CTDBCRC(int prefixSamples, int suffixSamples)
public unsafe uint CTDBCRC(int iTrack, int oi, int prefixSamples, int suffixSamples)
{
if (prefixSamples > maxOffset || suffixSamples > maxOffset)
prefixSamples += oi;
suffixSamples -= oi;
if (prefixSamples < 0 || prefixSamples >= maxOffset || suffixSamples < 0 || suffixSamples > maxOffset)
throw new ArgumentOutOfRangeException();
int discLen = (int)_toc.AudioLength * 588;
int lastTrackLen = (int)_toc[_toc.FirstAudio + (int)_toc.AudioTracks - 1].Length * 588;
int trackOneBorder = (int)_toc[_toc.FirstAudio].Pregap * 588;
if (preLeadoutCrc == 0)
uint crc;
if (iTrack == 0)
{
preLeadoutCrc = CRC32(0, 0) ^ _CRCMASK[0];
preLeadoutCrc = Crc32.Substract(preLeadoutCrc, _CRC32[_toc.AudioTracks, 0], lastTrackLen * 4);
int discLen = (int)_toc.AudioLength * 588;
int chunkLen = discLen - prefixSamples - suffixSamples;
crc = Crc32.Combine(
_CRC32[0, prefixSamples],
_CRC32[_toc.AudioTracks, 2 * maxOffset - suffixSamples],
chunkLen * 4);
return Crc32.Combine(0xffffffff, crc, chunkLen * 4) ^ 0xffffffff;
}
uint crcA = prefixSamples == 0 ? 0
: prefixSamples < trackOneBorder ? _CRC32[0, prefixSamples]
: trackOneBorder == 0 ? _CRC32[1, prefixSamples - trackOneBorder]
: Crc32.Combine(_CRC32[0, 0], _CRC32[1, prefixSamples - trackOneBorder], (prefixSamples - trackOneBorder) * 4);
if (_toc.AudioTracks == 1)
int posA = (int)_toc[iTrack + _toc.FirstAudio - 1].Start * 588 + (iTrack > 1 ? oi : prefixSamples);
int posB = iTrack < _toc.AudioTracks ?
(int)_toc[iTrack + 1 + _toc.FirstAudio - 1].Start * 588 + oi :
(int)_toc.AudioLength * 588 - suffixSamples;
uint crcA, crcB;
if (oi > 0)
{
uint crcY = Crc32.Combine(crcA, _CRC32[_toc.AudioTracks, 2 * maxOffset - suffixSamples], (discLen - prefixSamples - suffixSamples) * 4);
return Crc32.Combine(0xffffffff, crcY, (discLen - prefixSamples - suffixSamples) * 4) ^ 0xffffffff;
crcA = iTrack > 1 ?
_CRC32[iTrack, oi]:
_CRC32[iTrack, prefixSamples];
crcB = iTrack < _toc.AudioTracks ?
_CRC32[iTrack + 1, oi] :
_CRC32[iTrack, maxOffset * 2 - suffixSamples];
}
uint crcXE = Crc32.Combine(crcA, preLeadoutCrc, (discLen - prefixSamples - lastTrackLen) * 4);
uint crcX = Crc32.Combine(crcXE, _CRC32[_toc.AudioTracks, 2 * maxOffset - suffixSamples], (lastTrackLen - suffixSamples) * 4);
return Crc32.Combine(0xffffffff, crcX, (discLen - prefixSamples - suffixSamples) * 4) ^ 0xffffffff;
else //if (oi <= 0)
{
crcA = iTrack > 1 ?
_CRC32[iTrack - 1, maxOffset * 2 + oi] :
_CRC32[iTrack, prefixSamples];
crcB = iTrack < _toc.AudioTracks ?
_CRC32[iTrack, maxOffset * 2 + oi] :
_CRC32[iTrack, maxOffset * 2 - suffixSamples];
}
crc = Crc32.Combine(crcA, crcB, (posB - posA) * 4);
// Use 0xffffffff as an initial state
crc = Crc32.Combine(0xffffffff, crc, (posB - posA) * 4) ^ 0xffffffff;
return crc;
}
public uint CTDBCRC(int actualOffset)
public uint CTDBCRC(int offset)
{
return CTDBCRC(stride / 2 - actualOffset, laststride / 2 + actualOffset);
return CTDBCRC(0, offset, stride / 2, laststride / 2);
}
private unsafe static void CalcSyn8(ushort* exp, ushort* log, ushort* syn, uint lo, uint n, int npar)
@@ -645,11 +598,12 @@ namespace CUETools.AccurateRip
bool doPar = currentStride >= 1 && currentStride <= stridecount && calcParity;
uint n = (uint)(stridecount - currentStride);
int crcTrack = _currentTrack + (_samplesDoneTrack == 0 && _currentTrack > 0 ? -1 : 0);
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];
uint crc32 = _CRC32[crcTrack, 2 * maxOffset];
uint crcwn = _CRCWN[crcTrack, 2 * maxOffset];
int crcnl = _CRCNL[crcTrack, 2 * maxOffset];
uint crcv2 = _CRCV2[_currentTrack, 0];
int peak = _Peak[_currentTrack];
@@ -678,8 +632,8 @@ namespace CUETools.AccurateRip
{
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ lo)];
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ (lo >> 8))];
crcnl++;
}
else crcnl++;
int pk = ((int)(lo << 16)) >> 16;
peak = Math.Max(peak, (pk << 1) ^ (pk >> 31));
@@ -694,8 +648,8 @@ namespace CUETools.AccurateRip
{
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ hi)];
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ (hi >> 8))];
crcnl++;
}
else crcnl++;
pk = ((int)(hi << 16)) >> 16;
peak = Math.Max(peak, (pk << 1) ^ (pk >> 31));
@@ -706,9 +660,9 @@ namespace CUETools.AccurateRip
_CRCAR[_currentTrack, 0] = crcar;
_CRCSM[_currentTrack, 0] = crcsm;
_CRC32[_currentTrack, 0] = crc32;
_CRCWN[_currentTrack, 0] = crcwn;
_CRCNL[_currentTrack, 0] = crcnl;
_CRC32[_currentTrack, 2 * maxOffset] = crc32;
_CRCWN[_currentTrack, 2 * maxOffset] = crcwn;
_CRCNL[_currentTrack, 2 * maxOffset] = crcnl;
_CRCV2[_currentTrack, 0] = crcv2;
_Peak[_currentTrack] = peak;
}
@@ -773,7 +727,7 @@ namespace CUETools.AccurateRip
int offset = _samplesDoneTrack < maxOffset ? _samplesDoneTrack
: _samplesRemTrack <= maxOffset ? 2 * maxOffset - _samplesRemTrack
: _samplesDoneTrack >= 445 * 588 && _samplesDoneTrack <= 455 * 588 ? 2 * maxOffset + _samplesDoneTrack - 445 * 588
: _samplesDoneTrack >= 445 * 588 && _samplesDoneTrack <= 455 * 588 ? 2 * maxOffset + 1 + _samplesDoneTrack - 445 * 588
: -1;
CalculateCRCs(t, exp, log, synptr, wr, samples, copyCount, offset);
@@ -784,15 +738,26 @@ namespace CUETools.AccurateRip
Array.Copy(_CRC32, _currentTrack * 3 * maxOffset + _samplesDoneTrack,
_CRC32, _currentTrack * 3 * maxOffset + 2 * maxOffset - _samplesRemTrack,
copyCount);
Array.Copy(_CRCWN, _currentTrack * 3 * maxOffset + _samplesDoneTrack,
_CRCWN, _currentTrack * 3 * maxOffset + 2 * maxOffset - _samplesRemTrack,
copyCount);
Array.Copy(_CRCNL, _currentTrack * 3 * maxOffset + _samplesDoneTrack,
_CRCNL, _currentTrack * 3 * maxOffset + 2 * maxOffset - _samplesRemTrack,
copyCount);
}
// duplicate prefix to pregap
if (_sampleCount < maxOffset && _currentTrack == 1)
{
Array.Copy(_CRC32, _currentTrack * 3 * maxOffset + _samplesDoneTrack,
_CRC32, _sampleCount,
copyCount);
Array.Copy(_CRCWN, _currentTrack * 3 * maxOffset + _samplesDoneTrack,
_CRCWN, _sampleCount,
copyCount);
Array.Copy(_CRCNL, _currentTrack * 3 * maxOffset + _samplesDoneTrack,
_CRCNL, _sampleCount,
copyCount);
}
//// duplicate prefix to pregap
//// be careful here not overwrite _CRC32[0, maxOffset] which can hold disc CRC in the future!!!
//if (_sampleCount < maxOffset && _currentTrack == 1)
//{
// Array.Copy(_CRC32, _currentTrack * 3 * maxOffset + _samplesDoneTrack,
// _CRC32, _sampleCount,
// copyCount);
//}
pos += copyCount;
_samplesRemTrack -= copyCount;
@@ -823,6 +788,22 @@ namespace CUETools.AccurateRip
if (currentOffset >= start && currentOffset < end)
this.leadout[i] = part.leadout[i];
}
int iSplitTrack = -1;
for (int iTrack = 0; iTrack <= _toc.AudioTracks; iTrack++)
{
int tempLocation = (int)(iTrack == 0 ? 0 : _toc[_toc.FirstAudio + iTrack - 1].Start - _toc[_toc.FirstAudio][0].Start) * 588;
int tempLen = (int)(iTrack == 0 ? _toc[_toc.FirstAudio].Pregap : _toc[_toc.FirstAudio + iTrack - 1].Length) * 588;
if (start > tempLocation && start <= tempLocation + tempLen)
{
iSplitTrack = iTrack;
break;
}
}
uint crc32 = _CRC32[iSplitTrack, 2 * maxOffset];
uint crcwn = _CRCWN[iSplitTrack, 2 * maxOffset];
int crcnl = _CRCNL[iSplitTrack, 2 * maxOffset];
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;
@@ -836,39 +817,32 @@ namespace CUETools.AccurateRip
uint crcar = _CRCAR[iTrack, 0];
uint crcv2 = _CRCV2[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]);
_CRCV2[iTrack, 0] = crcv2 + part._CRCV2[iTrack, 0];
for (int i = 1; i < 3 * maxOffset; i++)
for (int i = 0; i < 3 * maxOffset; i++)
{
int currentOffset;
if (i < maxOffset)
{
currentOffset = tempLocation + i;
}
else if (i < 2 * maxOffset)
{
currentOffset = tempLocation + tempLen + i - 2 * maxOffset;
}
else
{
currentOffset = tempLocation + i - 2 * maxOffset + 445 * 588;
}
if (currentOffset < trStart)
else if (i == 2 * maxOffset)
currentOffset = trEnd;
else //if (i > 2 * maxOffset)
currentOffset = tempLocation + i - 1 - 2 * maxOffset + 445 * 588;
if (currentOffset < trStart || currentOffset > trEnd)
continue;
_CRC32[iTrack, i] = Crc32.Combine(crc32, part._CRC32[iTrack, i], 4 * (currentOffset - start));
_CRCWN[iTrack, i] = Crc32.Combine(crcwn, part._CRCWN[iTrack, i], part._CRCNL[iTrack, i] * 2);
_CRCNL[iTrack, i] = crcnl + part._CRCNL[iTrack, i];
if (i == 0 || i == 2 * maxOffset) continue;
_CRCAR[iTrack, i] = crcar + part._CRCAR[iTrack, i];
_CRCV2[iTrack, i] = crcv2 + part._CRCV2[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]);
}
@@ -902,7 +876,6 @@ namespace CUETools.AccurateRip
int leadout_len = Math.Max(4096 * 4, (calcSyn || calcParity) ? stride + laststride : 0);
leadin = new ushort[leadin_len];
leadout = new ushort[leadout_len];
preLeadoutCrc = 0;
_currentTrack = 0;
Position = 0; // NOT _toc[_toc.FirstAudio][0].Start * 588;
}

View File

@@ -332,7 +332,7 @@ namespace CUETools.AccurateRip
if (err_count == allowed_errors && (err_count == 0 || rs.chienSearch(_errpos, stridecount + npar, err_count, _sigma)))
{
actualOffset = offset;
hasErrors = err_count != 0 || ar.CTDBCRC(offset) != expectedCRC;
hasErrors = err_count != 0 || ar.CTDBCRC(-offset) != expectedCRC;
return true;
}
}

View File

@@ -108,7 +108,10 @@ namespace CUETools.Codecs.ALAC
int sampleDuration;
int sampleSize;
if (_iSample >= _sample_byte_size.Length)
{
buff.Length = offset;
return offset;
}
get_sample_info(_iSample, out sampleDuration, out sampleSize);
_IO.Read(_framesBuffer, 0, sampleSize);
decodeFrame(sampleSize);

View File

@@ -1628,6 +1628,8 @@ namespace CUETools.Codecs.ALAC
verifyBuffer = new int[Alac.MAX_BLOCKSIZE * _pcm.ChannelCount];
}
if (sample_count < 0)
throw new InvalidOperationException("FinalSampleCount unknown");
int frames = sample_count / eparams.block_size;
int header_len = max_header_len
+ eparams.padding_size

View File

@@ -263,7 +263,10 @@ namespace CUETools { namespace Codecs { namespace FLAC {
do
{
if (FLAC__stream_decoder_get_state(_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
return buff->Length - samplesNeeded;
{
buff->Length -= samplesNeeded;
return buff->Length;
}
if (!FLAC__stream_decoder_process_single(_decoder))
{
String^ state = gcnew String(FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(_decoder)]);

View File

@@ -251,7 +251,10 @@ namespace CUETools.Codecs.FLAKE
fill_frames_buffer();
if (_framesBufferLength == 0)
{
buff.Length = offset;
return offset;
}
int bytesDecoded = DecodeFrame(_framesBuffer, _framesBufferOffset, _framesBufferLength);
_framesBufferLength -= bytesDecoded;

View File

@@ -79,14 +79,6 @@ namespace CUETools.TestCodecs
AudioBuffer buff = WAVReader.ReadAllSamples("test.wav", null);
ALACWriter target;
target = new ALACWriter("alacwriter0.m4a", null, buff.PCM);
target.Padding = 1;
target.Vendor = "CUETools";
target.CreationTime = DateTime.Parse("15 Aug 1976");
target.Write(buff);
target.Close();
CollectionAssert.AreEqual(File.ReadAllBytes("alac.m4a"), File.ReadAllBytes("alacwriter0.m4a"), "alacwriter0.m4a doesn't match.");
target = new ALACWriter("alacwriter1.m4a", null, buff.PCM);
target.Padding = 1;
target.Vendor = "CUETools";
@@ -95,6 +87,14 @@ namespace CUETools.TestCodecs
target.Write(buff);
target.Close();
CollectionAssert.AreEqual(File.ReadAllBytes("alac.m4a"), File.ReadAllBytes("alacwriter1.m4a"), "alacwriter1.m4a doesn't match.");
target = new ALACWriter("alacwriter0.m4a", null, buff.PCM);
target.Padding = 1;
target.Vendor = "CUETools";
target.CreationTime = DateTime.Parse("15 Aug 1976");
target.Write(buff);
target.Close();
CollectionAssert.AreEqual(File.ReadAllBytes("alac.m4a"), File.ReadAllBytes("alacwriter0.m4a"), "alacwriter0.m4a doesn't match.");
}
}

View File

@@ -91,10 +91,10 @@ namespace CUETools.TestCodecs
}
/// <summary>
///A test for CRC32
///A test for CRC32 with offset
///</summary>
[TestMethod()]
public void CRC32Test1()
public void CRC32TestOffset()
{
Assert.AreEqual<uint>(2953798997, ar.CRC32(0, 13), "CRC32[0][13] was not set correctly.");
Assert.AreEqual<uint>(0480843614, ar.CRC32(0, -7), "CRC32[0][-7] was not set correctly.");
@@ -108,6 +108,20 @@ namespace CUETools.TestCodecs
Assert.AreEqual<uint>(0480843614, ar2.CRC32(1, -7), "CRC32[1,13](2) was not set correctly.");
}
/// <summary>
///A test for CTDBCRC
///</summary>
[TestMethod()]
public void CTDBCRCTest()
{
Assert.AreEqual<uint>(4209773141, ar.CTDBCRC(1, 0, 5 * 588, 5 * 588), "CTDBCRC[1] was not set correctly.");
Assert.AreEqual<uint>(0037001035, ar.CTDBCRC(2, 0, 5 * 588, 5 * 588), "CTDBCRC[2] was not set correctly.");
Assert.AreEqual<uint>(1024656428, ar.CTDBCRC(3, 0, 5 * 588, 5 * 588), "CTDBCRC[3] was not set correctly.");
Assert.AreEqual<uint>(ar.CRC32(2), ar.CTDBCRC(2, 0, 5 * 588, 5 * 588), "CTDBCRC[2] was not set correctly.");
}
/// <summary>
///A test for ARV1 CRC
///</summary>
@@ -195,19 +209,21 @@ namespace CUETools.TestCodecs
Assert.AreEqual<uint>(ar0.CRC(track), ar1.CRC(track, -offs), "CRC with offset " + (-offs) + " was not set correctly.");
Assert.AreEqual<uint>(ar0.CRC450(track, offs), ar1.CRC450(track, 0), "CRC450 with offset " + offs + " was not set correctly.");
Assert.AreEqual<uint>(ar0.CRC450(track, 0), ar1.CRC450(track, -offs), "CRC450 with offset " + (-offs) + " was not set correctly.");
Assert.AreEqual<uint>(ar0.CTDBCRC(track + 1, offs, 588 * 5, 588 * 5), ar1.CTDBCRC(track + 1, 0, 588 * 5, 588 * 5), "CTDBCRC with offset " + offs + " was not set correctly.");
Assert.AreEqual<uint>(ar1.CTDBCRC(track + 1, -offs, 588 * 5, 588 * 5), ar0.CTDBCRC(track + 1, 0, 588 * 5, 588 * 5), "CTDBCRC with offset " + (-offs) + " was not set correctly.");
if (track != 2)
{
Assert.AreEqual<uint>(ar0.CRC32(track + 1, offs), ar1.CRC32(track + 1), "CRC32 with offset " + (offs) + " was not set correctly.");
Assert.AreEqual<uint>(ar0.CRCWONULL(track + 1, offs), ar1.CRCWONULL(track + 1), "CRCWONULL with offset " + (offs) + " was not set correctly.");
}
if (track != 0)
//if (track != 0)
{
Assert.AreEqual<uint>(ar0.CRC32(track + 1), ar1.CRC32(track + 1, -offs), "CRC32 with offset " + (-offs) + " was not set correctly.");
Assert.AreEqual<uint>(ar0.CRCWONULL(track + 1), ar1.CRCWONULL(track + 1, -offs), "CRCWONULL with offset " + (-offs) + " was not set correctly.");
}
}
Assert.AreEqual<uint>(ar0.CTDBCRC(588 * 5, 588 * 5), ar1.CTDBCRC(588 * 5 - offs, 588 * 5 + offs), "CTDBCRC with offset " + offs + " was not set correctly.");
Assert.AreEqual<uint>(ar1.CTDBCRC(588 * 5, 588 * 5), ar0.CTDBCRC(588 * 5 + offs, 588 * 5 - offs), "CTDBCRC with offset " + (-offs) + " was not set correctly.");
Assert.AreEqual<uint>(ar0.CTDBCRC(0, offs, 588 * 5, 588 * 5), ar1.CTDBCRC(0, 0, 588 * 5, 588 * 5), "CTDBCRC with offset " + offs + " was not set correctly.");
Assert.AreEqual<uint>(ar1.CTDBCRC(0, -offs, 588 * 5, 588 * 5), ar0.CTDBCRC(0, 0, 588 * 5, 588 * 5), "CTDBCRC with offset " + (-offs) + " was not set correctly.");
}
}
@@ -231,8 +247,10 @@ namespace CUETools.TestCodecs
{
string message = "split = " + CDImageLayout.TimeToString((uint)split/588) + "." + (split%588).ToString() + ", offset = " + offs.ToString() + ", track = " + (track + 1).ToString();
Assert.AreEqual<uint>(ar0.CRC(track, offs), ar1.CRC(track, offs), "CRC was not set correctly, " + message);
Assert.AreEqual<uint>(ar0.CRC450(track, offs), ar1.CRC450(track, offs), "CRC450 was not set correctly, " + message);
if ((track != 2 || offs <= 0) && (track != 0 || offs >= 0))
Assert.AreEqual<uint>(ar0.CTDBCRC(track, offs, 5 * 588, 5 * 588), ar1.CTDBCRC(track, offs, 5 * 588, 5 * 588), "CTDBCRC was not set correctly, " + message);
//CRC450 is zero here :( too small tracks
//Assert.AreEqual<uint>(ar0.CRC450(track, offs), ar1.CRC450(track, offs), "CRC450 was not set correctly, " + message);
if ((track != 2 || offs <= 0))// && (track != 0 || offs >= 0))
{
Assert.AreEqual<uint>(ar0.CRC32(track + 1, offs), ar1.CRC32(track + 1, offs), "CRC32 was not set correctly, " + message);
Assert.AreEqual<uint>(ar0.CRCWONULL(track + 1, offs), ar1.CRCWONULL(track + 1, offs), "CRCWONULL was not set correctly, " + message);

View File

@@ -70,12 +70,12 @@
<ProjectReference Include="..\..\CUETools.Codecs.ALAC\CUETools.Codecs.ALAC.csproj">
<Project>{F2EC7193-D5E5-4252-9803-5CEB407E910F}</Project>
<Name>CUETools.Codecs.ALAC</Name>
<Private>False</Private>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\..\CUETools.Codecs.FLAKE\CUETools.Codecs.FLAKE.csproj">
<Project>{082D6B9E-326E-4D15-9798-EDAE9EDE70A6}</Project>
<Name>CUETools.Codecs.FLAKE</Name>
<Private>False</Private>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\..\CUETools.Codecs.LossyWAV\CUETools.Codecs.LossyWAV.csproj">
<Project>{8A0426FA-0BC2-4C49-A6E5-1F9A68156F19}</Project>

View File

@@ -3,9 +3,4 @@
<TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
<RunConfiguration id="cad9b348-419f-496e-92ed-2dfc5d74da06" name="Local Test Run" storage="localtestrun.testrunconfig" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, PublicKeyToken=b03f5f7f11d50a3a" />
</TestList>
<TestList name="Results Not in a List" id="8c84fa94-04c1-424b-9868-57a2d4851a1d">
<TestLinks>
<TestLink id="707b580c-3801-a61c-0d6a-866ccb489f00" name="CDRepairFixTest" storage="cuetools.testparity\bin\release\cuetools.testparity.dll" enabled="false" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
</TestLinks>
</TestList>
</TestLists>

View File

@@ -80,7 +80,6 @@ namespace JDP {
this.toolStripMenuItemInputBrowserFiles = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemInputBrowserMulti = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemInputBrowserDrag = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemLocalDatabase = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemInputBrowserHide = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripOutput = new System.Windows.Forms.ToolStrip();
this.toolStripLabelOutput = new System.Windows.Forms.ToolStripLabel();
@@ -649,7 +648,6 @@ namespace JDP {
this.toolStripMenuItemInputBrowserFiles,
this.toolStripMenuItemInputBrowserMulti,
this.toolStripMenuItemInputBrowserDrag,
this.toolStripMenuItemLocalDatabase,
this.toolStripMenuItemInputBrowserHide});
this.toolStripSplitButtonInputBrowser.Image = global::JDP.Properties.Resources.folder;
resources.ApplyResources(this.toolStripSplitButtonInputBrowser, "toolStripSplitButtonInputBrowser");
@@ -675,12 +673,6 @@ namespace JDP {
this.toolStripMenuItemInputBrowserDrag.Name = "toolStripMenuItemInputBrowserDrag";
resources.ApplyResources(this.toolStripMenuItemInputBrowserDrag, "toolStripMenuItemInputBrowserDrag");
//
// toolStripMenuItemLocalDatabase
//
this.toolStripMenuItemLocalDatabase.Image = global::JDP.Properties.Resources.puzzle__arrow;
this.toolStripMenuItemLocalDatabase.Name = "toolStripMenuItemLocalDatabase";
resources.ApplyResources(this.toolStripMenuItemLocalDatabase, "toolStripMenuItemLocalDatabase");
//
// toolStripMenuItemInputBrowserHide
//
this.toolStripMenuItemInputBrowserHide.Image = global::JDP.Properties.Resources.folder_delete;
@@ -1206,7 +1198,6 @@ namespace JDP {
private System.Windows.Forms.CheckBox checkBoxVerifyUseCDRepair;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelCTDB;
private System.Windows.Forms.CheckBox checkBoxVerifyUseLocal;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemLocalDatabase;
private System.Windows.Forms.CheckBox checkBoxSkipRecent;
private System.Windows.Forms.ToolStripMenuItem editMetadataToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem addFolderToLocalDatabaseToolStripMenuItem;

View File

@@ -82,28 +82,26 @@ namespace JDP {
{
if (node.IsExpanded)
AddCheckedNodesToBatch(node.Nodes);
else if (node.Checked && node is CUEControls.FileSystemTreeNodeFileSystemInfo)
_batchPaths.Add((node as CUEControls.FileSystemTreeNodeFileSystemInfo).Path);
else if (node.Checked)
{
if (node is CUEControls.FileSystemTreeNodeFileSystemInfo || node is FileSystemTreeNodeLocalDBEntry)
if ((node as CUEControls.FileSystemTreeNode).Path != null)
_batchPaths.Add((node as CUEControls.FileSystemTreeNode).Path);
if (node is FileSystemTreeNodeLocalDBFolder)
foreach (var entry in (node as FileSystemTreeNodeLocalDBFolder).Group)
if (entry.Path != null)
_batchPaths.Add(entry.Path);
}
}
}
private void AddAllNodesToBatch(TreeNode node)
{
if (node.IsExpanded || !(node is CUEControls.FileSystemTreeNode))
{
AddAllNodesToBatch(node.Nodes);
return;
}
if (node is CUEControls.FileSystemTreeNodeFileSystemInfo)
{
_batchPaths.Add((node as CUEControls.FileSystemTreeNodeFileSystemInfo).Path);
return;
}
if (node is FileSystemTreeNodeLocalDBEntry)
{
_batchPaths.Add((node as FileSystemTreeNodeLocalDBEntry).Path);
return;
}
if (node is FileSystemTreeNodeLocalDBFolder)
{
foreach (var entry in (node as FileSystemTreeNodeLocalDBFolder).Group)
@@ -111,6 +109,17 @@ namespace JDP {
_batchPaths.Add(entry.Path);
return;
}
if (node is FileSystemTreeNodeLocalDBEntry)
{
if ((node as FileSystemTreeNodeLocalDBEntry).Path != null)
_batchPaths.Add((node as FileSystemTreeNodeLocalDBEntry).Path);
return;
}
if (node.IsExpanded || !(node is CUEControls.FileSystemTreeNode))
{
AddAllNodesToBatch(node.Nodes);
return;
}
}
private void AddAllNodesToBatch(TreeNodeCollection nodes)
@@ -164,10 +173,10 @@ namespace JDP {
// }
//}
if (FileBrowserState != FileBrowserStateEnum.Checkboxes
&& FileBrowserState != FileBrowserStateEnum.DragDrop
&& (FileBrowserState != FileBrowserStateEnum.LocalDB || fileSystemTreeView1.SelectedPath != null)
&& !Directory.Exists(InputPath))
if (FileBrowserState == FileBrowserStateEnum.Hidden
|| (FileBrowserState == FileBrowserStateEnum.Tree
&& !(fileSystemTreeView1.SelectedNode is FileSystemTreeNodeLocalDBFolder)
&& !Directory.Exists(InputPath)))
{
StartConvert();
return;
@@ -182,8 +191,12 @@ namespace JDP {
AddCheckedNodesToBatch(fileSystemTreeView1.Nodes);
else if (FileBrowserState == FileBrowserStateEnum.DragDrop)
AddAllNodesToBatch(fileSystemTreeView1.Nodes);
else if (FileBrowserState == FileBrowserStateEnum.LocalDB && fileSystemTreeView1.SelectedNode != null)
AddAllNodesToBatch(fileSystemTreeView1.SelectedNode);
else if (FileBrowserState == FileBrowserStateEnum.Tree && fileSystemTreeView1.SelectedNode is FileSystemTreeNodeLocalDBFolder)
{
foreach (var entry in (fileSystemTreeView1.SelectedNode as FileSystemTreeNodeLocalDBFolder).Group)
if (entry.Path != null)
_batchPaths.Add(entry.Path);
}
else
{
_batchRoot = InputPath;
@@ -386,7 +399,6 @@ namespace JDP {
Tree = 0,
Checkboxes = 1,
DragDrop = 2,
LocalDB = 8,
Hidden = 4
}
@@ -1153,7 +1165,6 @@ namespace JDP {
toolStripMenu.Enabled = !running;
fileSystemTreeView1.Enabled = !running;
txtInputPath.Enabled = !running;
txtInputPath.ReadOnly = FileBrowserState == FileBrowserStateEnum.DragDrop || FileBrowserState == FileBrowserStateEnum.Checkboxes || FileBrowserState == FileBrowserStateEnum.LocalDB;
grpExtra.Enabled = !running && (converting || verifying);
//groupBoxCorrector.Enabled = !running && SelectedAction == CUEAction.CorrectFilenames;
//grpOutputStyle.Enabled = !running && converting;
@@ -1361,7 +1372,7 @@ namespace JDP {
if (InputPath == "")
{
InputPath = sr.Load("InputPath") ?? "";
FileBrowserState = (FileBrowserStateEnum)(sr.LoadInt32("FileBrowserState", (int)FileBrowserStateEnum.Tree, (int)FileBrowserStateEnum.LocalDB) ?? (int)FileBrowserStateEnum.Hidden);
FileBrowserState = (FileBrowserStateEnum)(sr.LoadInt32("FileBrowserState", (int)FileBrowserStateEnum.Tree, (int)FileBrowserStateEnum.Hidden) ?? (int)FileBrowserStateEnum.Hidden);
}
else
FileBrowserState = FileBrowserStateEnum.Hidden;
@@ -1542,7 +1553,7 @@ namespace JDP {
? toolStripMenuItemOutputManual : toolStripMenuItemOutputBrowse;
toolStripSplitButtonOutputBrowser.Text = toolStripSplitButtonOutputBrowser.DefaultItem.Text;
toolStripSplitButtonOutputBrowser.Image = toolStripSplitButtonOutputBrowser.DefaultItem.Image;
toolStripSplitButtonOutputBrowser.Enabled = toolStripSplitButtonOutputBrowser.DefaultItem.Enabled;
toolStripSplitButtonOutputBrowser.Enabled = true;// toolStripSplitButtonOutputBrowser.DefaultItem.Enabled;
UpdateOutputPath();
}
}
@@ -1555,7 +1566,6 @@ namespace JDP {
case FileBrowserStateEnum.Checkboxes: return toolStripMenuItemInputBrowserMulti;
case FileBrowserStateEnum.DragDrop: return toolStripMenuItemInputBrowserDrag;
case FileBrowserStateEnum.Hidden: return toolStripMenuItemInputBrowserHide;
case FileBrowserStateEnum.LocalDB: return toolStripMenuItemLocalDatabase;
}
return null;
}
@@ -1601,6 +1611,7 @@ namespace JDP {
{
fileSystemTreeView1.Nodes.Clear();
fileSystemTreeView1.IconManager = m_icon_mgr;
fileSystemTreeView1.Nodes.Add(new FileSystemTreeNodeLocalDB(m_icon_mgr, _localDB));
if (InputPath != "")
{
TreeNode node = null;
@@ -1619,8 +1630,9 @@ namespace JDP {
}
}
}
if (fileSystemTreeView1.Nodes.Count > 0)
fileSystemTreeView1.Nodes[0].Expand();
foreach (TreeNode node in fileSystemTreeView1.Nodes)
node.Expand();
if (value == FileBrowserStateEnum.Checkboxes
&& fileSystemTreeView1.SelectedNode != null
&& fileSystemTreeView1.SelectedNode is CUEControls.FileSystemTreeNodeFileSystemInfo)
@@ -1647,92 +1659,6 @@ namespace JDP {
fileSystemTreeView1.Select();
fileSystemTreeView1.ShowRootLines = false;
break;
case FileBrowserStateEnum.LocalDB:
OutputPathUseTemplate = true;
if (_fileBrowserControlState != value)
{
fileSystemTreeView1.BeginUpdate();
fileSystemTreeView1.CheckBoxes = false;
//fileSystemTreeView1.StateImageList = m_state_image_list;
fileSystemTreeView1.Nodes.Clear();
fileSystemTreeView1.Nodes.Add("dummy");
fileSystemTreeView1.IconManager = m_icon_mgr;
fileSystemTreeView1.Nodes.Clear();
fileSystemTreeView1.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
m_icon_mgr, _localDB, true, true, m_icon_mgr.GetIconIndex(".#puzzle"), "By Uniqueness",
i => ((int)FileSystemTreeNodeLocalDBCollision.GetGroupType(_localDB.FindAll(j => j.DiscID == i.DiscID))).ToString(),
i => FileSystemTreeNodeLocalDBCollision.GroupTypeToDescription(FileSystemTreeNodeLocalDBCollision.GetGroupType(_localDB.FindAll(j => j.DiscID == i.DiscID))),
i => m_icon_mgr.GetIconIndex(FileSystemTreeNodeLocalDBCollision.GroupTypeToIconTag(FileSystemTreeNodeLocalDBCollision.GetGroupType(_localDB.FindAll(j => j.DiscID == i.DiscID)))))); //converter_icon
fileSystemTreeView1.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
m_icon_mgr, _localDB, true, true, m_icon_mgr.GetIconIndex(".flac"), "By Format",
i => i.AudioPaths == null || i.AudioPaths.Count == 0 ? null : Path.GetExtension(i.AudioPaths[0]).ToLower(),
null,
i => m_icon_mgr.GetIconIndex(i.AudioPaths[0])));
fileSystemTreeView1.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
m_icon_mgr, _localDB, false, true, m_icon_mgr.GetIconIndex(".#users"), "By Artist",
i => i.Metadata.Artist, null, null));
fileSystemTreeView1.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
m_icon_mgr, _localDB, true, false, m_icon_mgr.GetIconIndex(".#calendar"), "By Release Date",
i => i.Metadata.Year, null, null));
fileSystemTreeView1.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
m_icon_mgr, _localDB, true, true, m_icon_mgr.GetIconIndex(".#alarm_clock"), "By Verification Date",
i =>
i.VerificationDate == DateTime.MinValue ? "0" :
i.VerificationDate.AddHours(1) > DateTime.Now ? "1" :
i.VerificationDate.AddDays(1) > DateTime.Now ? "2" :
i.VerificationDate.AddDays(7) > DateTime.Now ? "3" :
i.VerificationDate.AddDays(31) > DateTime.Now ? "4" :
i.VerificationDate.AddDays(365) > DateTime.Now ? "5" :
"6",
i =>
i.VerificationDate == DateTime.MinValue ? "never" :
i.VerificationDate.AddHours(1) > DateTime.Now ? "this hour" :
i.VerificationDate.AddDays(1) > DateTime.Now ? "this day" :
i.VerificationDate.AddDays(7) > DateTime.Now ? "this week" :
i.VerificationDate.AddDays(31) > DateTime.Now ? "this month" :
i.VerificationDate.AddDays(365) > DateTime.Now ? "this year" :
"more than a year ago",
null));
fileSystemTreeView1.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
m_icon_mgr, _localDB, true, true, m_icon_mgr.GetIconIndex(".#ar"), "By AccurateRip Confidence",
i =>
i.VerificationDate == DateTime.MinValue ? "00" :
i.ARConfidence == 0 ? "01" :
i.ARConfidence == 1 ? "02" :
i.ARConfidence == 2 ? "03" :
i.ARConfidence == 3 ? "04" :
i.ARConfidence < 5 ? "05" :
i.ARConfidence < 10 ? "06" :
i.ARConfidence < 20 ? "07" :
i.ARConfidence < 50 ? "08" :
i.ARConfidence < 100 ? "09" :
"10",
i =>
i.VerificationDate == DateTime.MinValue ? "?" :
i.ARConfidence == 0 ? "0" :
i.ARConfidence == 1 ? "1" :
i.ARConfidence == 2 ? "2" :
i.ARConfidence == 3 ? "3" :
i.ARConfidence < 5 ? "< 5" :
i.ARConfidence < 10 ? "< 10" :
i.ARConfidence < 20 ? "< 20" :
i.ARConfidence < 50 ? "< 50" :
i.ARConfidence < 100 ? "< 100" :
">=100",
null));
_fileBrowserControlState = value;
fileSystemTreeView1.EndUpdate();
}
fileSystemTreeView1.Select();
fileSystemTreeView1.ShowRootLines = true;
break;
case FileBrowserStateEnum.Hidden:
break;
}
@@ -1872,7 +1798,7 @@ namespace JDP {
private void UpdateActions()
{
if (FileBrowserState == FileBrowserStateEnum.DragDrop || FileBrowserState == FileBrowserStateEnum.Checkboxes || FileBrowserState == FileBrowserStateEnum.LocalDB)
if (FileBrowserState == FileBrowserStateEnum.DragDrop || FileBrowserState == FileBrowserStateEnum.Checkboxes)
{
rbActionCorrectFilenames.Enabled = true;
rbActionCreateCUESheet.Enabled = true;
@@ -1881,24 +1807,21 @@ namespace JDP {
//toolStripSplitButtonOutputBrowser.Enabled = false;
toolStripMenuItemOutputManual.Enabled =
toolStripMenuItemOutputBrowse.Enabled = false;
txtInputPath.ReadOnly = true;
}
else
{
string pathIn = InputPath;
rbActionCorrectFilenames.Enabled = pathIn.Length != 0
&& ((File.Exists(pathIn) && Path.GetExtension(pathIn).ToLower() == ".cue")
|| Directory.Exists(pathIn));
rbActionCreateCUESheet.Enabled = pathIn.Length != 0
&& ((File.Exists(pathIn) && Path.GetExtension(pathIn).ToLower() != ".cue")
//&& ((File.Exists(pathIn) && CUESheet.CreateDummyCUESheet(_profile._config, pathIn) != null) -- too slow
|| Directory.Exists(pathIn));
rbActionVerify.Enabled =
rbActionEncode.Enabled = pathIn.Length != 0
&& (File.Exists(pathIn) || Directory.Exists(pathIn) || IsCDROM(pathIn));
toolStripMenuItemOutputManual.Enabled =
toolStripMenuItemOutputBrowse.Enabled =
pathIn.Length != 0
&& (IsCDROM(pathIn) || File.Exists(pathIn));
bool is_file = !string.IsNullOrEmpty(pathIn) && File.Exists(pathIn);
bool is_cue = is_file && Path.GetExtension(pathIn).ToLower() == ".cue";
bool is_directory = !string.IsNullOrEmpty(pathIn) && Directory.Exists(pathIn);
bool is_folder = FileBrowserState == FileBrowserStateEnum.Tree && fileSystemTreeView1.SelectedNode is FileSystemTreeNodeLocalDBFolder;
bool is_cdrom = !string.IsNullOrEmpty(pathIn) && IsCDROM(pathIn);
rbActionCorrectFilenames.Enabled = is_cue || is_directory;
rbActionCreateCUESheet.Enabled = (is_file && !is_cue) || is_directory;
rbActionVerify.Enabled = rbActionEncode.Enabled = is_file || is_directory || is_folder || is_cdrom;
toolStripMenuItemOutputManual.Enabled = toolStripMenuItemOutputBrowse.Enabled = is_file || is_cdrom;
txtInputPath.ReadOnly = is_folder;
}
btnConvert.Enabled = btnConvert.Visible &&
@@ -1911,54 +1834,27 @@ namespace JDP {
comboBoxScript.Enabled = btnConvert.Enabled && comboBoxScript.Items.Count > 1;
}
private void DumpLocalDB(StringBuilder report, TreeNode parent)
private void fileSystemTreeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (parent is FileSystemTreeNodeLocalDBFolder)
InputPath = fileSystemTreeView1.SelectedPath ?? "";
txtInputPath.SelectAll();
UpdateActions();
if (fileSystemTreeView1.SelectedNode is FileSystemTreeNodeLocalDBEntry)
{
foreach (var entry in (parent as FileSystemTreeNodeLocalDBFolder).Group)
var entry = (fileSystemTreeView1.SelectedNode as FileSystemTreeNodeLocalDBEntry).Item;
textBatchReport.Text = (entry.Log ?? "").Replace("\r", "").Replace("\n", "\r\n");
}
else if (fileSystemTreeView1.SelectedNode is FileSystemTreeNodeLocalDBFolder)
{
var group = (fileSystemTreeView1.SelectedNode as FileSystemTreeNodeLocalDBFolder).Group;
StringBuilder report = new StringBuilder();
foreach (var entry in group)
if (entry.Path != null)
if (entry.Status == null || entry.OffsetSafeCRC == null)
report.AppendFormat("{0}: never verified\r\n", entry.Path);
else
report.AppendFormat("{0}: CRC {1,8:X}, {2}\r\n", entry.Path, entry.OffsetSafeCRC.Value[0], entry.Status);
}
else
{
foreach (TreeNode node in parent.Nodes)
if (node is FileSystemTreeNodeLocalDBEntry)
{
var entry = (node as FileSystemTreeNodeLocalDBEntry).Item;
if (entry.Path != null)
if (entry.Status == null || entry.OffsetSafeCRC == null)
report.AppendFormat("{0}: never verified\r\n", entry.Path);
else
report.AppendFormat("{0}: CRC {1,8:X}, {2}\r\n", entry.Path, entry.OffsetSafeCRC.Value[0], entry.Status);
}
else
DumpLocalDB(report, node);
}
}
private void fileSystemTreeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (fileSystemTreeView1.SelectedPath != null)
{
InputPath = fileSystemTreeView1.SelectedPath;
txtInputPath.SelectAll();
}
if (FileBrowserState == FileBrowserStateEnum.LocalDB && fileSystemTreeView1.SelectedNode != null)
{
if (fileSystemTreeView1.SelectedNode is FileSystemTreeNodeLocalDBEntry)
{
var entry = (fileSystemTreeView1.SelectedNode as FileSystemTreeNodeLocalDBEntry).Item;
textBatchReport.Text = (entry.Log ?? "").Replace("\r", "").Replace("\n", "\r\n");
}
else
{
StringBuilder report = new StringBuilder();
DumpLocalDB(report, fileSystemTreeView1.SelectedNode);
textBatchReport.Text = report.ToString();
}
textBatchReport.Text = report.ToString();
}
}
@@ -2028,9 +1924,6 @@ namespace JDP {
fileSystemTreeView1.Nodes.Add(node);
}
break;
case FileBrowserStateEnum.LocalDB:
// ???
break;
}
fileSystemTreeView1.Focus();
}
@@ -2139,9 +2032,6 @@ namespace JDP {
}
fileSystemTreeView1.Select();
break;
case FileBrowserStateEnum.LocalDB:
// ???
break;
}
}
if (WindowState == FormWindowState.Minimized)
@@ -2549,8 +2439,6 @@ namespace JDP {
FileBrowserState = FileBrowserStateEnum.Checkboxes;
if (e.ClickedItem == toolStripMenuItemInputBrowserDrag)
FileBrowserState = FileBrowserStateEnum.DragDrop;
if (e.ClickedItem == toolStripMenuItemLocalDatabase)
FileBrowserState = FileBrowserStateEnum.LocalDB;
if (e.ClickedItem == toolStripMenuItemInputBrowserHide)
FileBrowserState = FileBrowserStateEnum.Hidden;
SetupControls(false);
@@ -2953,4 +2841,110 @@ namespace JDP {
this.Nodes.Add(new FileSystemTreeNodeLocalDBGroup(icon_mgr, group, ShowArtist, ShowYear, m_converter_icon(group[0]), m_converter_name(group[0])));
}
}
public class FileSystemTreeNodeLocalDB : FileSystemTreeNodeLocalDBFolder
{
public override string Path
{
get
{
return null;
}
}
public override string DisplayName
{
get
{
return "Local DB";
}
}
public override int DisplayIcon
{
get
{
return icon_mgr.GetIconIndex(".#puzzle");
}
}
public FileSystemTreeNodeLocalDB(CUEControls.IIconManager icon_mgr, List<CUEToolsLocalDBEntry> group)
: base(icon_mgr)
{
this.Group = group;
this.SelectedImageIndex = this.ImageIndex = this.DisplayIcon;
this.Text = this.DisplayName;
}
public override void DoExpand()
{
this.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
icon_mgr, this.Group, true, true, icon_mgr.GetIconIndex(".#puzzle"), "By Uniqueness",
i => ((int)FileSystemTreeNodeLocalDBCollision.GetGroupType(this.Group.FindAll(j => j.DiscID == i.DiscID))).ToString(),
i => FileSystemTreeNodeLocalDBCollision.GroupTypeToDescription(FileSystemTreeNodeLocalDBCollision.GetGroupType(this.Group.FindAll(j => j.DiscID == i.DiscID))),
i => icon_mgr.GetIconIndex(FileSystemTreeNodeLocalDBCollision.GroupTypeToIconTag(FileSystemTreeNodeLocalDBCollision.GetGroupType(this.Group.FindAll(j => j.DiscID == i.DiscID)))))); //converter_icon
this.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
icon_mgr, this.Group, true, true, icon_mgr.GetIconIndex(".flac"), "By Format",
i => i.AudioPaths == null || i.AudioPaths.Count == 0 ? null : System.IO.Path.GetExtension(i.AudioPaths[0]).ToLower(),
null,
i => icon_mgr.GetIconIndex(i.AudioPaths[0])));
this.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
icon_mgr, this.Group, false, true, icon_mgr.GetIconIndex(".#users"), "By Artist",
i => i.Metadata.Artist, null, null));
this.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
icon_mgr, this.Group, true, false, icon_mgr.GetIconIndex(".#calendar"), "By Release Date",
i => i.Metadata.Year, null, null));
this.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
icon_mgr, this.Group, true, true, icon_mgr.GetIconIndex(".#alarm_clock"), "By Verification Date",
i =>
i.VerificationDate == DateTime.MinValue ? "0" :
i.VerificationDate.AddHours(1) > DateTime.Now ? "1" :
i.VerificationDate.AddDays(1) > DateTime.Now ? "2" :
i.VerificationDate.AddDays(7) > DateTime.Now ? "3" :
i.VerificationDate.AddDays(31) > DateTime.Now ? "4" :
i.VerificationDate.AddDays(365) > DateTime.Now ? "5" :
"6",
i =>
i.VerificationDate == DateTime.MinValue ? "never" :
i.VerificationDate.AddHours(1) > DateTime.Now ? "this hour" :
i.VerificationDate.AddDays(1) > DateTime.Now ? "this day" :
i.VerificationDate.AddDays(7) > DateTime.Now ? "this week" :
i.VerificationDate.AddDays(31) > DateTime.Now ? "this month" :
i.VerificationDate.AddDays(365) > DateTime.Now ? "this year" :
"more than a year ago",
null));
this.Nodes.Add(new FileSystemTreeNodeLocalDBCategory(
icon_mgr, this.Group, true, true, icon_mgr.GetIconIndex(".#ar"), "By AccurateRip Confidence",
i =>
i.VerificationDate == DateTime.MinValue ? "00" :
i.ARConfidence == 0 ? "01" :
i.ARConfidence == 1 ? "02" :
i.ARConfidence == 2 ? "03" :
i.ARConfidence == 3 ? "04" :
i.ARConfidence < 5 ? "05" :
i.ARConfidence < 10 ? "06" :
i.ARConfidence < 20 ? "07" :
i.ARConfidence < 50 ? "08" :
i.ARConfidence < 100 ? "09" :
"10",
i =>
i.VerificationDate == DateTime.MinValue ? "?" :
i.ARConfidence == 0 ? "0" :
i.ARConfidence == 1 ? "1" :
i.ARConfidence == 2 ? "2" :
i.ARConfidence == 3 ? "3" :
i.ARConfidence < 5 ? "< 5" :
i.ARConfidence < 10 ? "< 10" :
i.ARConfidence < 20 ? "< 20" :
i.ARConfidence < 50 ? "< 50" :
i.ARConfidence < 100 ? "< 100" :
">=100",
null));
}
}
}

File diff suppressed because it is too large Load Diff