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:
commit
7a1b4eb149
@ -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()"));
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user