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:
parent
7d1ea7b82e
commit
a6ca36cdab
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 ®ion, 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
|
||||||
|
@ -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) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
149
src/Track.cpp
149
src/Track.cpp
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
22
src/Track.h
22
src/Track.h
@ -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.
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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++) {
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user