mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-27 16:56:03 +02:00
Bug2532: should preserve sharing of sample blocks when importing AUP (#651)
This commit is contained in:
parent
c17b804750
commit
7294f7a8e0
@ -1470,11 +1470,51 @@ size_t Sequence::GetIdealAppendLen() const
|
|||||||
return max - lastBlockLen;
|
return max - lastBlockLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! @excsafety{Strong} */
|
||||||
|
SeqBlock::SampleBlockPtr Sequence::AppendNewBlock(
|
||||||
|
samplePtr buffer, sampleFormat format, size_t len)
|
||||||
|
{
|
||||||
|
return DoAppend( buffer, format, len, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @excsafety{Strong} */
|
||||||
|
void Sequence::AppendSharedBlock(const SeqBlock::SampleBlockPtr &pBlock)
|
||||||
|
{
|
||||||
|
auto len = pBlock->GetSampleCount();
|
||||||
|
|
||||||
|
// Quick check to make sure that it doesn't overflow
|
||||||
|
if (Overflows(mNumSamples.as_double() + ((double)len)))
|
||||||
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
|
|
||||||
|
BlockArray newBlock;
|
||||||
|
newBlock.emplace_back( pBlock, mNumSamples );
|
||||||
|
auto newNumSamples = mNumSamples + len;
|
||||||
|
|
||||||
|
AppendBlocksIfConsistent(newBlock, false,
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
/*! @excsafety{Strong} */
|
/*! @excsafety{Strong} */
|
||||||
void Sequence::Append(samplePtr buffer, sampleFormat format, size_t len)
|
void Sequence::Append(samplePtr buffer, sampleFormat format, size_t len)
|
||||||
{
|
{
|
||||||
|
DoAppend(buffer, format, len, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @excsafety{Strong} */
|
||||||
|
SeqBlock::SampleBlockPtr Sequence::DoAppend(
|
||||||
|
samplePtr buffer, sampleFormat format, size_t len, bool coalesce)
|
||||||
|
{
|
||||||
|
SeqBlock::SampleBlockPtr result;
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return;
|
return result;
|
||||||
|
|
||||||
auto &factory = *mpFactory;
|
auto &factory = *mpFactory;
|
||||||
|
|
||||||
@ -1492,7 +1532,8 @@ void Sequence::Append(samplePtr buffer, sampleFormat format, size_t len)
|
|||||||
size_t bufferSize = mMaxSamples;
|
size_t bufferSize = mMaxSamples;
|
||||||
SampleBuffer buffer2(bufferSize, mSampleFormat);
|
SampleBuffer buffer2(bufferSize, mSampleFormat);
|
||||||
bool replaceLast = false;
|
bool replaceLast = false;
|
||||||
if (numBlocks > 0 &&
|
if (coalesce &&
|
||||||
|
numBlocks > 0 &&
|
||||||
(length =
|
(length =
|
||||||
(pLastBlock = &mBlock.back())->sb->GetSampleCount()) < mMinSamples) {
|
(pLastBlock = &mBlock.back())->sb->GetSampleCount()) < mMinSamples) {
|
||||||
// Enlarge a sub-minimum block at the end
|
// Enlarge a sub-minimum block at the end
|
||||||
@ -1529,6 +1570,10 @@ void Sequence::Append(samplePtr buffer, sampleFormat format, size_t len)
|
|||||||
SampleBlockPtr pBlock;
|
SampleBlockPtr pBlock;
|
||||||
if (format == mSampleFormat) {
|
if (format == mSampleFormat) {
|
||||||
pBlock = factory.Create(buffer, addedLen, mSampleFormat);
|
pBlock = factory.Create(buffer, addedLen, mSampleFormat);
|
||||||
|
// It's expected that when not requesting coalescence, the
|
||||||
|
// data should fit in one block
|
||||||
|
wxASSERT( coalesce || !result );
|
||||||
|
result = pBlock;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CopySamples(buffer, format, buffer2.ptr(), mSampleFormat, addedLen);
|
CopySamples(buffer, format, buffer2.ptr(), mSampleFormat, addedLen);
|
||||||
@ -1551,6 +1596,8 @@ void Sequence::Append(samplePtr buffer, sampleFormat format, size_t len)
|
|||||||
#ifdef VERY_SLOW_CHECKING
|
#ifdef VERY_SLOW_CHECKING
|
||||||
ConsistencyCheck(wxT("Append"));
|
ConsistencyCheck(wxT("Append"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequence::Blockify(SampleBlockFactory &factory,
|
void Sequence::Blockify(SampleBlockFactory &factory,
|
||||||
|
@ -103,6 +103,11 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
|
|||||||
|
|
||||||
size_t GetIdealAppendLen() const;
|
size_t GetIdealAppendLen() const;
|
||||||
void Append(samplePtr buffer, sampleFormat format, size_t len);
|
void Append(samplePtr buffer, sampleFormat format, size_t len);
|
||||||
|
|
||||||
|
//! Append data, not coalescing blocks, returning a pointer to the new block.
|
||||||
|
SeqBlock::SampleBlockPtr AppendNewBlock(samplePtr buffer, sampleFormat format, size_t len);
|
||||||
|
//! Append a complete block, not coalescing
|
||||||
|
void AppendSharedBlock(const SeqBlock::SampleBlockPtr &pBlock);
|
||||||
void Delete(sampleCount start, sampleCount len);
|
void Delete(sampleCount start, sampleCount len);
|
||||||
|
|
||||||
void SetSilence(sampleCount s0, sampleCount len);
|
void SetSilence(sampleCount s0, sampleCount len);
|
||||||
@ -196,6 +201,9 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
|
|||||||
|
|
||||||
int FindBlock(sampleCount pos) const;
|
int FindBlock(sampleCount pos) const;
|
||||||
|
|
||||||
|
SeqBlock::SampleBlockPtr DoAppend(
|
||||||
|
samplePtr buffer, sampleFormat format, size_t len, bool coalesce);
|
||||||
|
|
||||||
static void AppendBlock(SampleBlockFactory *pFactory, sampleFormat format,
|
static void AppendBlock(SampleBlockFactory *pFactory, sampleFormat format,
|
||||||
BlockArray &blocks,
|
BlockArray &blocks,
|
||||||
sampleCount &numSamples,
|
sampleCount &numSamples,
|
||||||
|
@ -1202,6 +1202,19 @@ void WaveClip::GetDisplayRect(wxRect* r)
|
|||||||
*r = mDisplayRect;
|
*r = mDisplayRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! @excsafety{Strong} */
|
||||||
|
std::shared_ptr<SampleBlock> WaveClip::AppendNewBlock(
|
||||||
|
samplePtr buffer, sampleFormat format, size_t len)
|
||||||
|
{
|
||||||
|
return mSequence->AppendNewBlock( buffer, format, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @excsafety{Strong} */
|
||||||
|
void WaveClip::AppendSharedBlock(const std::shared_ptr<SampleBlock> &pBlock)
|
||||||
|
{
|
||||||
|
mSequence->AppendSharedBlock( pBlock );
|
||||||
|
}
|
||||||
|
|
||||||
/*! @excsafety{Partial}
|
/*! @excsafety{Partial}
|
||||||
-- Some prefix (maybe none) of the buffer is appended,
|
-- Some prefix (maybe none) of the buffer is appended,
|
||||||
and no content already flushed to disk is lost. */
|
and no content already flushed to disk is lost. */
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
class BlockArray;
|
class BlockArray;
|
||||||
class Envelope;
|
class Envelope;
|
||||||
class ProgressDialog;
|
class ProgressDialog;
|
||||||
|
class SampleBlock;
|
||||||
class SampleBlockFactory;
|
class SampleBlockFactory;
|
||||||
using SampleBlockFactoryPtr = std::shared_ptr<SampleBlockFactory>;
|
using SampleBlockFactoryPtr = std::shared_ptr<SampleBlockFactory>;
|
||||||
class Sequence;
|
class Sequence;
|
||||||
@ -280,6 +281,13 @@ public:
|
|||||||
* function to tell the envelope about it. */
|
* function to tell the envelope about it. */
|
||||||
void UpdateEnvelopeTrackLen();
|
void UpdateEnvelopeTrackLen();
|
||||||
|
|
||||||
|
//! For use in importing pre-version-3 projects to preserve sharing of blocks
|
||||||
|
std::shared_ptr<SampleBlock> AppendNewBlock(
|
||||||
|
samplePtr buffer, sampleFormat format, size_t len);
|
||||||
|
|
||||||
|
//! For use in importing pre-version-3 projects to preserve sharing of blocks
|
||||||
|
void AppendSharedBlock(const std::shared_ptr<SampleBlock> &pBlock);
|
||||||
|
|
||||||
/// You must call Flush after the last Append
|
/// You must call Flush after the last Append
|
||||||
/// @return true if at least one complete block was created
|
/// @return true if at least one complete block was created
|
||||||
bool Append(samplePtr buffer, sampleFormat format,
|
bool Append(samplePtr buffer, sampleFormat format,
|
||||||
|
@ -196,7 +196,8 @@ private:
|
|||||||
const wxChar **mAttrs;
|
const wxChar **mAttrs;
|
||||||
|
|
||||||
wxFileName mProjDir;
|
wxFileName mProjDir;
|
||||||
using BlockFileMap = std::map<wxString, FilePath>;
|
using BlockFileMap =
|
||||||
|
std::map<wxString, std::pair<FilePath, std::shared_ptr<SampleBlock>>>;
|
||||||
BlockFileMap mFileMap;
|
BlockFileMap mFileMap;
|
||||||
|
|
||||||
ListOfTracks mTracks;
|
ListOfTracks mTracks;
|
||||||
@ -774,10 +775,9 @@ bool AUPImportFileHandle::HandleProject(XMLTagHandler *&handler)
|
|||||||
&files,
|
&files,
|
||||||
"*.*");
|
"*.*");
|
||||||
|
|
||||||
for (size_t i = 0; i < cnt; ++i)
|
for (const auto &fn : files)
|
||||||
{
|
{
|
||||||
FilePath fn = files[i];
|
mFileMap[wxFileNameFromPath(fn)] = {fn, {}};
|
||||||
mFileMap[wxFileNameFromPath(fn)] = fn;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!wxStrcmp(attr, wxT("rate")))
|
else if (!wxStrcmp(attr, wxT("rate")))
|
||||||
@ -1199,7 +1199,7 @@ bool AUPImportFileHandle::HandleSimpleBlockFile(XMLTagHandler *&handler)
|
|||||||
{
|
{
|
||||||
if (mFileMap.find(strValue) != mFileMap.end())
|
if (mFileMap.find(strValue) != mFileMap.end())
|
||||||
{
|
{
|
||||||
filename = mFileMap[strValue];
|
filename = mFileMap[strValue].first;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1387,6 +1387,14 @@ bool AUPImportFileHandle::AddSamples(const FilePath &filename,
|
|||||||
sampleCount origin /* = 0 */,
|
sampleCount origin /* = 0 */,
|
||||||
int channel /* = 0 */)
|
int channel /* = 0 */)
|
||||||
{
|
{
|
||||||
|
auto pClip = mClip ? mClip : mWaveTrack->RightmostOrNewClip();
|
||||||
|
auto &pBlock = mFileMap[wxFileNameFromPath(filename)].second;
|
||||||
|
if (pBlock) {
|
||||||
|
// Replicate the sharing of blocks
|
||||||
|
pClip->AppendSharedBlock( pBlock );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Third party library has its own type alias, check it before
|
// Third party library has its own type alias, check it before
|
||||||
// adding origin + size_t
|
// adding origin + size_t
|
||||||
static_assert(sizeof(sampleCount::type) <= sizeof(sf_count_t),
|
static_assert(sizeof(sampleCount::type) <= sizeof(sf_count_t),
|
||||||
@ -1533,15 +1541,9 @@ bool AUPImportFileHandle::AddSamples(const FilePath &filename,
|
|||||||
wxASSERT(mClip || mWaveTrack);
|
wxASSERT(mClip || mWaveTrack);
|
||||||
|
|
||||||
// Add the samples to the clip/track
|
// Add the samples to the clip/track
|
||||||
if (mClip)
|
if (pClip)
|
||||||
{
|
{
|
||||||
mClip->Append(bufptr, format, cnt);
|
pBlock = pClip->AppendNewBlock(bufptr, format, cnt);
|
||||||
mClip->Flush();
|
|
||||||
}
|
|
||||||
else if (mWaveTrack)
|
|
||||||
{
|
|
||||||
mWaveTrack->Append(bufptr, format, cnt);
|
|
||||||
mWaveTrack->Flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the finally block know everything is good
|
// Let the finally block know everything is good
|
||||||
|
Loading…
x
Reference in New Issue
Block a user