1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-12-15 17:11:20 +01:00

Sequence::Append* give strong guarantee

This commit is contained in:
Paul Licameli
2016-12-01 20:01:40 -05:00
parent 63cf80d244
commit fc0f093db7
3 changed files with 60 additions and 58 deletions

View File

@@ -689,13 +689,15 @@ void Sequence::InsertSilence(sampleCount s0, sampleCount len)
Paste(s0, &sTrack);
}
bool Sequence::AppendAlias(const wxString &fullPath,
void Sequence::AppendAlias(const wxString &fullPath,
sampleCount start,
size_t len, int channel, bool useOD)
// STRONG-GUARANTEE
{
// Quick check to make sure that it doesn't overflow
if (Overflows((mNumSamples.as_double()) + ((double)len)))
return false;
//THROW_INCONSISTENCY_EXCEPTION
;
SeqBlock newBlock(
useOD?
@@ -705,16 +707,16 @@ bool Sequence::AppendAlias(const wxString &fullPath,
);
mBlock.push_back(newBlock);
mNumSamples += len;
return true;
}
bool Sequence::AppendCoded(const wxString &fName, sampleCount start,
void Sequence::AppendCoded(const wxString &fName, sampleCount start,
size_t len, int channel, int decodeType)
// STRONG-GUARANTEE
{
// Quick check to make sure that it doesn't overflow
if (Overflows((mNumSamples.as_double()) + ((double)len)))
return false;
//THROW_INCONSISTENCY_EXCEPTION
;
SeqBlock newBlock(
mDirManager->NewODDecodeBlockFile(fName, start, len, channel, decodeType),
@@ -722,8 +724,6 @@ bool Sequence::AppendCoded(const wxString &fName, sampleCount start,
);
mBlock.push_back(newBlock);
mNumSamples += len;
return true;
}
void Sequence::AppendBlock
@@ -1518,22 +1518,32 @@ size_t Sequence::GetIdealAppendLen() const
return max - lastBlockLen;
}
bool Sequence::Append(samplePtr buffer, sampleFormat format,
void Sequence::Append(samplePtr buffer, sampleFormat format,
size_t len, XMLWriter* blockFileLog /*=NULL*/)
// STRONG-GUARANTEE
{
if (len == 0)
return;
// Quick check to make sure that it doesn't overflow
if (Overflows(mNumSamples.as_double() + ((double)len)))
return false;
//THROW_INCONSISTENCY_EXCEPTION
;
BlockArray newBlock;
sampleCount newNumSamples = mNumSamples;
// If the last block is not full, we need to add samples to it
int numBlocks = mBlock.size();
SeqBlock *pLastBlock;
decltype(pLastBlock->f->GetLength()) length;
SampleBuffer buffer2(mMaxSamples, mSampleFormat);
bool replaceLast = false;
if (numBlocks > 0 &&
(length =
(pLastBlock = &mBlock.back())->f->GetLength()) < mMinSamples) {
SeqBlock &lastBlock = *pLastBlock;
// Enlarge a sub-minimum block at the end
const SeqBlock &lastBlock = *pLastBlock;
const auto addLen = std::min(mMaxSamples - length, len);
Read(buffer2.ptr(), mSampleFormat, lastBlock, 0, length, true);
@@ -1544,11 +1554,13 @@ bool Sequence::Append(samplePtr buffer, sampleFormat format,
mSampleFormat,
addLen);
const int newLastBlockLen = length + addLen;
const auto newLastBlockLen = length + addLen;
SeqBlock newLastBlock(
mDirManager->NewSimpleBlockFile(buffer2.ptr(), newLastBlockLen, mSampleFormat,
blockFileLog != NULL),
mDirManager->NewSimpleBlockFile(
buffer2.ptr(), newLastBlockLen, mSampleFormat,
blockFileLog != NULL
),
lastBlock.start
);
@@ -1557,46 +1569,49 @@ bool Sequence::Append(samplePtr buffer, sampleFormat format,
static_cast< SimpleBlockFile * >( &*newLastBlock.f )
->SaveXML( *blockFileLog );
lastBlock = newLastBlock;
newBlock.push_back( newLastBlock );
len -= addLen;
mNumSamples += addLen;
newNumSamples += addLen;
buffer += addLen * SAMPLE_SIZE(format);
replaceLast = true;
}
// Append the rest as NEW blocks
while (len) {
const auto idealSamples = GetIdealBlockSize();
const auto l = std::min(idealSamples, len);
const auto addedLen = std::min(idealSamples, len);
BlockFilePtr pFile;
if (format == mSampleFormat) {
pFile = mDirManager->NewSimpleBlockFile(buffer, l, mSampleFormat,
blockFileLog != NULL);
pFile = mDirManager->NewSimpleBlockFile(
buffer, addedLen, mSampleFormat, blockFileLog != NULL);
}
else {
CopySamples(buffer, format, buffer2.ptr(), mSampleFormat, l);
pFile = mDirManager->NewSimpleBlockFile(buffer2.ptr(), l, mSampleFormat,
blockFileLog != NULL);
CopySamples(buffer, format, buffer2.ptr(), mSampleFormat, addedLen);
pFile = mDirManager->NewSimpleBlockFile(
buffer2.ptr(), addedLen, mSampleFormat, blockFileLog != NULL);
}
if (blockFileLog)
// shouldn't throw, because XMLWriter is not XMLFileWriter
static_cast< SimpleBlockFile * >( &*pFile )->SaveXML( *blockFileLog );
mBlock.push_back(SeqBlock(pFile, mNumSamples));
newBlock.push_back(SeqBlock(pFile, mNumSamples));
buffer += l * SAMPLE_SIZE(format);
mNumSamples += l;
len -= l;
buffer += addedLen * SAMPLE_SIZE(format);
newNumSamples += addedLen;
len -= addedLen;
}
AppendBlocksIfConsistent(newBlock, replaceLast,
newNumSamples, wxT("Append"));
// JKC: During generate we use Append again and again.
// If generating a long sequence this test would give O(n^2)
// performance - not good!
#ifdef VERY_SLOW_CHECKING
ConsistencyCheck(wxT("Append"));
#endif
return true;
}
void Sequence::Blockify