mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-17 16:50:26 +02:00
Sequence::Append* give strong guarantee
This commit is contained in:
parent
63cf80d244
commit
fc0f093db7
@ -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
|
||||
|
@ -107,14 +107,14 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
|
||||
void Paste(sampleCount s0, const Sequence *src);
|
||||
|
||||
size_t GetIdealAppendLen() const;
|
||||
bool Append(samplePtr buffer, sampleFormat format, size_t len,
|
||||
void Append(samplePtr buffer, sampleFormat format, size_t len,
|
||||
XMLWriter* blockFileLog=NULL);
|
||||
void Delete(sampleCount start, sampleCount len);
|
||||
bool AppendAlias(const wxString &fullPath,
|
||||
void AppendAlias(const wxString &fullPath,
|
||||
sampleCount start,
|
||||
size_t len, int channel, bool useOD);
|
||||
|
||||
bool AppendCoded(const wxString &fName, sampleCount start,
|
||||
void AppendCoded(const wxString &fName, sampleCount start,
|
||||
size_t len, int channel, int decodeType);
|
||||
|
||||
///gets an int with OD flags so that we can determine which ODTasks should be run on this track after save/open, etc.
|
||||
|
@ -1403,13 +1403,10 @@ void WaveClip::Append(samplePtr buffer, sampleFormat format,
|
||||
|
||||
for(;;) {
|
||||
if (mAppendBufferLen >= blockSize) {
|
||||
bool success =
|
||||
// flush some previously appended contents
|
||||
// use STRONG-GUARANTEE
|
||||
mSequence->Append(mAppendBuffer.ptr(), seqFormat, blockSize,
|
||||
blockFileLog);
|
||||
if (!success)
|
||||
return;
|
||||
// flush some previously appended contents
|
||||
// use STRONG-GUARANTEE
|
||||
mSequence->Append(mAppendBuffer.ptr(), seqFormat, blockSize,
|
||||
blockFileLog);
|
||||
|
||||
// use NOFAIL-GUARANTEE for rest of this "if"
|
||||
memmove(mAppendBuffer.ptr(),
|
||||
@ -1444,14 +1441,11 @@ void WaveClip::AppendAlias(const wxString &fName, sampleCount start,
|
||||
// STRONG-GUARANTEE
|
||||
{
|
||||
// use STRONG-GUARANTEE
|
||||
bool result = mSequence->AppendAlias(fName, start, len, channel,useOD);
|
||||
mSequence->AppendAlias(fName, start, len, channel,useOD);
|
||||
|
||||
// use NOFAIL-GUARANTEE
|
||||
if (result)
|
||||
{
|
||||
UpdateEnvelopeTrackLen();
|
||||
MarkChanged();
|
||||
}
|
||||
UpdateEnvelopeTrackLen();
|
||||
MarkChanged();
|
||||
}
|
||||
|
||||
void WaveClip::AppendCoded(const wxString &fName, sampleCount start,
|
||||
@ -1459,14 +1453,11 @@ void WaveClip::AppendCoded(const wxString &fName, sampleCount start,
|
||||
// STRONG-GUARANTEE
|
||||
{
|
||||
// use STRONG-GUARANTEE
|
||||
bool result = mSequence->AppendCoded(fName, start, len, channel, decodeType);
|
||||
mSequence->AppendCoded(fName, start, len, channel, decodeType);
|
||||
|
||||
// use NOFAIL-GUARANTEE
|
||||
if (result)
|
||||
{
|
||||
UpdateEnvelopeTrackLen();
|
||||
MarkChanged();
|
||||
}
|
||||
UpdateEnvelopeTrackLen();
|
||||
MarkChanged();
|
||||
}
|
||||
|
||||
void WaveClip::Flush()
|
||||
@ -1479,7 +1470,6 @@ void WaveClip::Flush()
|
||||
//wxLogDebug(wxT(" mAppendBufferLen=%lli"), (long long) mAppendBufferLen);
|
||||
//wxLogDebug(wxT(" previous sample count %lli"), (long long) mSequence->GetNumSamples());
|
||||
|
||||
bool success = true;
|
||||
if (mAppendBufferLen > 0) {
|
||||
|
||||
auto cleanup = finally( [&] {
|
||||
@ -1492,7 +1482,8 @@ void WaveClip::Flush()
|
||||
MarkChanged();
|
||||
} );
|
||||
|
||||
success = mSequence->Append(mAppendBuffer.ptr(), mSequence->GetSampleFormat(), mAppendBufferLen);
|
||||
mSequence->Append(mAppendBuffer.ptr(), mSequence->GetSampleFormat(),
|
||||
mAppendBufferLen);
|
||||
}
|
||||
|
||||
//wxLogDebug(wxT("now sample count %lli"), (long long) mSequence->GetNumSamples());
|
||||
@ -1904,12 +1895,8 @@ void WaveClip::Resample(int rate, ProgressDialog *progress)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!newSequence->Append((samplePtr)outBuffer.get(), floatSample,
|
||||
outGenerated))
|
||||
{
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
newSequence->Append((samplePtr)outBuffer.get(), floatSample,
|
||||
outGenerated);
|
||||
|
||||
if (progress)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user