30#include <wx/checkbox.h>
33#include <wx/spinctrl.h>
34#include <wx/valtext.h>
37#include "../widgets/valnum.h"
58BEGIN_EVENT_TABLE(EffectChangePitch, wxEvtHandler)
59 EVT_CHOICE(ID_FromPitch, EffectChangePitch::OnChoice_FromPitch)
60 EVT_TEXT(ID_FromOctave, EffectChangePitch::OnSpin_FromOctave)
61 EVT_CHOICE(ID_ToPitch, EffectChangePitch::OnChoice_ToPitch)
62 EVT_TEXT(ID_ToOctave, EffectChangePitch::OnSpin_ToOctave)
64 EVT_TEXT(ID_SemitonesChange, EffectChangePitch::OnText_SemitonesChange)
66 EVT_TEXT(ID_FromFrequency, EffectChangePitch::OnText_FromFrequency)
67 EVT_TEXT(ID_ToFrequency, EffectChangePitch::OnText_ToFrequency)
77 mUIParent =
S.GetParent();
81 for (
int ii = 0; ii < 12; ++ii)
86 S.StartVerticalLay(0);
91 XO(
"Estimated Start Pitch: %s%d (%.3f Hz)")
92 .
Format( pitch[m_nFromPitch], m_nFromOctave, m_FromFrequency) );
97 S.StartStatic(
XO(
"Pitch"));
99 S.StartMultiColumn(6, wxALIGN_CENTER);
101 m_pChoice_FromPitch =
S.Id(ID_FromPitch)
103 .Name(
XC(
"from",
"change pitch"))
104 .MinSize( { 80, -1 } )
106 .AddChoice(
XXC(
"&from",
"change pitch"), pitch);
108 m_pSpin_FromOctave =
S.Id(ID_FromOctave)
109 .Name(
XO(
"from Octave"))
110 .MinSize( { 50, -1 } )
111 .AddSpinCtrl( {}, m_nFromOctave, INT_MAX, INT_MIN);
113 m_pChoice_ToPitch =
S.Id(ID_ToPitch)
115 .Name(
XC(
"to",
"change pitch"))
116 .MinSize( { 80, -1 } )
118 .AddChoice(
XXC(
"&to",
"change pitch"), pitch);
120 m_pSpin_ToOctave =
S.Id(ID_ToOctave)
121 .Name(
XO(
"to Octave"))
122 .MinSize( { 50, -1 } )
123 .AddSpinCtrl( {}, m_nToOctave, INT_MAX, INT_MIN);
127 S.StartHorizontalLay(wxALIGN_CENTER);
129 m_pTextCtrl_SemitonesChange =
S.Id(ID_SemitonesChange)
130 .Name(
XO(
"Semitones (half-steps)"))
131 .Validator<FloatingPointValidator<double>>(
132 2, &m_dSemitonesChange,
133 NumValidatorStyle::TWO_TRAILING_ZEROES
135 .AddTextBox(
XXO(
"&Semitones (half-steps):"),
wxT(
""), 12);
137 S.EndHorizontalLay();
141 S.StartStatic(
XO(
"Frequency"));
143 S.StartMultiColumn(5, wxALIGN_CENTER);
145 m_pTextCtrl_FromFrequency =
S.Id(ID_FromFrequency)
146 .Name(
XO(
"from (Hz)"))
147 .
Validator<FloatingPointValidator<double>>(
149 NumValidatorStyle::THREE_TRAILING_ZEROES,
152 .AddTextBox(
XXO(
"f&rom"),
wxT(
""), 12);
154 m_pTextCtrl_ToFrequency =
S.Id(ID_ToFrequency)
156 .
Validator<FloatingPointValidator<double>>(
158 NumValidatorStyle::THREE_TRAILING_ZEROES,
161 .AddTextBox(
XXO(
"t&o"),
wxT(
""), 12);
163 S.AddUnits(
XO(
"Hz"));
167 S.StartHorizontalLay(wxALIGN_CENTER);
170 .Validator<FloatingPointValidator<double>>(
171 3, &m_dPercentChange,
172 NumValidatorStyle::THREE_TRAILING_ZEROES,
173 Percentage.min, Percentage.max )
174 .AddTextBox(
XXO(
"Percent C&hange:"), L
"", 12);
176 S.EndHorizontalLay();
178 S.StartHorizontalLay(wxEXPAND);
181 .Name(
XO(
"Percent Change"))
182 .Style(wxSL_HORIZONTAL)
183 .AddSlider( {}, 0, (int)
kSliderMax, (
int)Percentage.min);
185 S.EndHorizontalLay();
190 S.StartMultiColumn(2);
192 mUseSBSMSCheckBox =
S.Validator<wxGenericValidator>(&mUseSBSMS)
193 .AddCheckBox(
XXO(
"&Use high quality stretching (slow)"),
204bool EffectChangePitch::TransferDataToWindow(
const EffectSettings &)
206 m_bLoopDetect =
true;
208 if (!mUIParent->TransferDataToWindow())
213 Calc_SemitonesChange_fromPercentChange();
218 Update_Choice_FromPitch();
219 Update_Choice_ToPitch();
220 Update_Spin_FromOctave();
221 Update_Spin_ToOctave();
222 Update_Text_SemitonesChange();
223 Update_Text_FromFrequency();
224 Update_Text_ToFrequency();
225 Update_Text_PercentChange();
226 Update_Slider_PercentChange();
228 m_bLoopDetect =
false;
235 if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
241 m_nFromPitch = m_pChoice_FromPitch->GetSelection();
242 m_nFromOctave = m_pSpin_FromOctave->GetValue();
244 m_nToPitch = m_pChoice_ToPitch->GetSelection();
253void EffectChangePitch::OnChoice_FromPitch(wxCommandEvent & WXUNUSED(evt))
258 m_nFromPitch = m_pChoice_FromPitch->GetSelection();
259 m_FromFrequency =
PitchToFreq(m_nFromPitch, m_nFromOctave);
265 m_bLoopDetect =
true;
267 Update_Choice_ToPitch();
268 Update_Spin_ToOctave();
269 Update_Text_FromFrequency();
270 Update_Text_ToFrequency();
272 m_bLoopDetect =
false;
275void EffectChangePitch::OnSpin_FromOctave(wxCommandEvent & WXUNUSED(evt))
280 m_nFromOctave = m_pSpin_FromOctave->GetValue();
283 m_FromFrequency =
PitchToFreq(m_nFromPitch, m_nFromOctave);
288 m_bLoopDetect =
true;
290 Update_Spin_ToOctave();
291 Update_Text_FromFrequency();
292 Update_Text_ToFrequency();
294 m_bLoopDetect =
false;
297void EffectChangePitch::OnChoice_ToPitch(wxCommandEvent & WXUNUSED(evt))
302 m_nToPitch = m_pChoice_ToPitch->GetSelection();
304 Calc_SemitonesChange_fromPitches();
305 Calc_PercentChange();
308 m_bLoopDetect =
true;
310 Update_Text_SemitonesChange();
311 Update_Text_ToFrequency();
312 Update_Text_PercentChange();
313 Update_Slider_PercentChange();
315 m_bLoopDetect =
false;
318void EffectChangePitch::OnSpin_ToOctave(wxCommandEvent & WXUNUSED(evt))
323 int nNewValue = m_pSpin_ToOctave->GetValue();
326 if ((nNewValue + 3) < m_nFromOctave)
329 m_pSpin_ToOctave->SetValue(m_nFromOctave - 3);
332 m_nToOctave = nNewValue;
334 m_ToFrequency =
PitchToFreq(m_nToPitch, m_nToOctave);
336 Calc_SemitonesChange_fromPitches();
337 Calc_PercentChange();
339 m_bLoopDetect =
true;
341 Update_Text_SemitonesChange();
342 Update_Text_ToFrequency();
343 Update_Text_PercentChange();
344 Update_Slider_PercentChange();
346 m_bLoopDetect =
false;
349void EffectChangePitch::OnText_SemitonesChange(wxCommandEvent & WXUNUSED(evt))
354 if (!m_pTextCtrl_SemitonesChange->GetValidator()->TransferFromWindow())
360 Calc_PercentChange();
365 m_bLoopDetect =
true;
367 Update_Choice_ToPitch();
368 Update_Spin_ToOctave();
369 Update_Text_ToFrequency();
370 Update_Text_PercentChange();
371 Update_Slider_PercentChange();
373 m_bLoopDetect =
false;
378 bool bIsGoodValue = (m_dSemitonesChange > -80.0) && (m_dSemitonesChange <= 60.0);
382void EffectChangePitch::OnText_FromFrequency(wxCommandEvent & WXUNUSED(evt))
390 if (!m_pTextCtrl_FromFrequency->GetValidator()->TransferFromWindow())
403 m_bLoopDetect =
true;
405 Update_Choice_FromPitch();
406 Update_Spin_FromOctave();
407 Update_Choice_ToPitch();
408 Update_Spin_ToOctave();
409 Update_Text_ToFrequency();
411 m_bLoopDetect =
false;
417void EffectChangePitch::OnText_ToFrequency(wxCommandEvent & WXUNUSED(evt))
425 if (!m_pTextCtrl_ToFrequency->GetValidator()->TransferFromWindow())
431 m_dPercentChange = ((m_ToFrequency * 100.0) / m_FromFrequency) - 100.0;
434 Calc_SemitonesChange_fromPercentChange();
437 m_bLoopDetect =
true;
439 Update_Choice_ToPitch();
440 Update_Spin_ToOctave();
441 Update_Text_SemitonesChange();
442 Update_Text_PercentChange();
443 Update_Slider_PercentChange();
445 m_bLoopDetect =
false;
450 bool bIsGoodValue = (m_dPercentChange > Percentage.min) && (m_dPercentChange <= Percentage.max);
454void EffectChangePitch::OnText_PercentChange(wxCommandEvent & WXUNUSED(evt))
459 if (!m_pTextCtrl_PercentChange->GetValidator()->TransferFromWindow())
465 Calc_SemitonesChange_fromPercentChange();
470 m_bLoopDetect =
true;
472 Update_Choice_ToPitch();
473 Update_Spin_ToOctave();
474 Update_Text_SemitonesChange();
475 Update_Text_ToFrequency();
476 Update_Slider_PercentChange();
478 m_bLoopDetect =
false;
484void EffectChangePitch::OnSlider_PercentChange(wxCommandEvent & WXUNUSED(evt))
489 m_dPercentChange = (double)(m_pSlider_PercentChange->GetValue());
491 if (m_dPercentChange > 0.0)
492 m_dPercentChange = pow(m_dPercentChange,
kSliderWarp);
494 Calc_SemitonesChange_fromPercentChange();
499 m_bLoopDetect =
true;
501 Update_Choice_ToPitch();
502 Update_Spin_ToOctave();
503 Update_Text_SemitonesChange();
504 Update_Text_ToFrequency();
505 Update_Text_PercentChange();
507 m_bLoopDetect =
false;
512void EffectChangePitch::Update_Choice_FromPitch()
514 m_pChoice_FromPitch->SetSelection(m_nFromPitch);
517void EffectChangePitch::Update_Spin_FromOctave()
519 m_pSpin_FromOctave->SetValue(m_nFromOctave);
522void EffectChangePitch::Update_Choice_ToPitch()
524 m_pChoice_ToPitch->SetSelection(m_nToPitch);
527void EffectChangePitch::Update_Spin_ToOctave()
529 m_pSpin_ToOctave->SetValue(m_nToOctave);
532void EffectChangePitch::Update_Text_SemitonesChange()
534 m_pTextCtrl_SemitonesChange->GetValidator()->TransferToWindow();
537void EffectChangePitch::Update_Text_FromFrequency()
539 m_pTextCtrl_FromFrequency->GetValidator()->TransferToWindow();
542void EffectChangePitch::Update_Text_ToFrequency()
544 m_pTextCtrl_ToFrequency->GetValidator()->TransferToWindow();
547void EffectChangePitch::Update_Text_PercentChange()
549 m_pTextCtrl_PercentChange->GetValidator()->TransferToWindow();
552void EffectChangePitch::Update_Slider_PercentChange()
554 double unwarped = m_dPercentChange;
557 unwarped = pow(m_dPercentChange, (1.0 /
kSliderWarp));
560 m_pSlider_PercentChange->SetValue((
int)(unwarped + 0.5));
static const double kSliderMax
static const double kSliderWarp
XXO("&Cut/Copy/Paste Toolbar")
unsigned int PitchIndex(const double dMIDInote)
double PitchToFreq(const unsigned int nPitchIndex, const int nPitchOctave)
int PitchOctave(const double dMIDInote)
double FreqToMIDInote(const double freq)
TranslatableString PitchName(const double dMIDInote, const PitchNameChoice choice)
std::vector< TranslatableString > TranslatableStrings
static bool EnableApply(wxWindow *parent, bool enable=true)
Enable or disable the Apply button of the dialog that contains parent.
Performs effect computation.
Hold values to send to effect output meters.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
A Validator is an object which checks whether a wxVariant satisfies a certain criterion....
BuiltinCommandsModule::Registration< CompareAudioCommand > reg
Externalized state of a plug-in.