1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-24 16:01:16 +02:00

Duplicate command copies cutlines

This commit is contained in:
Paul Licameli 2016-11-26 15:20:28 -05:00
parent 934a505e1a
commit b4734ff790
3 changed files with 56 additions and 29 deletions

View File

@ -300,7 +300,8 @@ static void ComputeSpectrumUsingRealFFTf
}
}
WaveClip::WaveClip(const std::shared_ptr<DirManager> &projDirManager, sampleFormat format, int rate)
WaveClip::WaveClip(const std::shared_ptr<DirManager> &projDirManager,
sampleFormat format, int rate)
{
mRate = rate;
mSequence = std::make_unique<Sequence>(projDirManager, format);
@ -312,7 +313,9 @@ WaveClip::WaveClip(const std::shared_ptr<DirManager> &projDirManager, sampleForm
mSpecPxCache = std::make_unique<SpecPxCache>(1);
}
WaveClip::WaveClip(const WaveClip& orig, const std::shared_ptr<DirManager> &projDirManager)
WaveClip::WaveClip(const WaveClip& orig,
const std::shared_ptr<DirManager> &projDirManager,
bool copyCutlines)
{
// essentially a copy constructor - but you must pass in the
// current project's DirManager, because we might be copying
@ -331,14 +334,17 @@ WaveClip::WaveClip(const WaveClip& orig, const std::shared_ptr<DirManager> &proj
mSpecCache = std::make_unique<SpecCache>();
mSpecPxCache = std::make_unique<SpecPxCache>(1);
for (const auto &clip: orig.mCutLines)
mCutLines.push_back(make_movable<WaveClip>(*clip, projDirManager));
if ( copyCutlines )
for (const auto &clip: orig.mCutLines)
mCutLines.push_back
( make_movable<WaveClip>( *clip, projDirManager, true ) );
mIsPlaceholder = orig.GetIsPlaceholder();
}
WaveClip::WaveClip(const WaveClip& orig,
const std::shared_ptr<DirManager> &projDirManager,
bool copyCutlines,
double t0, double t1)
{
// Copy only a range of the other WaveClip
@ -363,6 +369,21 @@ WaveClip::WaveClip(const WaveClip& orig,
mEnvelope->CopyFrom(orig.mEnvelope.get(),
mOffset + s0.as_double()/mRate,
mOffset + s1.as_double()/mRate);
if ( copyCutlines )
// Copy cutline clips that fall in the range
for (const auto &ppClip : orig.mCutLines)
{
const WaveClip* clip = ppClip.get();
double cutlinePosition = orig.mOffset + clip->GetOffset();
if (cutlinePosition >= t0 && cutlinePosition <= t1)
{
auto newCutLine =
make_movable< WaveClip >( *clip, projDirManager, true );
newCutLine->SetOffset( cutlinePosition - t0 );
mCutLines.push_back(std::move(newCutLine));
}
}
}
@ -1518,7 +1539,7 @@ bool WaveClip::Paste(double t0, const WaveClip* other)
if (clipNeedsResampling || clipNeedsNewFormat)
{
newClip =
std::make_unique<WaveClip>(*other, mSequence->GetDirManager());
std::make_unique<WaveClip>(*other, mSequence->GetDirManager(), true);
if (clipNeedsResampling)
// The other clip's rate is different from ours, so resample
if (!newClip->Resample(mRate))
@ -1548,7 +1569,11 @@ bool WaveClip::Paste(double t0, const WaveClip* other)
for (const auto &cutline: pastedClip->mCutLines)
{
mCutLines.push_back(
make_movable<WaveClip>(*cutline, mSequence->GetDirManager()));
make_movable<WaveClip>
( *cutline, mSequence->GetDirManager(),
// Recursively copy cutlines of cutlines. They don't need
// their offsets adjusted.
true));
mCutLines.back()->Offset(t0 - mOffset);
}
@ -1645,21 +1670,19 @@ bool WaveClip::ClearAndAddCutLine(double t0, double t1)
const double clip_t1 = std::min( t1, GetEndTime() );
auto newClip = make_movable<WaveClip>
(*this, mSequence->GetDirManager(), clip_t0, clip_t1);
(*this, mSequence->GetDirManager(), true, clip_t0, clip_t1);
newClip->SetOffset(clip_t0-mOffset);
// Sort out cutlines that belong to the NEW cutline
// Remove cutlines from this clip that were in the selection, shift
// left those that were after the selection
// May DELETE as we iterate, so don't use range-for
for (auto it = mCutLines.begin(); it != mCutLines.end();)
{
WaveClip* clip = it->get();
double cutlinePosition = mOffset + clip->GetOffset();
if (cutlinePosition >= t0 && cutlinePosition <= t1)
{
clip->SetOffset(cutlinePosition - newClip->GetOffset() - mOffset);
newClip->mCutLines.push_back(std::move(*it)); // transfer ownership!!
it = mCutLines.erase(it);
}
else
{
if (cutlinePosition >= t1)
@ -1754,11 +1777,6 @@ bool WaveClip::RemoveCutLine(double cutLinePosition)
return false;
}
void WaveClip::RemoveAllCutLines()
{
mCutLines.clear();
}
void WaveClip::OffsetCutLines(double t0, double len)
{
for (const auto &cutLine : mCutLines)

View File

@ -215,11 +215,14 @@ public:
// essentially a copy constructor - but you must pass in the
// current project's DirManager, because we might be copying
// from one project to another
WaveClip(const WaveClip& orig, const std::shared_ptr<DirManager> &projDirManager);
WaveClip(const WaveClip& orig,
const std::shared_ptr<DirManager> &projDirManager,
bool copyCutlines);
// Copy only a range from the given WaveClip
WaveClip(const WaveClip& orig,
const std::shared_ptr<DirManager> &projDirManager,
bool copyCutlines,
double t0, double t1);
virtual ~WaveClip();
@ -341,7 +344,6 @@ public:
/// Remove cut line, without expanding the audio in it
bool RemoveCutLine(double cutLinePosition);
void RemoveAllCutLines();
/// Offset cutlines right to time 't0' by time amount 'len'
void OffsetCutLines(double t0, double len);

View File

@ -132,7 +132,8 @@ WaveTrack::WaveTrack(const WaveTrack &orig):
Init(orig);
for (const auto &clip : orig.mClips)
mClips.push_back(make_movable<WaveClip>(*clip, mDirManager));
mClips.push_back
( make_movable<WaveClip>( *clip, mDirManager, true ) );
}
// Copy the track metadata but not the contents.
@ -641,6 +642,10 @@ Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const
newTrack->Init(*this);
// PRL: Why shouldn't cutlines be copied and pasted too? I don't know, but
// that was the old behavior. But this function is also used by the
// Duplicate command and I changed its behavior in that case.
for (const auto &clip : mClips)
{
if (t0 <= clip->GetStartTime() && t1 >= clip->GetEndTime())
@ -649,9 +654,8 @@ Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const
//printf("copy: clip %i is in copy region\n", (int)clip);
newTrack->mClips.push_back
(make_movable<WaveClip>(*clip, mDirManager));
(make_movable<WaveClip>(*clip, mDirManager, ! forClipboard));
WaveClip *const newClip = newTrack->mClips.back().get();
newClip->RemoveAllCutLines();
newClip->Offset(-t0);
}
else if (t1 > clip->GetStartTime() && t0 < clip->GetEndTime())
@ -663,8 +667,7 @@ Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const
const double clip_t1 = std::min(t1, clip->GetEndTime());
auto newClip = make_movable<WaveClip>
(*clip, mDirManager, clip_t0, clip_t1);
newClip->RemoveAllCutLines();
(*clip, mDirManager, ! forClipboard, clip_t0, clip_t1);
//printf("copy: clip_t0=%f, clip_t1=%f\n", clip_t0, clip_t1);
@ -1055,7 +1058,8 @@ bool WaveTrack::HandleClear(double t0, double t1,
{
if (!clip->ClearAndAddCutLine(t0,t1))
return false;
} else
}
else
{
if (split) {
// Three cases:
@ -1074,11 +1078,13 @@ bool WaveTrack::HandleClear(double t0, double t1,
// NEW clips out of the left and right halves...
// left
clipsToAdd.push_back(make_movable<WaveClip>(*clip, mDirManager));
clipsToAdd.push_back
( make_movable<WaveClip>( *clip, mDirManager, true ) );
clipsToAdd.back()->Clear(t0, clip->GetEndTime());
// right
clipsToAdd.push_back(make_movable<WaveClip>(*clip, mDirManager));
clipsToAdd.push_back
( make_movable<WaveClip>( *clip, mDirManager, true ) );
WaveClip *const right = clipsToAdd.back().get();
right->Clear(clip->GetStartTime(), t1);
right->Offset(t1 - clip->GetStartTime());
@ -1335,7 +1341,8 @@ bool WaveTrack::Paste(double t0, const Track *src)
// AWD Oct. 2009: Don't actually paste in placeholder clips
if (!clip->GetIsPlaceholder())
{
auto newClip = make_movable<WaveClip>(*clip, mDirManager);
auto newClip =
make_movable<WaveClip>( *clip, mDirManager, true );
newClip->Resample(mRate);
newClip->Offset(t0);
newClip->MarkChanged();
@ -2363,7 +2370,7 @@ bool WaveTrack::SplitAt(double t)
if(t - 1.0/c->GetRate() >= c->GetOffset())
c->GetEnvelope()->Insert(t - c->GetOffset() - 1.0/c->GetRate(), val); // frame end points
c->GetEnvelope()->Insert(t - c->GetOffset(), val);
auto newClip = make_movable<WaveClip>(*c, mDirManager);
auto newClip = make_movable<WaveClip>( *c, mDirManager, true );
if (!c->Clear(t, c->GetEndTime()))
{
return false;