1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-05 22:28:57 +02:00

Sequence::Copy is a factory returning smart pointer. WaveClip stores it.

This commit is contained in:
Paul Licameli 2016-04-10 20:48:03 -04:00
commit 7a1b4eb149
4 changed files with 29 additions and 47 deletions

View File

@ -29,6 +29,7 @@
#include "Audacity.h"
#include "Sequence.h"
#include <algorithm>
#include <float.h>
@ -40,8 +41,6 @@
#include <wx/ffile.h>
#include <wx/log.h>
#include "Sequence.h"
#include "BlockFile.h"
#include "blockfile/ODDecodeBlockFile.h"
#include "DirManager.h"
@ -406,9 +405,9 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len,
return true;
}
bool Sequence::Copy(sampleCount s0, sampleCount s1, Sequence **dest)
bool Sequence::Copy(sampleCount s0, sampleCount s1, std::unique_ptr<Sequence> &dest) const
{
*dest = 0;
dest.reset();
if (s0 >= s1 || s0 >= mNumSamples || s1 < 0)
return false;
@ -423,8 +422,8 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, Sequence **dest)
wxUnusedVar(numBlocks);
wxASSERT(b0 <= b1);
*dest = new Sequence(mDirManager, mSampleFormat);
(*dest)->mBlock.reserve(b1 - b0 + 1);
dest = std::make_unique<Sequence>(mDirManager, mSampleFormat);
dest->mBlock.reserve(b1 - b0 + 1);
SampleBuffer buffer(mMaxSamples, mSampleFormat);
@ -439,14 +438,14 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, Sequence **dest)
wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29
Get(b0, buffer.ptr(), mSampleFormat, s0, blocklen);
(*dest)->Append(buffer.ptr(), mSampleFormat, blocklen);
dest->Append(buffer.ptr(), mSampleFormat, blocklen);
}
else
--b0;
// If there are blocks in the middle, copy the blockfiles directly
for (int bb = b0 + 1; bb < b1; ++bb)
(*dest)->AppendBlock(mBlock[bb]); // Increase ref count or duplicate file
dest->AppendBlock(mBlock[bb]); // Increase ref count or duplicate file
// Do the last block
if (b1 > b0) {
@ -456,11 +455,11 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, Sequence **dest)
wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29
if (blocklen < file->GetLength()) {
Get(b1, buffer.ptr(), mSampleFormat, block.start, blocklen);
(*dest)->Append(buffer.ptr(), mSampleFormat, blocklen);
dest->Append(buffer.ptr(), mSampleFormat, blocklen);
}
else
// Special case, copy exactly
(*dest)->AppendBlock(block); // Increase ref count or duplicate file
dest->AppendBlock(block); // Increase ref count or duplicate file
}
return ConsistencyCheck(wxT("Sequence::Copy()"));

View File

@ -11,6 +11,7 @@
#ifndef __AUDACITY_SEQUENCE__
#define __AUDACITY_SEQUENCE__
#include "MemoryX.h"
#include <vector>
#include <wx/string.h>
#include <wx/dynarray.h>
@ -99,7 +100,7 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
bool GetWaveDisplay(float *min, float *max, float *rms, int* bl,
int len, const sampleCount *where);
bool Copy(sampleCount s0, sampleCount s1, Sequence **dest);
bool Copy(sampleCount s0, sampleCount s1, std::unique_ptr<Sequence> &dest) const;
bool Paste(sampleCount s0, const Sequence *src);
sampleCount GetIdealAppendLen();

View File

@ -294,7 +294,7 @@ WaveClip::WaveClip(DirManager *projDirManager, sampleFormat format, int rate)
{
mOffset = 0;
mRate = rate;
mSequence = new Sequence(projDirManager, format);
mSequence = std::make_unique<Sequence>(projDirManager, format);
mEnvelope = new Envelope();
mWaveCache = new WaveCache();
mSpecCache = new SpecCache();
@ -312,7 +312,7 @@ WaveClip::WaveClip(const WaveClip& orig, DirManager *projDirManager)
mOffset = orig.mOffset;
mRate = orig.mRate;
mSequence = new Sequence(*orig.mSequence, projDirManager);
mSequence = std::make_unique<Sequence>(*orig.mSequence, projDirManager);
mEnvelope = new Envelope();
mEnvelope->Paste(0.0, orig.mEnvelope);
mEnvelope->SetOffset(orig.GetOffset());
@ -331,8 +331,6 @@ WaveClip::WaveClip(const WaveClip& orig, DirManager *projDirManager)
WaveClip::~WaveClip()
{
delete mSequence;
delete mEnvelope;
mEnvelope = NULL;
@ -547,7 +545,7 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
if (match &&
mWaveCache->start == t0 &&
mWaveCache->len >= numPixels) {
mWaveCache->LoadInvalidRegions(mSequence, true);
mWaveCache->LoadInvalidRegions(mSequence.get(), true);
mWaveCache->ClearInvalidRegions();
// Satisfy the request completely from the cache
@ -604,7 +602,7 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
//TODO: only load inval regions if
//necessary. (usually is the case, so no rush.)
//also, we should be updating the NEW cache, but here we are patching the old one up.
oldCache->LoadInvalidRegions(mSequence, false);
oldCache->LoadInvalidRegions(mSequence.get(), false);
oldCache->ClearInvalidRegions();
// Copy what we can from the old cache.
@ -1379,7 +1377,7 @@ void WaveClip::HandleXMLEndTag(const wxChar *tag)
XMLTagHandler *WaveClip::HandleXMLChild(const wxChar *tag)
{
if (!wxStrcmp(tag, wxT("sequence")))
return mSequence;
return mSequence.get();
else if (!wxStrcmp(tag, wxT("envelope")))
return mEnvelope;
else if (!wxStrcmp(tag, wxT("waveclip")))
@ -1414,15 +1412,14 @@ bool WaveClip::CreateFromCopy(double t0, double t1, const WaveClip* other)
other->TimeToSamplesClip(t0, &s0);
other->TimeToSamplesClip(t1, &s1);
Sequence* oldSequence = mSequence;
std::unique_ptr<Sequence> oldSequence = std::move(mSequence);
mSequence = NULL;
if (!other->mSequence->Copy(s0, s1, &mSequence))
if (!other->mSequence->Copy(s0, s1, mSequence))
{
mSequence = oldSequence;
mSequence = std::move(oldSequence);
return false;
}
delete oldSequence;
delete mEnvelope;
mEnvelope = new Envelope();
mEnvelope->CopyFrom(other->mEnvelope, (double)s0/mRate, (double)s1/mRate);
@ -1461,7 +1458,7 @@ bool WaveClip::Paste(double t0, const WaveClip* other)
TimeToSamplesClip(t0, &s0);
bool result = false;
if (mSequence->Paste(s0, pastedClip->mSequence))
if (mSequence->Paste(s0, pastedClip->mSequence.get()))
{
MarkChanged();
mEnvelope->Paste((double)s0/mRate + mOffset, pastedClip->mEnvelope);
@ -1741,8 +1738,8 @@ bool WaveClip::Resample(int rate, ProgressDialog *progress)
int outGenerated = 0;
sampleCount numSamples = mSequence->GetNumSamples();
Sequence* newSequence =
new Sequence(mSequence->GetDirManager(), mSequence->GetSampleFormat());
auto newSequence =
std::make_unique<Sequence>(mSequence->GetDirManager(), mSequence->GetSampleFormat());
/**
* We want to keep going as long as we have something to feed the resampler
@ -1796,13 +1793,9 @@ bool WaveClip::Resample(int rate, ProgressDialog *progress)
delete[] inBuffer;
delete[] outBuffer;
if (error)
if (!error)
{
delete newSequence;
} else
{
delete mSequence;
mSequence = newSequence;
mSequence = std::move(newSequence);
mRate = rate;
// Invalidate wave display cache

View File

@ -13,6 +13,7 @@
#define __AUDACITY_WAVECLIP__
#include "Audacity.h"
#include "MemoryX.h"
#include "SampleFormat.h"
#include "widgets/ProgressDialog.h"
#include "ondemand/ODTaskThread.h"
@ -205,20 +206,8 @@ class AUDACITY_DLL_API WaveClip final : public XMLTagHandler
{
private:
// It is an error to copy a WaveClip without specifying the DirManager.
// We define these break-inducing single-arg methods so that
// if some developer makes the mistake of calling a single-arg copy
// constructor rather than the one below (that requires a DirManager*),
// rather than it going to C++-generated default copy constructor,
// it goes here and the error is made clear to that developer.
WaveClip(const WaveClip&)
{
wxFAIL_MSG(wxT("It is an error to copy a WaveClip without specifying the DirManager."));
}
WaveClip& operator=(const WaveClip& orig)
{
WaveClip bogus(orig);
return *this;
}
WaveClip(const WaveClip&) PROHIBITED;
WaveClip& operator= (const WaveClip&) PROHIBITED;
public:
// typical constructor
@ -271,7 +260,7 @@ public:
// Get low-level access to the sequence. Whenever possible, don't use this,
// but use more high-level functions inside WaveClip (or add them if you
// think they are useful for general use)
Sequence* GetSequence() { return mSequence; }
Sequence* GetSequence() { return mSequence.get(); }
/** WaveTrack calls this whenever data in the wave clip changes. It is
* called automatically when WaveClip has a chance to know that something
@ -387,7 +376,7 @@ protected:
int mRate;
int mDirty;
bool mIsCutLine;
Sequence *mSequence;
std::unique_ptr<Sequence> mSequence;
Envelope *mEnvelope;
mutable WaveCache *mWaveCache;