Audacity 3.2.0
EffectOutputTracks.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 EffectOutputTracks.cpp
6
7 Paul Licameli split from Effect.cpp and EffectBase.cpp
8
9**********************************************************************/
10#include "EffectOutputTracks.h"
11#include "BasicUI.h"
12#include "SyncLock.h"
13#include "UserException.h"
14#include "WaveTrack.h"
15#include "TimeStretching.h"
16
17// Effect application counter
19
21 TrackList& tracks, EffectType effectType,
22 std::optional<TimeInterval> effectTimeInterval, bool allSyncLockSelected,
23 bool stretchSyncLocked)
24 : mTracks { tracks }
25 , mEffectType { effectType }
26{
27 assert(
28 !effectTimeInterval.has_value() ||
29 effectTimeInterval->first <= effectTimeInterval->second);
30 // Reset map
31 mIMap.clear();
32 mOMap.clear();
34
35 auto trackRange = mTracks.Any() +
36 [&] (const Track *pTrack) {
37 return allSyncLockSelected
39 : dynamic_cast<const WaveTrack*>(pTrack) && pTrack->GetSelected();
40 };
41
42 for (auto aTrack : trackRange) {
43 auto pTrack = aTrack->Duplicate();
44 mIMap.push_back(aTrack);
45 mOMap.push_back(pTrack.get());
46 mOutputTracks->Add(pTrack);
47 }
48
49 if (
50 effectTimeInterval.has_value() &&
51 effectTimeInterval->second > effectTimeInterval->first)
52 {
54 [&](const ProgressReporter& parent)
55 {
56 const auto tracksToUnstretch =
57 (stretchSyncLocked ? mOutputTracks->Any<WaveTrack>() :
58 mOutputTracks->Selected<WaveTrack>()) +
59 [&](const WaveTrack* pTrack)
60 {
62 *pTrack, effectTimeInterval->first,
63 effectTimeInterval->second);
64 };
66 tracksToUnstretch.begin(), tracksToUnstretch.end(),
67 [&](WaveTrack* aTrack, const ProgressReporter& child) {
68 aTrack->ApplyPitchAndSpeed(effectTimeInterval, child);
69 },
70 parent);
71 });
72 }
73
74 // Invariant is established
75 assert(mIMap.size() == mOutputTracks->Size());
76 assert(mIMap.size() == mOMap.size());
77}
78
80
81Track *EffectOutputTracks::AddToOutputTracks(const std::shared_ptr<Track> &t)
82{
83 mIMap.push_back(nullptr);
84 mOMap.push_back(t.get());
85 auto result = mOutputTracks->Add(t);
86 // Invariant is maintained
87 assert(mIMap.size() == mOutputTracks->Size());
88 assert(mIMap.size() == mOMap.size());
89 return result;
90}
91
93{
94 const auto it = std::find(mOMap.begin(), mOMap.end(), &outTrack);
95 if (it == mOMap.end())
96 return nullptr;
97 const auto index = it - mOMap.begin();
98 return mIMap[index];
99}
100
101// Replace tracks with successfully processed mOutputTracks copies.
102// Else clear and delete mOutputTracks copies.
104{
105 if (!mOutputTracks) {
106 // Already committed, violating precondition. Maybe wrong intent...
107 assert(false);
108 // ... but harmless
109 return;
110 }
111
112 size_t cnt = mOMap.size();
113 size_t i = 0;
114
115 while (!mOutputTracks->empty()) {
116 const auto pOutputTrack = *mOutputTracks->begin();
117
118 // If tracks were removed from mOutputTracks, then there will be
119 // tracks in the map that must be removed from mTracks.
120 while (i < cnt && mOMap[i] != pOutputTrack) {
121 const auto t = mIMap[i];
122 // Class invariant justifies the assertion
123 assert(t);
124 ++i;
125 mTracks.Remove(*t);
126 }
127
128 // The output track, still in the list, must also have been placed in
129 // the map
130 assert(i < cnt);
131
132 // Find the input track it corresponds to
133 if (!mIMap[i])
134 // This track was an addition to output tracks; add it to mTracks
135 mTracks.AppendOne(std::move(*mOutputTracks));
136 else if (
138 // Replace mTracks entry with the new track
139 mTracks.ReplaceOne(*mIMap[i], std::move(*mOutputTracks));
140 else
141 // This output track was just a placeholder for pre-processing. Discard
142 // it.
143 mOutputTracks->Remove(*pOutputTrack);
144 ++i;
145 }
146
147 // If tracks were removed from mOutputTracks, then there may be tracks
148 // left at the end of the map that must be removed from mTracks.
149 while (i < cnt) {
150 const auto t = mIMap[i];
151 // Class invariant justifies the assertion
152 assert(t);
153 ++i;
154 mTracks.Remove(*t);
155 }
156
157 // Reset map
158 mIMap.clear();
159 mOMap.clear();
160
161 // Make sure we processed everything
162 assert(mOutputTracks->empty());
163
164 // The output list is no longer needed
165 mOutputTracks.reset();
166 ++nEffectsDone;
167}
Toolkit-neutral facade for basic user interface services.
EffectType
@ EffectTypeAnalyze
@ EffectTypeNone
const auto tracks
std::function< void(double)> ProgressReporter
Definition: Track.h:48
An AudacityException with no visible message.
const Track * GetMatchingInput(const Track &outTrack) const
Gets the matching input track for the given output track if it finds its match, else nullptr.
Track * AddToOutputTracks(const std::shared_ptr< Track > &t)
Use this to add an output track, not corresponding to an input.
const EffectType mEffectType
EffectOutputTracks(TrackList &tracks, EffectType effectType, std::optional< TimeInterval > effectTimeInterval, bool allSyncLockSelected=false, bool stretchSyncLocked=false)
std::vector< Track * > mOMap
std::vector< Track * > mIMap
std::shared_ptr< TrackList > mOutputTracks
void Commit()
Replace input tracks with temporaries only on commit.
static bool IsSelectedOrSyncLockSelected(const Track &track)
Definition: SyncLock.cpp:104
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:110
bool GetSelected() const
Selectedness is always the same for all channels of a group.
Definition: Track.cpp:78
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:850
static TrackListHolder Create(AudacityProject *pOwner)
Definition: Track.cpp:330
void AppendOne(TrackList &&list)
Remove first track (if any) from list and put it at the end of this
Definition: Track.cpp:881
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:950
Track::Holder ReplaceOne(Track &t, TrackList &&with)
Definition: Track.cpp:560
Track::Holder Remove(Track &track)
Remove a track and return it.
Definition: Track.cpp:584
AudacityProject * GetOwner()
Definition: Track.h:887
A Track that contains audio waveform data.
Definition: WaveTrack.h:203
void SplitProgress(ItType first, ItType last, FnType action, ProgressReporter parent)
Helper for the update of a task's progress bar when this task is made of a range's subtasks.
Definition: BasicUI.h:331
WAVE_TRACK_API void WithClipRenderingProgress(std::function< void(const ProgressReporter &)> action, TranslatableString title=defaultStretchRenderingTitle)
WAVE_TRACK_API bool HasPitchOrSpeed(const WaveTrack &track, double t0, double t1)