Audacity 3.2.0
Repeat.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 Repeat.cpp
6
7 Dominic Mazzoni
8 Vaughan Johnson
9
10*******************************************************************//****************************************************************//*******************************************************************/
21#include "Repeat.h"
22#include "EffectEditor.h"
23#include "EffectOutputTracks.h"
24
25#include <math.h>
26
27#include <wx/stattext.h>
28
29#include "../LabelTrack.h"
30#include "ShuttleGui.h"
31#include "SyncLock.h"
32#include "WaveTrack.h"
33#include "../widgets/NumericTextCtrl.h"
34#include "../widgets/valnum.h"
35
36#include "LoadEffects.h"
37
39{
41 Count
42 > parameters;
43 return parameters;
44}
45
47{ XO("Repeat") };
48
50
51BEGIN_EVENT_TABLE(EffectRepeat, wxEvtHandler)
52 EVT_TEXT(wxID_ANY, EffectRepeat::OnRepeatTextChange)
54
56{
57 Parameters().Reset(*this);
58 SetLinearEffectFlag(true);
59}
60
62{
63}
64
65// ComponentInterface implementation
66
68{
69 return Symbol;
70}
71
73{
74 return XO("Repeats the selection the specified number of times");
75}
76
78{
79 return L"Repeat";
80}
81
82// EffectDefinitionInterface implementation
83
85{
86 return EffectTypeProcess;
87}
88
89// Effect implementation
90
92{
93 // Set up mOutputTracks.
94 // This effect needs all for sync-lock grouping.
95 EffectOutputTracks outputs { *mTracks, GetType(), { { mT0, mT1 } }, true };
96
97 int nTrack = 0;
98 bool bGoodResult = true;
99 double maxDestLen = 0.0; // used to change selection to generated bit
100
101 outputs.Get().Any().VisitWhile(bGoodResult,
102 [&](LabelTrack &track) {
104 {
105 if (!track.Repeat(mT0, mT1, repeatCount))
106 bGoodResult = false;
107 }
108 },
109 [&](auto &&fallthrough){ return [&](WaveTrack &track) {
110 if (!track.GetSelected())
111 return fallthrough(); // Fall through to next lambda
112 auto start = track.TimeToLongSamples(mT0);
113 auto end = track.TimeToLongSamples(mT1);
114 auto len = end - start;
115 const double tLen = track.LongSamplesToTime(len);
116 const double tc = mT0 + tLen;
117
118 if (len <= 0)
119 return;
120
121 auto tempList = track.Copy(mT0, mT1);
122 const auto firstTemp = *tempList->Any<const WaveTrack>().begin();
123
124
125
126 auto t0 = tc;
127 for (size_t j = 0; j < repeatCount; ++j) {
128 if (TrackProgress(nTrack, j / repeatCount)) {
129 // TrackProgress returns true on Cancel.
130 bGoodResult = false;
131 return;
132 }
133 track.Paste(t0, *firstTemp);
134 t0 += tLen;
135 }
136 if (t0 > maxDestLen)
137 maxDestLen = t0;
138
139 const auto compareIntervals = [](const auto& a, const auto& b) {
140 return a->Start() < b->Start();
141 };
142
143 const auto eps = 0.5 / track.GetRate();
144 auto sortedIntervals = std::vector(
145 track.Intervals().begin(),
146 track.Intervals().end()
147 );
148 auto sourceIntervals = std::vector(
149 firstTemp->Intervals().begin(),
150 firstTemp->Intervals().end()
151 );
152 std::sort(sortedIntervals.begin(), sortedIntervals.end(), compareIntervals);
153 std::sort(sourceIntervals.begin(), sourceIntervals.end(), compareIntervals);
154 for (auto it = sortedIntervals.begin(); it != sortedIntervals.end(); ++it)
155 {
156 const auto& interval = *it;
157 //Find first pasted interval
158 if (std::abs((*it)->GetPlayStartTime() - tc) > eps)
159 continue;
160
161 //Fix pasted clips names
162 for(int j = 0; j < repeatCount; ++j)
163 {
164 for (const auto& src : sourceIntervals)
165 {
166 if(it == sortedIntervals.end())
167 break;
168 (*it++)->SetName(src->GetName());
169 }
170 }
171 break;
172 }
173 nTrack++;
174 }; },
175 [&](Track &t)
176 {
178 t.SyncLockAdjust(mT1, mT1 + (mT1 - mT0) * repeatCount);
179 }
180 );
181
182 if (bGoodResult)
183 {
184 // Select the NEW bits + original bit
185 mT1 = maxDestLen;
186 }
187
188 if (bGoodResult)
189 outputs.Commit();
190 return bGoodResult;
191}
192
193std::unique_ptr<EffectEditor> EffectRepeat::PopulateOrExchange(
195 const EffectOutputs *)
196{
197 mUIParent = S.GetParent();
198 S.StartHorizontalLay(wxCENTER, false);
199 {
200 mRepeatCount = S.Validator<IntegerValidator<int>>(
201 &repeatCount, NumValidatorStyle::DEFAULT,
202 Count.min, 2147483647 / mProjectRate )
203 .AddTextBox(XXO("&Number of repeats to add:"), L"", 12);
204 }
205 S.EndHorizontalLay();
206
207 S.StartMultiColumn(1, wxCENTER);
208 {
209 mCurrentTime = S.AddVariableText(
210 XO("Current selection length: dd:hh:mm:ss"));
211 mTotalTime = S.AddVariableText(XO("New selection length: dd:hh:mm:ss"));
212 }
213 S.EndMultiColumn();
214 return nullptr;
215}
216
218{
219 mRepeatCount->ChangeValue(wxString::Format(wxT("%d"), repeatCount));
220
222
223 return true;
224}
225
227{
228 if (!mUIParent->Validate())
229 {
230 return false;
231 }
232
233 long l;
234
235 mRepeatCount->GetValue().ToLong(&l);
236
237 repeatCount = (int) l;
238
239 return true;
240}
241
243{
244 long l;
245 wxString str;
246 mRepeatCount->GetValue().ToLong(&l);
247
251 mT1 - mT0);
252
253 str = wxString::Format( _("Current selection length: %s"), nc.GetString() );
254
255 mCurrentTime->SetLabel(str);
256 mCurrentTime->SetName(str); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
257
258 if (l > 0) {
260 repeatCount = l;
261
262 nc.SetValue((mT1 - mT0) * (repeatCount + 1));
263 str = wxString::Format( _("New selection length: %s"), nc.GetString() );
264 }
265 else {
266 str = _("Warning: No repeats.");
268 }
269 mTotalTime->SetLabel(str);
270 mTotalTime->SetName(str); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
271}
272
273void EffectRepeat::OnRepeatTextChange(wxCommandEvent & WXUNUSED(evt))
274{
276}
277
279{
280 return false;
281}
wxT("CloseDown"))
END_EVENT_TABLE()
#define str(a)
EffectType
@ EffectTypeProcess
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define _(s)
Definition: Internat.h:73
const NumericConverterType & NumericConverterType_TIME()
#define S(N)
Definition: ToChars.cpp:64
Generates EffectParameterMethods overrides from variadic template arguments.
IteratorRange< IntervalIterator< IntervalType > > Intervals()
Get range of intervals with mutative access.
Definition: Channel.h:269
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
double mT1
Definition: EffectBase.h:116
double mProjectRate
Definition: EffectBase.h:112
std::shared_ptr< TrackList > mTracks
Definition: EffectBase.h:109
double mT0
Definition: EffectBase.h:115
static bool EnableApply(wxWindow *parent, bool enable=true)
Enable or disable the Apply button of the dialog that contains parent.
virtual NumericFormatID GetSelectionFormat()
Definition: Effect.cpp:187
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Definition: Effect.cpp:343
Performs effect computation.
Use this object to copy the input tracks to tentative outputTracks.
Hold values to send to effect output meters.
Interface for manipulations of an Effect's settings.
An Effect that repeats audio several times over.
Definition: Repeat.h:24
ComponentInterfaceSymbol GetSymbol() const override
Definition: Repeat.cpp:67
wxStaticText * mTotalTime
Definition: Repeat.h:66
wxWeakRef< wxWindow > mUIParent
Definition: Repeat.h:60
int repeatCount
Definition: Repeat.h:62
bool NeedsDither() const override
Definition: Repeat.cpp:278
bool Process(EffectInstance &instance, EffectSettings &settings) override
Definition: Repeat.cpp:91
static const ComponentInterfaceSymbol Symbol
Definition: Repeat.h:28
const EffectParameterMethods & Parameters() const override
Definition: Repeat.cpp:38
wxTextCtrl * mRepeatCount
Definition: Repeat.h:64
std::unique_ptr< EffectEditor > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) override
Add controls to effect panel; always succeeds.
Definition: Repeat.cpp:193
virtual ~EffectRepeat()
Definition: Repeat.cpp:61
bool TransferDataToWindow(const EffectSettings &settings) override
Definition: Repeat.cpp:217
TranslatableString GetDescription() const override
Definition: Repeat.cpp:72
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
Definition: Repeat.cpp:77
EffectRepeat()
Definition: Repeat.cpp:55
void DisplayNewTime()
Definition: Repeat.cpp:242
void OnRepeatTextChange(wxCommandEvent &evt)
Definition: Repeat.cpp:273
static constexpr EffectParameter Count
Definition: Repeat.h:71
bool TransferDataFromWindow(EffectSettings &settings) override
Definition: Repeat.cpp:226
EffectType GetType() const override
Type determines how it behaves.
Definition: Repeat.cpp:84
wxStaticText * mCurrentTime
Definition: Repeat.h:65
static FormatterContext SampleRateContext(double sampleRate)
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:87
bool Repeat(double t0, double t1, int n)
Definition: LabelTrack.cpp:829
TrackListHolder Copy(double t0, double t1, bool forClipboard=true) const override
Create new tracks and don't modify this track.
Definition: LabelTrack.cpp:731
void Paste(double t, const Track &src) override
Weak precondition allows overrides to replicate one channel into many.
Definition: LabelTrack.cpp:812
NumericConverter provides the advanced formatting control used in the selection bar of Audacity.
void SetValue(double newValue)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:630
static bool IsSelectedOrSyncLockSelected(const Track *pTrack)
Definition: SyncLock.cpp:112
static bool IsSyncLockSelected(const Track *pTrack)
Definition: SyncLock.cpp:82
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:122
bool GetSelected() const
Selectedness is always the same for all channels of a group.
Definition: Track.cpp:70
Holds a msgid for the translation catalog; may also bind format arguments.
A Track that contains audio waveform data.
Definition: WaveTrack.h:222
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150
BuiltinEffectsModule::Registration< EffectRepeat > reg
Definition: Repeat.cpp:49
const Type min
Minimum value.
Externalized state of a plug-in.