27#include <wx/checkbox.h>
31#include "../widgets/valnum.h"
45#undef PACKAGE_BUGREPORT
48#include "SoundTouch.h"
78{
XO(
"Change Tempo") };
85 EVT_TEXT(ID_FromBPM, EffectChangeTempo::OnText_FromBPM)
86 EVT_TEXT(ID_ToBPM, EffectChangeTempo::OnText_ToBPM)
87 EVT_TEXT(
ID_ToLength, EffectChangeTempo::OnText_ToLength)
94 Parameters().Reset(*
this);
100 m_bLoopDetect =
false;
102 SetLinearEffectFlag(
true);
105EffectChangeTempo::~EffectChangeTempo()
118 return XO(
"Changes the tempo of a selection without changing its pitch");
123 return L
"Change_Tempo";
133bool EffectChangeTempo::SupportsAutomation()
const
140double EffectChangeTempo::CalcPreviewInputLength(
143 return previewLength * (100.0 + m_PercentChange) / 100.0;
146bool EffectChangeTempo::CheckWhetherSkipEffect(
const EffectSettings &)
const
148 return (m_PercentChange == 0.0);
151bool EffectChangeTempo::Init()
155 m_FromLength = mT1 - mT0;
156 m_ToLength = (m_FromLength * 100.0) / (100.0 + m_PercentChange);
163 bool success =
false;
168 double tempoRatio = 1.0 + m_PercentChange / 100.0;
173 success = Delegate(proxy,
settings);
178 auto initer = [&](soundtouch::SoundTouch *soundtouch)
180 soundtouch->setTempoChange(m_PercentChange);
182 double mT1Dashed = mT0 + (mT1 - mT0)/(m_PercentChange/100.0 + 1.0);
184 std::make_unique<LinearTimeWarper>(mT0, mT0, mT1, mT1Dashed ) };
185 success = EffectSoundTouch::ProcessWithTimeWarper(initer, warper,
false);
189 mT1 = mT0 + (mT1 - mT0)/(m_PercentChange/100 + 1.);
194std::unique_ptr<EffectEditor> EffectChangeTempo::PopulateOrExchange(
198 mUIParent =
S.GetParent();
200 enum { precision = 2 };
202 S.StartVerticalLay(0);
205 S.StartMultiColumn(2, wxCENTER);
208 .Validator<FloatingPointValidator<double>>(
209 3, &m_PercentChange, NumValidatorStyle::THREE_TRAILING_ZEROES,
210 Percentage.min, Percentage.max )
211 .AddTextBox(
XXO(
"Percent C&hange:"), L
"", 12);
216 S.StartHorizontalLay(wxEXPAND);
219 .Name(
XO(
"Percent Change"))
220 .Style(wxSL_HORIZONTAL)
221 .AddSlider( {}, 0, (int)
kSliderMax, (
int)Percentage.min);
223 S.EndHorizontalLay();
225 S.StartStatic(
XO(
"Beats per minute"));
227 S.StartHorizontalLay(wxALIGN_CENTER);
229 m_pTextCtrl_FromBPM =
S.Id(ID_FromBPM)
231 .Name(
XO(
"Beats per minute, from"))
232 .
Validator<FloatingPointValidator<double>>(
234 NumValidatorStyle::THREE_TRAILING_ZEROES
235 | NumValidatorStyle::ZERO_AS_BLANK)
237 .AddTextBox(
XXC(
"&from",
"change tempo"),
wxT(
""), 12);
239 m_pTextCtrl_ToBPM =
S.Id(ID_ToBPM)
241 .Name(
XO(
"Beats per minute, to"))
242 .
Validator<FloatingPointValidator<double>>(
244 NumValidatorStyle::THREE_TRAILING_ZEROES
245 | NumValidatorStyle::ZERO_AS_BLANK)
247 .AddTextBox(
XXC(
"&to",
"change tempo"),
wxT(
""), 12);
249 S.EndHorizontalLay();
254 S.StartStatic(
XO(
"Length (seconds)"));
256 S.StartHorizontalLay(wxALIGN_CENTER);
258 m_pTextCtrl_FromLength =
S.Id(ID_FromLength)
261 .Validator<FloatingPointValidator<double>>(
262 precision, &m_FromLength,
263 NumValidatorStyle::TWO_TRAILING_ZEROES)
265 .AddTextBox(
XXC(
"from",
"change tempo"),
wxT(
""), 12);
267 .Validator<FloatingPointValidator<double>>(
268 2, &m_ToLength, NumValidatorStyle::TWO_TRAILING_ZEROES,
270 RoundValue( precision,
271 (m_FromLength * 100.0) / (100.0 + Percentage.max) ),
272 RoundValue( precision,
273 (m_FromLength * 100.0) / (100.0 + Percentage.min) ) )
275 .AddTextBox(
XXC(
"t&o",
"change tempo"),
wxT(
""), 12);
277 S.EndHorizontalLay();
282 S.StartMultiColumn(2);
284 mUseSBSMSCheckBox =
S.Validator<wxGenericValidator>(&mUseSBSMS)
285 .AddCheckBox(
XXO(
"&Use high quality stretching (slow)"),
297bool EffectChangeTempo::TransferDataToWindow(
const EffectSettings &)
300 m_FromLength = mT1 - mT0;
302 m_bLoopDetect =
true;
304 if (!mUIParent->TransferDataToWindow())
310 Update_Slider_PercentChange();
312 Update_Text_ToLength();
314 m_bLoopDetect =
false;
317 m_pTextCtrl_ToLength->SetName(
318 wxString::Format(
_(
"Length in seconds from %s, to"),
319 m_pTextCtrl_FromLength->GetValue() ) );
326 if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
336void EffectChangeTempo::OnText_PercentChange(wxCommandEvent & WXUNUSED(evt))
341 m_pTextCtrl_PercentChange->GetValidator()->TransferFromWindow();
343 m_bLoopDetect =
true;
344 Update_Slider_PercentChange();
346 Update_Text_ToLength();
347 m_bLoopDetect =
false;
350void EffectChangeTempo::OnSlider_PercentChange(wxCommandEvent & WXUNUSED(evt))
355 m_PercentChange = (double)(m_pSlider_PercentChange->GetValue());
357 if (m_PercentChange > 0.0)
358 m_PercentChange = pow(m_PercentChange,
kSliderWarp);
360 m_bLoopDetect =
true;
361 Update_Text_PercentChange();
363 Update_Text_ToLength();
364 m_bLoopDetect =
false;
367void EffectChangeTempo::OnText_FromBPM(wxCommandEvent & WXUNUSED(evt))
372 m_pTextCtrl_FromBPM->GetValidator()->TransferFromWindow();
374 m_bLoopDetect =
true;
378 m_bLoopDetect =
false;
381void EffectChangeTempo::OnText_ToBPM(wxCommandEvent & WXUNUSED(evt))
386 m_pTextCtrl_ToBPM->GetValidator()->TransferFromWindow();
388 m_bLoopDetect =
true;
391 if (m_FromBPM != 0.0 && m_ToBPM != 0.0)
393 m_PercentChange = ((m_ToBPM * 100.0) / m_FromBPM) - 100.0;
395 Update_Text_PercentChange();
396 Update_Slider_PercentChange();
398 Update_Text_ToLength();
401 m_bLoopDetect =
false;
404void EffectChangeTempo::OnText_ToLength(wxCommandEvent & WXUNUSED(evt))
409 m_pTextCtrl_ToLength->GetValidator()->TransferFromWindow();
411 if (m_ToLength != 0.0)
413 m_PercentChange = ((m_FromLength * 100.0) / m_ToLength) - 100.0;
416 m_bLoopDetect =
true;
418 Update_Text_PercentChange();
419 Update_Slider_PercentChange();
423 m_bLoopDetect =
false;
428void EffectChangeTempo::Update_Text_PercentChange()
430 m_pTextCtrl_PercentChange->GetValidator()->TransferToWindow();
433void EffectChangeTempo::Update_Slider_PercentChange()
435 double unwarped = m_PercentChange;
438 unwarped = pow(m_PercentChange, (1.0 /
kSliderWarp));
441 m_pSlider_PercentChange->SetValue((
int)(unwarped + 0.5));
444void EffectChangeTempo::Update_Text_ToBPM()
447 m_ToBPM = (((m_FromBPM * (100.0 + m_PercentChange)) / 100.0));
448 m_pTextCtrl_ToBPM->GetValidator()->TransferToWindow();
451void EffectChangeTempo::Update_Text_ToLength()
454 m_ToLength = (m_FromLength * 100.0) / (100.0 + m_PercentChange);
455 m_pTextCtrl_ToLength->GetValidator()->TransferToWindow();
static const double kSliderMax
static const double kSliderWarp
XXO("&Cut/Copy/Paste Toolbar")
Contains declarations for TimeWarper, IdentityTimeWarper, ShiftTimeWarper, LinearTimeWarper,...
static Settings & settings()
Generates EffectParameterMethods overrides from variadic template arguments.
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
An EffectSoundTouch provides speeding up or slowing down tempo without changing pitch.
Performs effect computation.
Hold values to send to effect output meters.
Interface for manipulations of an Effect's settings.
void setParameters(double rateStart, double rateEnd, double pitchStart, double pitchEnd, SlideType rateSlideType, SlideType pitchSlideType, bool bLinkRatePitch, bool bRateReferenceInput, bool bPitchReferenceInput)
TranslatableString mProxyEffectName
No change before the specified region; during the region, warp according to the given warper; after t...
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Holds a msgid for the translation catalog; may also bind format arguments.
A Validator is an object which checks whether a wxVariant satisfies a certain criterion....
BuiltinCommandsModule::Registration< CompareAudioCommand > reg
Externalized state of a plug-in.