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 "WaveClip.h"
33#include "WaveTrack.h"
34#include "../widgets/NumericTextCtrl.h"
35#include "../widgets/valnum.h"
36
37#include "LoadEffects.h"
38
40{
42 Count
43 > parameters;
44 return parameters;
45}
46
48{ XO("Repeat") };
49
51
52BEGIN_EVENT_TABLE(EffectRepeat, wxEvtHandler)
53 EVT_TEXT(wxID_ANY, EffectRepeat::OnRepeatTextChange)
55
57{
58 Parameters().Reset(*this);
59 SetLinearEffectFlag(true);
60}
61
63{
64}
65
66// ComponentInterface implementation
67
69{
70 return Symbol;
71}
72
74{
75 return XO("Repeats the selection the specified number of times");
76}
77
79{
80 return L"Repeat";
81}
82
83// EffectDefinitionInterface implementation
84
86{
87 return EffectTypeProcess;
88}
89
90// Effect implementation
91
93{
94 // Set up mOutputTracks.
95 // This effect needs all for sync-lock grouping.
96 EffectOutputTracks outputs { *mTracks, GetType(), { { mT0, mT1 } }, true };
97
98 int nTrack = 0;
99 bool bGoodResult = true;
100 double maxDestLen = 0.0; // used to change selection to generated bit
101
102 outputs.Get().Any().VisitWhile(bGoodResult,
103 [&](LabelTrack &track) {
105 {
106 if (!track.Repeat(mT0, mT1, repeatCount))
107 bGoodResult = false;
108 }
109 },
110 [&](auto &&fallthrough){ return [&](WaveTrack &track) {
111 if (!track.GetSelected())
112 return fallthrough(); // Fall through to next lambda
113 auto start = track.TimeToLongSamples(mT0);
114 auto end = track.TimeToLongSamples(mT1);
115 auto len = end - start;
116 const double tLen = track.LongSamplesToTime(len);
117 const double tc = mT0 + tLen;
118
119 if (len <= 0)
120 return;
121
122 auto firstTemp =
123 std::static_pointer_cast<WaveTrack>(track.Copy(mT0, mT1));
124
125 auto t0 = tc;
126 for (size_t j = 0; j < repeatCount; ++j) {
127 if (TrackProgress(nTrack, j / repeatCount)) {
128 // TrackProgress returns true on Cancel.
129 bGoodResult = false;
130 return;
131 }
132 track.Paste(t0, *firstTemp);
133 t0 += tLen;
134 }
135 if (t0 > maxDestLen)
136 maxDestLen = t0;
137
138 const auto compareIntervals = [](const auto& a, const auto& b) {
139 return a->Start() < b->Start();
140 };
141
142 const auto eps = 0.5 / track.GetRate();
143 auto sortedIntervals = std::vector(
144 track.Intervals().begin(),
145 track.Intervals().end()
146 );
147 auto sourceIntervals = std::vector(
148 firstTemp->Intervals().begin(),
149 firstTemp->Intervals().end()
150 );
151 std::sort(sortedIntervals.begin(), sortedIntervals.end(), compareIntervals);
152 std::sort(sourceIntervals.begin(), sourceIntervals.end(), compareIntervals);
153 for (auto it = sortedIntervals.begin(); it != sortedIntervals.end(); ++it)
154 {
155 const auto& interval = *it;
156 //Find first pasted interval
157 if (std::abs((*it)->GetPlayStartTime() - tc) > eps)
158 continue;
159
160 //Fix pasted clips names
161 for(int j = 0; j < repeatCount; ++j)
162 {
163 for (const auto& src : sourceIntervals)
164 {
165 if(it == sortedIntervals.end())
166 break;
167 (*it++)->SetName(src->GetName());
168 }
169 }
170 break;
171 }
172 nTrack++;
173 }; },
174 [&](Track &t)
175 {
177 t.SyncLockAdjust(mT1, mT1 + (mT1 - mT0) * repeatCount);
178 }
179 );
180
181 if (bGoodResult)
182 {
183 // Select the NEW bits + original bit
184 mT1 = maxDestLen;
185 }
186
187 if (bGoodResult)
188 outputs.Commit();
189 return bGoodResult;
190}
191
192std::unique_ptr<EffectEditor> EffectRepeat::PopulateOrExchange(
194 const EffectOutputs *)
195{
196 mUIParent = S.GetParent();
197 S.StartHorizontalLay(wxCENTER, false);
198 {
199 mRepeatCount = S.Validator<IntegerValidator<int>>(
200 &repeatCount, NumValidatorStyle::DEFAULT,
201 Count.min, 2147483647 / mProjectRate )
202 .AddTextBox(XXO("&Number of repeats to add:"), L"", 12);
203 }
204 S.EndHorizontalLay();
205
206 S.StartMultiColumn(1, wxCENTER);
207 {
208 mCurrentTime = S.AddVariableText(
209 XO("Current selection length: dd:hh:mm:ss"));
210 mTotalTime = S.AddVariableText(XO("New selection length: dd:hh:mm:ss"));
211 }
212 S.EndMultiColumn();
213 return nullptr;
214}
215
217{
218 mRepeatCount->ChangeValue(wxString::Format(wxT("%d"), repeatCount));
219
221
222 return true;
223}
224
226{
227 if (!mUIParent->Validate())
228 {
229 return false;
230 }
231
232 long l;
233
234 mRepeatCount->GetValue().ToLong(&l);
235
236 repeatCount = (int) l;
237
238 return true;
239}
240
242{
243 long l;
244 wxString str;
245 mRepeatCount->GetValue().ToLong(&l);
246
250 mT1 - mT0);
251
252 str = wxString::Format( _("Current selection length: %s"), nc.GetString() );
253
254 mCurrentTime->SetLabel(str);
255 mCurrentTime->SetName(str); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
256
257 if (l > 0) {
259 repeatCount = l;
260
261 nc.SetValue((mT1 - mT0) * (repeatCount + 1));
262 str = wxString::Format( _("New selection length: %s"), nc.GetString() );
263 }
264 else {
265 str = _("Warning: No repeats.");
267 }
268 mTotalTime->SetLabel(str);
269 mTotalTime->SetName(str); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
270}
271
272void EffectRepeat::OnRepeatTextChange(wxCommandEvent & WXUNUSED(evt))
273{
275}
276
278{
279 return false;
280}
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:248
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
double mT1
Definition: EffectBase.h:114
double mProjectRate
Definition: EffectBase.h:110
std::shared_ptr< TrackList > mTracks
Definition: EffectBase.h:107
double mT0
Definition: EffectBase.h:113
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:68
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:277
bool Process(EffectInstance &instance, EffectSettings &settings) override
Definition: Repeat.cpp:92
static const ComponentInterfaceSymbol Symbol
Definition: Repeat.h:28
const EffectParameterMethods & Parameters() const override
Definition: Repeat.cpp:39
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:192
virtual ~EffectRepeat()
Definition: Repeat.cpp:62
bool TransferDataToWindow(const EffectSettings &settings) override
Definition: Repeat.cpp:216
TranslatableString GetDescription() const override
Definition: Repeat.cpp:73
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
Definition: Repeat.cpp:78
EffectRepeat()
Definition: Repeat.cpp:56
void DisplayNewTime()
Definition: Repeat.cpp:241
void OnRepeatTextChange(wxCommandEvent &evt)
Definition: Repeat.cpp:272
static constexpr EffectParameter Count
Definition: Repeat.h:71
bool TransferDataFromWindow(EffectSettings &settings) override
Definition: Repeat.cpp:225
EffectType GetType() const override
Type determines how it behaves.
Definition: Repeat.cpp:85
wxStaticText * mCurrentTime
Definition: Repeat.h:65
static FormatterContext SampleRateContext(double sampleRate)
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:95
bool Repeat(double t0, double t1, int n)
Definition: LabelTrack.cpp:954
void Paste(double t, const Track &src) override
Weak precondition allows overrides to replicate one channel into many.
Definition: LabelTrack.cpp:937
Track::Holder Copy(double t0, double t1, bool forClipboard=true) const override
Create new tracks and don't modify this track.
Definition: LabelTrack.cpp:856
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:640
static bool IsSelectedOrSyncLockSelected(const Track &track)
Definition: SyncLock.cpp:104
static bool IsSyncLockSelected(const Track &track)
Definition: SyncLock.cpp:80
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
Holds a msgid for the translation catalog; may also bind format arguments.
A Track that contains audio waveform data.
Definition: WaveTrack.h:203
BuiltinEffectsModule::Registration< EffectRepeat > reg
Definition: Repeat.cpp:50
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
const Type min
Minimum value.
Externalized state of a plug-in.