1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-09 08:53:23 +02:00

TrackList holds smart pointers to tracks, Add() only takes rvalue refs to such

This commit is contained in:
Paul Licameli 2016-03-13 11:08:21 -04:00
parent 7d1ea7b82e
commit a6ca36cdab
10 changed files with 209 additions and 183 deletions

View File

@ -319,9 +319,9 @@ bool LabelDialog::TransferDataFromWindow()
wxString name = mTrackNames[tndx + 1].AfterFirst(wxT('-')).Mid(1); wxString name = mTrackNames[tndx + 1].AfterFirst(wxT('-')).Mid(1);
// Create the NEW track and add to track list // Create the NEW track and add to track list
LabelTrack *newTrack = mFactory.NewLabelTrack().release(); auto newTrack = mFactory.NewLabelTrack();
newTrack->SetName(name); newTrack->SetName(name);
mTracks->Add(newTrack); mTracks->Add(std::move(newTrack));
tndx++; tndx++;
} }

View File

@ -3341,7 +3341,7 @@ bool AudacityProject::OnEffect(const PluginID & ID, int flags)
TrackListIterator iter(mTracks); TrackListIterator iter(mTracks);
Track *t = iter.First(); Track *t = iter.First();
WaveTrack *newTrack = NULL; WaveTrack *newTrack{};
wxWindow *focus = wxWindow::FindFocus(); wxWindow *focus = wxWindow::FindFocus();
//double prevEndTime = mTracks->GetEndTime(); //double prevEndTime = mTracks->GetEndTime();
@ -3359,8 +3359,7 @@ bool AudacityProject::OnEffect(const PluginID & ID, int flags)
// No tracks were selected... // No tracks were selected...
if (type == EffectTypeGenerate) { if (type == EffectTypeGenerate) {
// Create a NEW track for the generated audio... // Create a NEW track for the generated audio...
newTrack = mTrackFactory->NewWaveTrack().release(); newTrack = static_cast<WaveTrack*>(mTracks->Add(mTrackFactory->NewWaveTrack()));
mTracks->Add(newTrack);
newTrack->SetSelected(true); newTrack->SetSelected(true);
} }
} }
@ -3851,7 +3850,7 @@ void AudacityProject::OnCut()
dest->SetChannel(n->GetChannel()); dest->SetChannel(n->GetChannel());
dest->SetLinked(n->GetLinked()); dest->SetLinked(n->GetLinked());
dest->SetName(n->GetName()); dest->SetName(n->GetName());
msClipboard->Add(dest.release()); msClipboard->Add(std::move(dest));
} }
} }
n = iter.Next(); n = iter.Next();
@ -3925,7 +3924,7 @@ void AudacityProject::OnSplitCut()
dest->SetChannel(n->GetChannel()); dest->SetChannel(n->GetChannel());
dest->SetLinked(n->GetLinked()); dest->SetLinked(n->GetLinked());
dest->SetName(n->GetName()); dest->SetName(n->GetName());
msClipboard->Add(dest.release()); msClipboard->Add(std::move(dest));
} }
} }
n = iter.Next(); n = iter.Next();
@ -3970,7 +3969,7 @@ void AudacityProject::OnCopy()
dest->SetChannel(n->GetChannel()); dest->SetChannel(n->GetChannel());
dest->SetLinked(n->GetLinked()); dest->SetLinked(n->GetLinked());
dest->SetName(n->GetName()); dest->SetName(n->GetName());
msClipboard->Add(dest.release()); msClipboard->Add(std::move(dest));
} }
} }
n = iter.Next(); n = iter.Next();
@ -4251,7 +4250,7 @@ bool AudacityProject::HandlePasteNothingSelected()
if (!pClip) if (!pClip)
return true; // nothing to paste return true; // nothing to paste
Track* pNewTrack; Track::Holder pNewTrack;
Track* pFirstNewTrack = NULL; Track* pFirstNewTrack = NULL;
while (pClip) { while (pClip) {
if ((msClipProject != this) && (pClip->GetKind() == Track::Wave)) if ((msClipProject != this) && (pClip->GetKind() == Track::Wave))
@ -4261,19 +4260,19 @@ bool AudacityProject::HandlePasteNothingSelected()
case Track::Wave: case Track::Wave:
{ {
WaveTrack *w = (WaveTrack *)pClip; WaveTrack *w = (WaveTrack *)pClip;
pNewTrack = mTrackFactory->NewWaveTrack(w->GetSampleFormat(), w->GetRate()).release(); pNewTrack = mTrackFactory->NewWaveTrack(w->GetSampleFormat(), w->GetRate());
} }
break; break;
#ifdef USE_MIDI #ifdef USE_MIDI
case Track::Note: case Track::Note:
pNewTrack = mTrackFactory->NewNoteTrack().release(); pNewTrack = mTrackFactory->NewNoteTrack();
break; break;
#endif // USE_MIDI #endif // USE_MIDI
case Track::Label: case Track::Label:
pNewTrack = mTrackFactory->NewLabelTrack().release(); pNewTrack = mTrackFactory->NewLabelTrack();
break; break;
case Track::Time: case Track::Time:
pNewTrack = mTrackFactory->NewTimeTrack().release(); pNewTrack = mTrackFactory->NewTimeTrack();
break; break;
default: default:
pClip = iterClip.Next(); pClip = iterClip.Next();
@ -4288,14 +4287,16 @@ bool AudacityProject::HandlePasteNothingSelected()
bool bResult = pNewTrack->Paste(0.0, pClip); bool bResult = pNewTrack->Paste(0.0, pClip);
wxASSERT(bResult); // TO DO: Actually handle this. wxASSERT(bResult); // TO DO: Actually handle this.
wxUnusedVar(bResult); wxUnusedVar(bResult);
mTracks->Add(pNewTrack);
if (!pFirstNewTrack)
pFirstNewTrack = pNewTrack.get();
pNewTrack->SetSelected(true); pNewTrack->SetSelected(true);
mTracks->Add(std::move(pNewTrack));
if (msClipProject != this && pClip->GetKind() == Track::Wave) if (msClipProject != this && pClip->GetKind() == Track::Wave)
((WaveTrack *) pClip)->Unlock(); ((WaveTrack *) pClip)->Unlock();
if (!pFirstNewTrack)
pFirstNewTrack = pNewTrack;
pClip = iterClip.Next(); pClip = iterClip.Next();
} }
@ -4352,8 +4353,7 @@ void AudacityProject::OnPasteNewLabel()
// If no match found, add one // If no match found, add one
if (!t) { if (!t) {
t = GetTrackFactory()->NewLabelTrack().release(); t = mTracks->Add(GetTrackFactory()->NewLabelTrack());
mTracks->Add(t);
} }
// Select this track so the loop picks it up // Select this track so the loop picks it up
@ -4562,7 +4562,7 @@ void AudacityProject::OnDuplicate()
if (dest) { if (dest) {
dest->Init(*n); dest->Init(*n);
dest->SetOffset(wxMax(mViewInfo.selectedRegion.t0(), n->GetOffset())); dest->SetOffset(wxMax(mViewInfo.selectedRegion.t0(), n->GetOffset()));
mTracks->Add(dest.release()); mTracks->Add(std::move(dest));
} }
} }
@ -4840,7 +4840,7 @@ void AudacityProject::OnSplitNew()
dest->SetLinked(n->GetLinked()); dest->SetLinked(n->GetLinked());
dest->SetName(n->GetName()); dest->SetName(n->GetName());
dest->SetOffset(wxMax(newt0, offset)); dest->SetOffset(wxMax(newt0, offset));
mTracks->Add(dest.release()); mTracks->Add(std::move(dest));
} }
} }
@ -5489,7 +5489,7 @@ void AudacityProject::OnImportLabels()
return; return;
} }
LabelTrack *newTrack = GetTrackFactory()->NewLabelTrack().release(); auto newTrack = GetTrackFactory()->NewLabelTrack();
wxString sTrackName; wxString sTrackName;
wxFileName::SplitPath(fileName, NULL, NULL, &sTrackName, NULL); wxFileName::SplitPath(fileName, NULL, NULL, &sTrackName, NULL);
newTrack->SetName(sTrackName); newTrack->SetName(sTrackName);
@ -5497,8 +5497,8 @@ void AudacityProject::OnImportLabels()
newTrack->Import(f); newTrack->Import(f);
SelectNone(); SelectNone();
mTracks->Add(newTrack);
newTrack->SetSelected(true); newTrack->SetSelected(true);
mTracks->Add(std::move(newTrack));
PushState(wxString:: PushState(wxString::
Format(_("Imported labels from '%s'"), fileName.c_str()), Format(_("Imported labels from '%s'"), fileName.c_str()),
@ -5532,22 +5532,20 @@ void AudacityProject::OnImportMIDI()
void AudacityProject::DoImportMIDI(const wxString &fileName) void AudacityProject::DoImportMIDI(const wxString &fileName)
{ {
NoteTrack *newTrack = GetTrackFactory()->NewNoteTrack().release(); auto newTrack = GetTrackFactory()->NewNoteTrack();
if (::ImportMIDI(fileName, newTrack)) { if (::ImportMIDI(fileName, newTrack.get())) {
SelectNone(); SelectNone();
mTracks->Add(newTrack); auto pTrack = mTracks->Add(std::move(newTrack));
newTrack->SetSelected(true); pTrack->SetSelected(true);
PushState(wxString::Format(_("Imported MIDI from '%s'"), PushState(wxString::Format(_("Imported MIDI from '%s'"),
fileName.c_str()), _("Import MIDI")); fileName.c_str()), _("Import MIDI"));
RedrawProject(); RedrawProject();
mTrackPanel->EnsureVisible(newTrack); mTrackPanel->EnsureVisible(pTrack);
} }
else
delete newTrack;
} }
#endif // USE_MIDI #endif // USE_MIDI
@ -5611,10 +5609,8 @@ void AudacityProject::HandleMixAndRender(bool toNewTrack)
auto results = auto results =
::MixAndRender(mTracks, mTrackFactory, mRate, mDefaultFormat, 0.0, 0.0); ::MixAndRender(mTracks, mTrackFactory, mRate, mDefaultFormat, 0.0, 0.0);
auto &uNewLeft = results.first, &uNewRight = results.second; auto &uNewLeft = results.first, &uNewRight = results.second;
const auto newLeft = uNewLeft.get();
const auto newRight = uNewRight.get();
if (newLeft) { if (uNewLeft) {
// Remove originals, get stats on what tracks were mixed // Remove originals, get stats on what tracks were mixed
TrackListIterator iter(mTracks); TrackListIterator iter(mTracks);
@ -5644,15 +5640,16 @@ void AudacityProject::HandleMixAndRender(bool toNewTrack)
// Add NEW tracks // Add NEW tracks
mTracks->Add(uNewLeft.release()); auto pNewLeft = mTracks->Add(std::move(uNewLeft));
if (newRight) decltype(pNewLeft) pNewRight{};
mTracks->Add(uNewRight.release()); if (uNewRight)
pNewRight = mTracks->Add(std::move(uNewRight));
// If we're just rendering (not mixing), keep the track name the same // If we're just rendering (not mixing), keep the track name the same
if (selectedCount==1) { if (selectedCount==1) {
newLeft->SetName(firstName); pNewLeft->SetName(firstName);
if (newRight) if (pNewRight)
newRight->SetName(firstName); pNewRight->SetName(firstName);
} }
// Smart history/undo message // Smart history/undo message
@ -5665,7 +5662,7 @@ void AudacityProject::HandleMixAndRender(bool toNewTrack)
} }
else { else {
wxString msg; wxString msg;
if (newRight) if (pNewRight)
msg.Printf(_("Mixed and rendered %d tracks into one new stereo track"), msg.Printf(_("Mixed and rendered %d tracks into one new stereo track"),
selectedCount); selectedCount);
else else
@ -5675,8 +5672,8 @@ void AudacityProject::HandleMixAndRender(bool toNewTrack)
} }
mTrackPanel->SetFocus(); mTrackPanel->SetFocus();
mTrackPanel->SetFocusedTrack(newLeft); mTrackPanel->SetFocusedTrack(pNewLeft);
mTrackPanel->EnsureVisible(newLeft); mTrackPanel->EnsureVisible(pNewLeft);
RedrawProject(); RedrawProject();
} }
} }
@ -6247,10 +6244,9 @@ void AudacityProject::OnScoreAlign()
void AudacityProject::OnNewWaveTrack() void AudacityProject::OnNewWaveTrack()
{ {
WaveTrack *t = mTrackFactory->NewWaveTrack(mDefaultFormat, mRate).release(); auto t = mTracks->Add(mTrackFactory->NewWaveTrack(mDefaultFormat, mRate));
SelectNone(); SelectNone();
mTracks->Add(t);
t->SetSelected(true); t->SetSelected(true);
PushState(_("Created new audio track"), _("New Track")); PushState(_("Created new audio track"), _("New Track"));
@ -6261,18 +6257,16 @@ void AudacityProject::OnNewWaveTrack()
void AudacityProject::OnNewStereoTrack() void AudacityProject::OnNewStereoTrack()
{ {
WaveTrack *t = mTrackFactory->NewWaveTrack(mDefaultFormat, mRate).release(); auto t = mTracks->Add(mTrackFactory->NewWaveTrack(mDefaultFormat, mRate));
t->SetChannel(Track::LeftChannel); t->SetChannel(Track::LeftChannel);
SelectNone(); SelectNone();
mTracks->Add(t);
t->SetSelected(true); t->SetSelected(true);
t->SetLinked (true); t->SetLinked (true);
t = mTrackFactory->NewWaveTrack(mDefaultFormat, mRate).release(); t = mTracks->Add(mTrackFactory->NewWaveTrack(mDefaultFormat, mRate));
t->SetChannel(Track::RightChannel); t->SetChannel(Track::RightChannel);
mTracks->Add(t);
t->SetSelected(true); t->SetSelected(true);
PushState(_("Created new stereo audio track"), _("New Track")); PushState(_("Created new stereo audio track"), _("New Track"));
@ -6283,11 +6277,10 @@ void AudacityProject::OnNewStereoTrack()
void AudacityProject::OnNewLabelTrack() void AudacityProject::OnNewLabelTrack()
{ {
LabelTrack *t = GetTrackFactory()->NewLabelTrack().release(); auto t = mTracks->Add(GetTrackFactory()->NewLabelTrack());
SelectNone(); SelectNone();
mTracks->Add(t);
t->SetSelected(true); t->SetSelected(true);
PushState(_("Created new label track"), _("New Track")); PushState(_("Created new label track"), _("New Track"));
@ -6303,11 +6296,10 @@ void AudacityProject::OnNewTimeTrack()
return; return;
} }
TimeTrack *t = mTrackFactory->NewTimeTrack().release(); auto t = mTracks->AddToHead(mTrackFactory->NewTimeTrack());
SelectNone(); SelectNone();
mTracks->AddToHead(t);
t->SetSelected(true); t->SetSelected(true);
PushState(_("Created new time track"), _("New Track")); PushState(_("Created new time track"), _("New Track"));
@ -6379,8 +6371,8 @@ int AudacityProject::DoAddLabel(const SelectedRegion &region, bool preserveFocus
// If none found, start a NEW label track and use it // If none found, start a NEW label track and use it
if (!lt) { if (!lt) {
lt = GetTrackFactory()->NewLabelTrack().release(); lt = static_cast<LabelTrack*>
mTracks->Add(lt); (mTracks->Add(GetTrackFactory()->NewLabelTrack()));
} }
// LLL: Commented as it seemed a little forceful to remove users // LLL: Commented as it seemed a little forceful to remove users

View File

@ -2751,7 +2751,7 @@ void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory)
} }
} }
mLastSavedTracks->Add(t->Duplicate().release()); mLastSavedTracks->Add(t->Duplicate());
t = iter.Next(); t = iter.Next();
} }
@ -3147,29 +3147,21 @@ XMLTagHandler *AudacityProject::HandleXMLChild(const wxChar *tag)
} }
if (!wxStrcmp(tag, wxT("wavetrack"))) { if (!wxStrcmp(tag, wxT("wavetrack"))) {
WaveTrack *newTrack = mTrackFactory->NewWaveTrack().release(); return mTracks->Add(mTrackFactory->NewWaveTrack());
mTracks->Add(newTrack);
return newTrack;
} }
#ifdef USE_MIDI #ifdef USE_MIDI
if (!wxStrcmp(tag, wxT("notetrack"))) { if (!wxStrcmp(tag, wxT("notetrack"))) {
NoteTrack *newTrack = mTrackFactory->NewNoteTrack().release(); return mTracks->Add(mTrackFactory->NewNoteTrack());
mTracks->Add(newTrack);
return newTrack;
} }
#endif // USE_MIDI #endif // USE_MIDI
if (!wxStrcmp(tag, wxT("labeltrack"))) { if (!wxStrcmp(tag, wxT("labeltrack"))) {
LabelTrack *newTrack = mTrackFactory->NewLabelTrack().release(); return mTracks->Add(mTrackFactory->NewLabelTrack());
mTracks->Add(newTrack);
return newTrack;
} }
if (!wxStrcmp(tag, wxT("timetrack"))) { if (!wxStrcmp(tag, wxT("timetrack"))) {
TimeTrack *newTrack = mTrackFactory->NewTimeTrack().release(); return mTracks->Add(mTrackFactory->NewTimeTrack());
mTracks->Add(newTrack);
return newTrack;
} }
if (!wxStrcmp(tag, wxT("recordingrecovery"))) { if (!wxStrcmp(tag, wxT("recordingrecovery"))) {
@ -3547,10 +3539,8 @@ bool AudacityProject::Save(bool overwrite /* = true */ ,
TrackListIterator iter(mTracks); TrackListIterator iter(mTracks);
Track *t = iter.First(); Track *t = iter.First();
Track *dupT;
while (t) { while (t) {
dupT = t->Duplicate().release(); mLastSavedTracks->Add(t->Duplicate());
mLastSavedTracks->Add(dupT);
//only after the xml has been saved we can mark it saved. //only after the xml has been saved we can mark it saved.
//thus is because the OD blockfiles change on background thread while this is going on. //thus is because the OD blockfiles change on background thread while this is going on.
@ -3582,19 +3572,17 @@ bool AudacityProject::Save(bool overwrite /* = true */ ,
// but that code is really tied into the dialogs. // but that code is really tied into the dialogs.
// Copy the tracks because we're going to do some state changes before exporting. // Copy the tracks because we're going to do some state changes before exporting.
Track* pSavedTrack;
Track* pTrack; Track* pTrack;
WaveTrack* pWaveTrack; WaveTrack* pWaveTrack;
TrackListOfKindIterator iter(Track::Wave, mTracks); TrackListOfKindIterator iter(Track::Wave, mTracks);
unsigned int numWaveTracks = 0; unsigned int numWaveTracks = 0;
TrackList pSavedTrackList{}; TrackList pSavedTrackList;
for (pTrack = iter.First(); pTrack != NULL; pTrack = iter.Next()) for (pTrack = iter.First(); pTrack != NULL; pTrack = iter.Next())
{ {
numWaveTracks++; numWaveTracks++;
pWaveTrack = (WaveTrack*)pTrack; pWaveTrack = (WaveTrack*)pTrack;
pSavedTrack = mTrackFactory->DuplicateWaveTrack(*pWaveTrack).release(); pSavedTrackList.Add(mTrackFactory->DuplicateWaveTrack(*pWaveTrack));
pSavedTrackList.Add(pSavedTrack);
} }
if (numWaveTracks == 0) if (numWaveTracks == 0)
@ -3652,6 +3640,7 @@ bool AudacityProject::Save(bool overwrite /* = true */ ,
// Restore the saved track states and clean up. // Restore the saved track states and clean up.
TrackListIterator savedTrackIter(&pSavedTrackList); TrackListIterator savedTrackIter(&pSavedTrackList);
Track *pSavedTrack;
for (pTrack = iter.First(), pSavedTrack = savedTrackIter.First(); for (pTrack = iter.First(), pSavedTrack = savedTrackIter.First();
((pTrack != NULL) && (pSavedTrack != NULL)); ((pTrack != NULL) && (pSavedTrack != NULL));
pTrack = iter.Next(), pSavedTrack = savedTrackIter.Next()) pTrack = iter.Next(), pSavedTrack = savedTrackIter.Next())
@ -3684,8 +3673,7 @@ void AudacityProject::AddImportedTracks(const wxString &fileName,
for (auto &uNewTrack : newTracks) { for (auto &uNewTrack : newTracks) {
++i; ++i;
Track *newTrack; // TO DO: use unique_ptr, not bare pointer auto newTrack = mTracks->Add(std::move(uNewTrack));
mTracks->Add(newTrack = ((Track*)(uNewTrack.get()))->Duplicate().release()); // Ack! Once mTracks holds a smart pointer, Duplicate() won't be needed.
if (newRate == 0 && newTrack->GetKind() == Track::Wave) { if (newRate == 0 && newTrack->GetKind() == Track::Wave) {
newRate = ((WaveTrack *)newTrack)->GetRate(); newRate = ((WaveTrack *)newTrack)->GetRate();
} }
@ -4066,11 +4054,10 @@ void AudacityProject::PopState(const UndoState &state)
Track *t = iter.First(); Track *t = iter.First();
bool odUsed = false; bool odUsed = false;
ODComputeSummaryTask* computeTask = NULL; ODComputeSummaryTask* computeTask = NULL;
Track* copyTrack;
while (t) while (t)
{ {
mTracks->Add(copyTrack = t->Duplicate().release()); auto copyTrack = mTracks->Add(t->Duplicate());
//add the track to OD if the manager exists. later we might do a more rigorous check... //add the track to OD if the manager exists. later we might do a more rigorous check...
if (copyTrack->GetKind() == Track::Wave) if (copyTrack->GetKind() == Track::Wave)
@ -4627,7 +4614,7 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action )
regions.at(i + 1).start - region.end); regions.at(i + 1).start - region.end);
} }
if( merged ) if( merged )
msClipboard->Add( merged.release() ); msClipboard->Add( std::move(merged) );
} }
} }

View File

@ -26,6 +26,7 @@ and TimeTrack.
#include "TimeTrack.h" #include "TimeTrack.h"
#include "WaveTrack.h" #include "WaveTrack.h"
#include "NoteTrack.h" #include "NoteTrack.h"
#include "LabelTrack.h"
#include "Project.h" #include "Project.h"
#include "DirManager.h" #include "DirManager.h"
@ -135,7 +136,7 @@ Track::~Track()
TrackNodePointer Track::GetNode() const TrackNodePointer Track::GetNode() const
{ {
wxASSERT(mList == NULL || this == *mNode); wxASSERT(mList == NULL || this == mNode->get());
return mNode; return mNode;
} }
@ -266,14 +267,14 @@ Track *Track::GetLink() const
auto next = mNode; auto next = mNode;
++next; ++next;
if (!mList->isNull(next)) { if (!mList->isNull(next)) {
return *next; return next->get();
} }
} }
if (mList->hasPrev(mNode)) { if (mList->hasPrev(mNode)) {
auto prev = mNode; auto prev = mNode;
--prev; --prev;
auto track = *prev; auto track = prev->get();
if (track && track->GetLinked()) { if (track && track->GetLinked()) {
return track; return track;
} }
@ -366,7 +367,7 @@ Track *TrackListIterator::StartWith(Track * val)
return nullptr; return nullptr;
cur = val->GetNode(); cur = val->GetNode();
return *cur; return cur->get();
} }
Track *TrackListIterator::First(TrackList * val) Track *TrackListIterator::First(TrackList * val)
@ -382,7 +383,7 @@ Track *TrackListIterator::First(TrackList * val)
cur = l->begin(); cur = l->begin();
if (!l->isNull(cur)) { if (!l->isNull(cur)) {
return *cur; return cur->get();
} }
return NULL; return NULL;
@ -407,7 +408,7 @@ Track *TrackListIterator::Last(bool skiplinked)
(*cur)->GetLink()) (*cur)->GetLink())
--cur; --cur;
return *cur; return cur->get();
} }
Track *TrackListIterator::Next(bool skipLinked) Track *TrackListIterator::Next(bool skipLinked)
@ -437,7 +438,7 @@ Track *TrackListIterator::Next(bool skipLinked)
#endif #endif
if (!l->isNull(cur)) { if (!l->isNull(cur)) {
return *cur; return cur->get();
} }
return NULL; return NULL;
@ -462,7 +463,7 @@ Track *TrackListIterator::Prev(bool skiplinked)
cur = prev; cur = prev;
} }
return *cur; return cur->get();
} }
Track *TrackListIterator::RemoveCurrent() Track *TrackListIterator::RemoveCurrent()
@ -470,14 +471,14 @@ Track *TrackListIterator::RemoveCurrent()
if (!l || l->isNull(cur)) if (!l || l->isNull(cur))
return nullptr; return nullptr;
cur = l->Remove(*cur); cur = l->Remove(cur->get());
#ifdef DEBUG_TLI // if we are debugging this bit #ifdef DEBUG_TLI // if we are debugging this bit
wxASSERT_MSG((!cur || (*l).Contains((*cur).t)), wxT("cur invalid after deletion of track.")); // check that cur is in the list wxASSERT_MSG((!cur || (*l).Contains((*cur).t)), wxT("cur invalid after deletion of track.")); // check that cur is in the list
#endif #endif
if (!l->isNull(cur)) { if (!l->isNull(cur)) {
return *cur; return cur->get();
} }
return NULL; return NULL;
@ -687,7 +688,7 @@ Track *SyncLockedTracksIterator::Last(bool skiplinked)
if (!l || l->isNull(cur)) if (!l || l->isNull(cur))
return NULL; return NULL;
Track *t = *cur; Track *t = cur->get();
while (l->GetNext(t)) { while (l->GetNext(t)) {
// Check if this is the last track in the sync-locked group. // Check if this is the last track in the sync-locked group.
@ -723,7 +724,7 @@ TrackList::TrackList()
} }
TrackList::TrackList(const TrackList &that) TrackList::TrackList(const TrackList &that)
: ListOfTracks() : ListOfTracks{}
{ {
DoAssign(that); DoAssign(that);
} }
@ -755,7 +756,7 @@ void TrackList::DoAssign(const TrackList &that)
{ {
TrackListConstIterator it(&that); TrackListConstIterator it(&that);
for (const Track *track = it.First(); track; track = it.Next()) for (const Track *track = it.First(); track; track = it.Next())
Add(track->Duplicate().release()); Add(track->Duplicate());
} }
void TrackList::Swap(TrackList &that) void TrackList::Swap(TrackList &that)
@ -812,14 +813,14 @@ void TrackList::RecalcPositions(TrackNodePointer node)
if (hasPrev(node)) { if (hasPrev(node)) {
auto prev = node; auto prev = node;
--prev; --prev;
t = *prev; t = prev->get();
i = t->GetIndex() + 1; i = t->GetIndex() + 1;
y = t->GetY() + t->GetHeight(); y = t->GetY() + t->GetHeight();
} }
const auto theEnd = end(); const auto theEnd = end();
for (auto n = node; n != theEnd; ++n) { for (auto n = node; n != theEnd; ++n) {
t = *n; t = n->get();
t->SetIndex(i++); t->SetIndex(i++);
t->SetY(y); t->SetY(y);
y += t->GetHeight(); y += t->GetHeight();
@ -831,7 +832,7 @@ void TrackList::UpdatedEvent(TrackNodePointer node)
{ {
wxCommandEvent e(EVT_TRACKLIST_UPDATED); wxCommandEvent e(EVT_TRACKLIST_UPDATED);
if (!isNull(node)) { if (!isNull(node)) {
e.SetClientData(*node); e.SetClientData(node->get());
} }
else { else {
e.SetClientData(NULL); e.SetClientData(NULL);
@ -843,7 +844,7 @@ void TrackList::ResizedEvent(TrackNodePointer node)
{ {
if (!isNull(node)) { if (!isNull(node)) {
wxCommandEvent e(EVT_TRACKLIST_RESIZED); wxCommandEvent e(EVT_TRACKLIST_RESIZED);
e.SetClientData(*node); e.SetClientData(node->get());
ProcessEvent(e); ProcessEvent(e);
} }
} }
@ -851,9 +852,10 @@ void TrackList::ResizedEvent(TrackNodePointer node)
void TrackList::Permute(const std::vector<TrackNodePointer> &permutation) void TrackList::Permute(const std::vector<TrackNodePointer> &permutation)
{ {
for (const auto iter : permutation) { for (const auto iter : permutation) {
Track *track = *iter; value_type track = std::move(*iter);
erase(iter); erase(iter);
track->SetOwner(this, insert(end(), track)); Track *pTrack = track.get();
pTrack->SetOwner(this, insert(end(), std::move(track)));
} }
auto n = begin(); auto n = begin();
RecalcPositions(n); RecalcPositions(n);
@ -861,7 +863,45 @@ void TrackList::Permute(const std::vector<TrackNodePointer> &permutation)
ResizedEvent(n); ResizedEvent(n);
} }
void TrackList::Add(Track * t) template<typename TrackKind>
Track *TrackList::Add(std::unique_ptr<TrackKind> &&t)
{
Track *pTrack;
push_back(value_type(pTrack = t.release()));
auto n = end();
--n;
pTrack->SetOwner(this, n);
RecalcPositions(n);
UpdatedEvent(n);
return back().get();
}
// Make instantiations for the linker to find
template Track *TrackList::Add<TimeTrack>(std::unique_ptr<TimeTrack> &&);
template Track *TrackList::Add<NoteTrack>(std::unique_ptr<NoteTrack> &&);
template Track *TrackList::Add<WaveTrack>(std::unique_ptr<WaveTrack> &&);
template Track *TrackList::Add<LabelTrack>(std::unique_ptr<LabelTrack> &&);
template<typename TrackKind>
Track *TrackList::AddToHead(std::unique_ptr<TrackKind> &&t)
{
Track *pTrack;
push_front(value_type(pTrack = t.release()));
auto n = begin();
pTrack->SetOwner(this, n);
RecalcPositions(n);
UpdatedEvent(n);
ResizedEvent(n);
return front().get();
}
// Make instantiations for the linker to find
template Track *TrackList::AddToHead<TimeTrack>(std::unique_ptr<TimeTrack> &&);
#ifdef __AUDACITY_OLD_STD__
template<typename TrackKind>
Track *TrackList::Add(std::shared_ptr<TrackKind> &&t)
{ {
push_back(t); push_back(t);
auto n = end(); auto n = end();
@ -869,34 +909,30 @@ void TrackList::Add(Track * t)
t->SetOwner(this, n); t->SetOwner(this, n);
RecalcPositions(n); RecalcPositions(n);
UpdatedEvent(n); UpdatedEvent(n);
return back().get();
} }
void TrackList::AddToHead(Track * t) // Make instantiations for the linker to find
{ template Track *TrackList::Add<Track>(std::shared_ptr<Track> &&);
push_front(t); template Track *TrackList::Add<WaveTrack>(std::shared_ptr<WaveTrack> &&);
auto n = begin();
t->SetOwner(this, n);
RecalcPositions(n);
UpdatedEvent(n);
ResizedEvent(n);
}
void TrackList::Replace(Track * t, Track * with, bool deletetrack) #endif
auto TrackList::Replace(Track * t, value_type &&with) -> value_type
{ {
value_type holder;
if (t && with) { if (t && with) {
auto node = t->GetNode(); auto node = t->GetNode();
holder = std::move(*node);
if (deletetrack) Track *pTrack = with.get();
delete t; *node = std::move(with);
else pTrack->SetOwner(this, node);
t->SetOwner(NULL, TrackNodePointer{});
*node = with;
with->SetOwner(this, node);
RecalcPositions(node); RecalcPositions(node);
UpdatedEvent(node); UpdatedEvent(node);
ResizedEvent(node); ResizedEvent(node);
} }
return holder;
} }
TrackNodePointer TrackList::Remove(Track *t) TrackNodePointer TrackList::Remove(Track *t)
@ -905,8 +941,6 @@ TrackNodePointer TrackList::Remove(Track *t)
if (t) { if (t) {
auto node = t->GetNode(); auto node = t->GetNode();
delete t;
if (!isNull(node)) { if (!isNull(node)) {
result = erase(node); result = erase(node);
if (!isNull(result)) { if (!isNull(result)) {
@ -922,8 +956,6 @@ TrackNodePointer TrackList::Remove(Track *t)
void TrackList::Clear() void TrackList::Clear()
{ {
for (auto track : *this)
delete track;
ListOfTracks::clear(); ListOfTracks::clear();
UpdatedEvent(end()); UpdatedEvent(end());
} }
@ -974,7 +1006,7 @@ Track *TrackList::GetNext(Track * t, bool linked) const
} }
if (!isNull(node)) { if (!isNull(node)) {
return *node; return node->get();
} }
} }
} }
@ -1002,7 +1034,7 @@ Track *TrackList::GetPrev(Track * t, bool linked) const
!(*node)->GetLinked() && (*node)->GetLink()) !(*node)->GetLinked() && (*node)->GetLink())
--node; --node;
return *node; return node->get();
} }
} }
} }
@ -1074,31 +1106,32 @@ void TrackList::SwapNodes(TrackNodePointer s1, TrackNodePointer s2)
} }
// Remove tracks // Remove tracks
Track *save11 = *s1, *save12{}; value_type save11 = std::move(*s1), save12{};
s1 = erase(s1); s1 = erase(s1);
if (linked1) { if (linked1) {
wxASSERT(s1 != s2); wxASSERT(s1 != s2);
save12 = *s1, s1 = erase(s1); save12 = std::move(*s1), s1 = erase(s1);
} }
const bool same = (s1 == s2); const bool same = (s1 == s2);
Track *save21 = *s2, *save22{}; value_type save21 = std::move(*s2), save22{};
s2 = erase(s2); s2 = erase(s2);
if (linked2) if (linked2)
save22 = *s2, s2 = erase(s2); save22 = std::move(*s2), s2 = erase(s2);
if (same) if (same)
// We invalidated s1! // We invalidated s1!
s1 = s2; s1 = s2;
// Reinsert them // Reinsert them
Track *pTrack;
if (save22) if (save22)
save22->SetOwner(this, s1 = insert(s1, save22)); pTrack = save22.get(), pTrack->SetOwner(this, s1 = insert(s1, std::move(save22)));
save21->SetOwner(this, s1 = insert(s1, save21)); pTrack = save21.get(), pTrack->SetOwner(this, s1 = insert(s1, std::move(save21)));
if (save12) if (save12)
save12->SetOwner(this, s2 = insert(s2, save12)); pTrack = save12.get(), pTrack->SetOwner(this, s2 = insert(s2, std::move(save12)));
save11->SetOwner(this, s2 = insert(s2, save11)); pTrack = save11.get(), pTrack->SetOwner(this, s2 = insert(s2, std::move(save11)));
// Now correct the Index in the tracks, and other things // Now correct the Index in the tracks, and other things
RecalcPositions(s1); RecalcPositions(s1);
@ -1134,7 +1167,9 @@ bool TrackList::MoveDown(Track * t)
bool TrackList::Contains(Track * t) const bool TrackList::Contains(Track * t) const
{ {
return std::find(begin(), end(), t) != end(); return std::find_if(begin(), end(),
[=](const value_type &track) { return t == track.get(); }
) != end();
} }
bool TrackList::IsEmpty() const bool TrackList::IsEmpty() const
@ -1156,12 +1191,12 @@ int TrackList::GetCount() const
TimeTrack *TrackList::GetTimeTrack() TimeTrack *TrackList::GetTimeTrack()
{ {
auto iter = std::find_if(begin(), end(), auto iter = std::find_if(begin(), end(),
[] (Track *t) { return t->GetKind() == Track::Time; } [] (const value_type &t) { return t->GetKind() == Track::Time; }
); );
if (iter == end()) if (iter == end())
return nullptr; return nullptr;
else else
return static_cast<TimeTrack*>(*iter); return static_cast<TimeTrack*>(iter->get());
} }
const TimeTrack *TrackList::GetTimeTrack() const const TimeTrack *TrackList::GetTimeTrack() const
@ -1238,11 +1273,11 @@ namespace {
Array waveTrackArray; Array waveTrackArray;
for (; p != end; ++p) { for (; p != end; ++p) {
auto track = *p; const auto &track = *p;
if (track->GetKind() == Track::Wave && if (track->GetKind() == Track::Wave &&
(includeMuted || !track->GetMute()) && (includeMuted || !track->GetMute()) &&
(track->GetSelected() || !selectionOnly)) { (track->GetSelected() || !selectionOnly)) {
waveTrackArray.push_back(static_cast<WaveTrack*>(track)); waveTrackArray.push_back(static_cast<WaveTrack*>(track.get()));
} }
} }
@ -1268,7 +1303,7 @@ NoteTrackArray TrackList::GetNoteTrackArray(bool selectionOnly)
for(const auto &track : *this) { for(const auto &track : *this) {
if (track->GetKind() == Track::Note && if (track->GetKind() == Track::Note &&
(track->GetSelected() || !selectionOnly)) { (track->GetSelected() || !selectionOnly)) {
noteTrackArray.Add(static_cast<NoteTrack*>(track)); noteTrackArray.Add(static_cast<NoteTrack*>(track.get()));
} }
} }

View File

@ -67,7 +67,8 @@ WX_DEFINE_USER_EXPORTED_ARRAY(NoteTrack*, NoteTrackArray, class AUDACITY_DLL_API
class TrackList; class TrackList;
using ListOfTracks = std::list<Track*>; using ListOfTracks = std::list<movable_ptr<Track>>;
using TrackNodePointer = ListOfTracks::iterator; using TrackNodePointer = ListOfTracks::iterator;
class AUDACITY_DLL_API Track /* not final */ : public XMLTagHandler class AUDACITY_DLL_API Track /* not final */ : public XMLTagHandler
@ -257,7 +258,7 @@ class AUDACITY_DLL_API TrackListIterator /* not final */
virtual Track *Prev(bool skiplinked = false); virtual Track *Prev(bool skiplinked = false);
virtual Track *Last(bool skiplinked = false); virtual Track *Last(bool skiplinked = false);
Track *RemoveCurrent(); // returns next Track *RemoveCurrent(); // deletes track, returns next
protected: protected:
friend TrackList; friend TrackList;
@ -398,7 +399,7 @@ DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_RESIZED, -1);
// track that was added. // track that was added.
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_UPDATED, -1); DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_UPDATED, -1);
class AUDACITY_DLL_API TrackList final : public wxEvtHandler, public ListOfTracks class TrackList final : public wxEvtHandler, public ListOfTracks
{ {
public: public:
// Create an empty TrackList // Create an empty TrackList
@ -427,11 +428,18 @@ class AUDACITY_DLL_API TrackList final : public wxEvtHandler, public ListOfTrack
void Permute(const std::vector<TrackNodePointer> &permutation); void Permute(const std::vector<TrackNodePointer> &permutation);
/// Add this Track or all children of this TrackList. /// Add this Track or all children of this TrackList.
void Add(Track * t); template<typename TrackKind>
void AddToHead(Track * t); Track *Add(std::unique_ptr<TrackKind> &&t);
template<typename TrackKind>
Track *AddToHead(std::unique_ptr<TrackKind> &&t);
/// Replace first track with second track #ifdef __AUDACITY_OLD_STD__
void Replace(Track * t, Track * with, bool deletetrack = false); template<typename TrackKind>
Track *Add(std::shared_ptr<TrackKind> &&t);
#endif
/// Replace first track with second track, give back a holder
value_type Replace(Track * t, value_type &&with);
/// Remove this Track or all children of this TrackList. /// Remove this Track or all children of this TrackList.
/// Return an iterator to what followed the removed track. /// Return an iterator to what followed the removed track.

View File

@ -214,7 +214,7 @@ void UndoManager::ModifyState(const TrackList * l,
TrackListConstIterator iter(l); TrackListConstIterator iter(l);
const Track *t = iter.First(); const Track *t = iter.First();
while (t) { while (t) {
tracksCopy->Add(t->Duplicate().release()); tracksCopy->Add(t->Duplicate());
t = iter.Next(); t = iter.Next();
} }
@ -259,7 +259,7 @@ void UndoManager::PushState(const TrackList * l,
TrackListConstIterator iter(l); TrackListConstIterator iter(l);
const Track *t = iter.First(); const Track *t = iter.First();
while (t) { while (t) {
tracksCopy->Add(t->Duplicate().release()); tracksCopy->Add(t->Duplicate());
t = iter.Next(); t = iter.Next();
} }

View File

@ -2104,19 +2104,18 @@ void Effect::CopyInputTracks(int trackType)
if (aTrack->GetSelected() || if (aTrack->GetSelected() ||
(trackType == Track::All && aTrack->IsSyncLockSelected())) (trackType == Track::All && aTrack->IsSyncLockSelected()))
{ {
Track *o = aTrack->Duplicate().release(); Track *o = mOutputTracks->Add(aTrack->Duplicate());
mOutputTracks->Add(o);
mIMap.Add(aTrack); mIMap.Add(aTrack);
mOMap.Add(o); mOMap.Add(o);
} }
} }
} }
void Effect::AddToOutputTracks(Track *t) Track *Effect::AddToOutputTracks(std::unique_ptr<Track> &&t)
{ {
mOutputTracks->Add(t);
mIMap.Add(NULL); mIMap.Add(NULL);
mOMap.Add(t); mOMap.Add(t.get());
return mOutputTracks->Add(std::move(t));
} }
Effect::AddedAnalysisTrack::AddedAnalysisTrack(Effect *pEffect, const wxString &name) Effect::AddedAnalysisTrack::AddedAnalysisTrack(Effect *pEffect, const wxString &name)
@ -2126,7 +2125,7 @@ Effect::AddedAnalysisTrack::AddedAnalysisTrack(Effect *pEffect, const wxString &
mpTrack = pTrack.get(); mpTrack = pTrack.get();
if (!name.empty()) if (!name.empty())
pTrack->SetName(name); pTrack->SetName(name);
pEffect->mTracks->Add(pTrack.release()); pEffect->mTracks->Add(std::move(pTrack));
} }
Effect::AddedAnalysisTrack::AddedAnalysisTrack(AddedAnalysisTrack &&that) Effect::AddedAnalysisTrack::AddedAnalysisTrack(AddedAnalysisTrack &&that)
@ -2158,7 +2157,6 @@ auto Effect::AddAnalysisTrack(const wxString &name) -> std::shared_ptr<AddedAnal
Effect::ModifiedAnalysisTrack::ModifiedAnalysisTrack Effect::ModifiedAnalysisTrack::ModifiedAnalysisTrack
(Effect *pEffect, const LabelTrack *pOrigTrack, const wxString &name) (Effect *pEffect, const LabelTrack *pOrigTrack, const wxString &name)
: mpEffect(pEffect) : mpEffect(pEffect)
, mpOrigTrack(pOrigTrack)
{ {
// copy LabelTrack here, so it can be undone on cancel // copy LabelTrack here, so it can be undone on cancel
auto newTrack = pOrigTrack->Copy(pOrigTrack->GetStartTime(), pOrigTrack->GetEndTime()); auto newTrack = pOrigTrack->Copy(pOrigTrack->GetStartTime(), pOrigTrack->GetEndTime());
@ -2172,14 +2170,21 @@ Effect::ModifiedAnalysisTrack::ModifiedAnalysisTrack
// mpOrigTrack came from mTracks which we own but expose as const to subclasses // mpOrigTrack came from mTracks which we own but expose as const to subclasses
// So it's okay that we cast it back to const // So it's okay that we cast it back to const
pEffect->mTracks->Replace(const_cast<LabelTrack*>(mpOrigTrack), newTrack.release(), false); mpOrigTrack =
pEffect->mTracks->Replace(const_cast<LabelTrack*>(pOrigTrack),
#ifdef __AUDACITY_OLD_STD__
std::shared_ptr<Track>(newTrack.release())
#else
std::move(newTrack)
#endif
);
} }
Effect::ModifiedAnalysisTrack::ModifiedAnalysisTrack(ModifiedAnalysisTrack &&that) Effect::ModifiedAnalysisTrack::ModifiedAnalysisTrack(ModifiedAnalysisTrack &&that)
{ {
mpEffect = that.mpEffect; mpEffect = that.mpEffect;
mpTrack = that.mpTrack; mpTrack = that.mpTrack;
mpOrigTrack = that.mpOrigTrack; mpOrigTrack = std::move(that.mpOrigTrack);
that.Commit(); that.Commit();
} }
@ -2194,7 +2199,7 @@ Effect::ModifiedAnalysisTrack::~ModifiedAnalysisTrack()
// not committed -- DELETE the label track // not committed -- DELETE the label track
// mpOrigTrack came from mTracks which we own but expose as const to subclasses // mpOrigTrack came from mTracks which we own but expose as const to subclasses
// So it's okay that we cast it back to const // So it's okay that we cast it back to const
mpEffect->mTracks->Replace(mpTrack, const_cast<LabelTrack*>(mpOrigTrack), true); mpEffect->mTracks->Replace(mpTrack, std::move(mpOrigTrack));
} }
} }
@ -2228,10 +2233,10 @@ void Effect::ReplaceProcessedTracks(const bool bGoodResult)
size_t i = 0; size_t i = 0;
for (; iterOut != iterEnd; ++i) { for (; iterOut != iterEnd; ++i) {
Track *o = std::move(*iterOut); ListOfTracks::value_type o = std::move(*iterOut);
// If tracks were removed from mOutputTracks, then there will be // If tracks were removed from mOutputTracks, then there will be
// tracks in the map that must be removed from mTracks. // tracks in the map that must be removed from mTracks.
while (i < cnt && mOMap[i] != o) { while (i < cnt && mOMap[i] != o.get()) {
Track *t = (Track *) mIMap[i]; Track *t = (Track *) mIMap[i];
if (t) { if (t) {
mTracks->Remove(t); mTracks->Remove(t);
@ -2249,22 +2254,20 @@ void Effect::ReplaceProcessedTracks(const bool bGoodResult)
if (t == NULL) if (t == NULL)
{ {
// This track is a NEW addition to output tracks; add it to mTracks // This track is a NEW addition to output tracks; add it to mTracks
mTracks->Add(o); mTracks->Add(std::move(o));
} }
else else
{ {
// Replace mTracks entry with the NEW track // Replace mTracks entry with the NEW track
mTracks->Replace(t, o, false); WaveTrack *newTrack = static_cast<WaveTrack*>(o.get());
mTracks->Replace(t, std::move(o));
// Swap the wavecache track the ondemand task uses, since now the NEW // Swap the wavecache track the ondemand task uses, since now the NEW
// one will be kept in the project // one will be kept in the project
if (ODManager::IsInstanceCreated()) { if (ODManager::IsInstanceCreated()) {
ODManager::Instance()->ReplaceWaveTrack((WaveTrack *)t, ODManager::Instance()->ReplaceWaveTrack((WaveTrack *)t,
(WaveTrack *)o); newTrack);
} }
// No longer need the original track
delete t;
} }
} }
@ -2579,12 +2582,12 @@ void Effect::Preview(bool dryOnly)
mixLeft->InsertSilence(0.0, mT0); mixLeft->InsertSilence(0.0, mT0);
mixLeft->SetSelected(true); mixLeft->SetSelected(true);
mixLeft->SetDisplay(WaveTrack::NoDisplay); mixLeft->SetDisplay(WaveTrack::NoDisplay);
mTracks->Add(mixLeft.release()); mTracks->Add(std::move(mixLeft));
if (mixRight) { if (mixRight) {
mixRight->Offset(-mixRight->GetStartTime()); mixRight->Offset(-mixRight->GetStartTime());
mixRight->InsertSilence(0.0, mT0); mixRight->InsertSilence(0.0, mT0);
mixRight->SetSelected(true); mixRight->SetSelected(true);
mTracks->Add(mixRight.release()); mTracks->Add(std::move(mixRight));
} }
} }
else { else {
@ -2597,7 +2600,7 @@ void Effect::Preview(bool dryOnly)
dest->InsertSilence(0.0, mT0); dest->InsertSilence(0.0, mT0);
dest->SetSelected(src->GetSelected()); dest->SetSelected(src->GetSelected());
static_cast<WaveTrack*>(dest.get())->SetDisplay(WaveTrack::NoDisplay); static_cast<WaveTrack*>(dest.get())->SetDisplay(WaveTrack::NoDisplay);
mTracks->Add(dest.release()); mTracks->Add(std::move(dest));
} }
src = (WaveTrack *) iter.Next(); src = (WaveTrack *) iter.Next();
} }

View File

@ -16,6 +16,7 @@
#include "../MemoryX.h" #include "../MemoryX.h"
#include <set> #include <set>
#include "../MemoryX.h"
#include <wx/bmpbuttn.h> #include <wx/bmpbuttn.h>
#include <wx/dynarray.h> #include <wx/dynarray.h>
#include <wx/intl.h> #include <wx/intl.h>
@ -37,6 +38,8 @@ class wxWindow;
#include "../Internat.h" #include "../Internat.h"
#include "../widgets/ProgressDialog.h" #include "../widgets/ProgressDialog.h"
#include "../Track.h"
class ShuttleGui; class ShuttleGui;
#define BUILTIN_EFFECT_PREFIX wxT("Built-in Effect: ") #define BUILTIN_EFFECT_PREFIX wxT("Built-in Effect: ")
@ -409,7 +412,7 @@ protected:
private: private:
Effect *mpEffect{}; Effect *mpEffect{};
LabelTrack *mpTrack{}; LabelTrack *mpTrack{};
const LabelTrack *mpOrigTrack{}; movable_ptr<Track> mpOrigTrack{};
}; };
// Set name to given value if that is not empty, else use default name // Set name to given value if that is not empty, else use default name
@ -422,7 +425,7 @@ protected:
void ReplaceProcessedTracks(const bool bGoodResult); void ReplaceProcessedTracks(const bool bGoodResult);
// Use this to append a NEW output track. // Use this to append a NEW output track.
void AddToOutputTracks(Track *t); Track *AddToOutputTracks(std::unique_ptr<Track> &&t);
// //
// protected data // protected data

View File

@ -1120,8 +1120,7 @@ bool NyquistEffect::ProcessOne()
} }
if (!ltrack) { if (!ltrack) {
ltrack = mFactory->NewLabelTrack().release(); ltrack = static_cast<LabelTrack*>(AddToOutputTracks(mFactory->NewLabelTrack()));
AddToOutputTracks((Track *)ltrack);
} }
for (l = 0; l < numLabels; l++) { for (l = 0; l < numLabels; l++) {

View File

@ -920,7 +920,7 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt)
wxString baseTrackName = recordingNameCustom? defaultRecordingTrackName : defaultTrackName; wxString baseTrackName = recordingNameCustom? defaultRecordingTrackName : defaultTrackName;
for (int c = 0; c < recordingChannels; c++) { for (int c = 0; c < recordingChannels; c++) {
WaveTrack *newTrack = p->GetTrackFactory()->NewWaveTrack().release(); auto newTrack = p->GetTrackFactory()->NewWaveTrack();
newTrack->SetOffset(t0); newTrack->SetOffset(t0);
wxString nameSuffix = wxString(wxT("")); wxString nameSuffix = wxString(wxT(""));
@ -972,14 +972,12 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt)
newTrack->SetChannel( Track::MonoChannel ); newTrack->SetChannel( Track::MonoChannel );
} }
newRecordingTracks.push_back(newTrack); // Let the list hold the track, and keep a pointer to it
newRecordingTracks.push_back(
static_cast<WaveTrack*>(
trackList->Add(
std::move(newTrack))));
} }
// msmeyer: StartStream calls a callback which triggers auto-save, so
// we add the tracks where recording is done into now. We remove them
// later if starting the stream fails
for (unsigned int i = 0; i < newRecordingTracks.size(); i++)
trackList->Add(newRecordingTracks[i]);
} }
//Automated Input Level Adjustment Initialization //Automated Input Level Adjustment Initialization
@ -1096,18 +1094,19 @@ void ControlToolBar::SetupCutPreviewTracks(double WXUNUSED(playStart), double cu
if (track1) if (track1)
{ {
// Duplicate and change tracks // Duplicate and change tracks
track1 = track1->Duplicate().release(); auto new1 = track1->Duplicate();
track1->Clear(cutStart, cutEnd); new1->Clear(cutStart, cutEnd);
decltype(new1) new2{};
if (track2) if (track2)
{ {
track2 = track2->Duplicate().release(); new2 = track2->Duplicate();
track2->Clear(cutStart, cutEnd); new2->Clear(cutStart, cutEnd);
} }
mCutPreviewTracks = new TrackList(); mCutPreviewTracks = new TrackList();
mCutPreviewTracks->Add(track1); mCutPreviewTracks->Add(std::move(new1));
if (track2) if (track2)
mCutPreviewTracks->Add(track2); mCutPreviewTracks->Add(std::move(new2));
} }
} }
} }