void EffectChangePitch::OnSpin_ToOctave(wxCommandEvent & WXUNUSED(evt)) { if (m_bLoopDetect) return; int nNewValue = m_pSpin_ToOctave->GetValue(); // Validation: Rather than set a range for octave numbers, enforce a range that // keeps m_dPercentChange above -99%, per Soundtouch constraints. if ((nNewValue + 3) < m_nFromOctave) { ::wxBell(); m_pSpin_ToOctave->SetValue(m_nFromOctave - 3); return; } m_nToOctave = nNewValue; m_ToFrequency = PitchToFreq(m_nToPitch, m_nToOctave); Calc_SemitonesChange_fromPitches(); Calc_PercentChange(); // Call *after* m_dSemitonesChange is updated. m_bLoopDetect = true; { Update_Text_SemitonesChange(); Update_Text_ToFrequency(); Update_Text_PercentChange(); Update_Slider_PercentChange(); } m_bLoopDetect = false; }
void EffectChangePitch::OnSlider_PercentChange(wxCommandEvent & WXUNUSED(evt)) { if (m_bLoopDetect) return; m_dPercentChange = (double)(m_pSlider_PercentChange->GetValue()); // Warp positive values to actually go up faster & further than negatives. if (m_dPercentChange > 0.0) m_dPercentChange = pow(m_dPercentChange, kSliderWarp); Calc_SemitonesChange_fromPercentChange(); Calc_ToPitch(); // Call *after* m_dSemitonesChange is updated. Calc_ToFrequency(); Calc_ToOctave(); // Call after Calc_ToFrequency(). m_bLoopDetect = true; { Update_Choice_ToPitch(); Update_Spin_ToOctave(); Update_Text_SemitonesChange(); Update_Text_ToFrequency(); Update_Text_PercentChange(); } m_bLoopDetect = false; }
void EffectChangePitch::OnText_SemitonesChange(wxCommandEvent & WXUNUSED(evt)) { if (m_bLoopDetect) return; if (!m_pTextCtrl_SemitonesChange->GetValidator()->TransferFromWindow()) { EnableApply(false); return; } Calc_PercentChange(); Calc_ToFrequency(); // Call *after* m_dPercentChange is updated. Calc_ToPitch(); Calc_ToOctave(); // Call after Calc_ToFrequency(). m_bLoopDetect = true; { Update_Choice_ToPitch(); Update_Spin_ToOctave(); Update_Text_ToFrequency(); Update_Text_PercentChange(); Update_Slider_PercentChange(); } m_bLoopDetect = false; // If m_dSemitonesChange is a big enough negative, we can go to or below 0 freq. // If m_dSemitonesChange is a big enough positive, we can go to 1.#INF (Windows) or inf (Linux). // But practically, these are best limits for Soundtouch. bool bIsGoodValue = (m_dSemitonesChange > -80.0) && (m_dSemitonesChange <= 60.0); EnableApply(bIsGoodValue); }
bool EffectChangePitch::TransferDataToWindow() { m_bLoopDetect = true; if (!mUIParent->TransferDataToWindow()) { return false; } Calc_SemitonesChange_fromPercentChange(); Calc_ToPitch(); // Call *after* m_dSemitonesChange is updated. Calc_ToFrequency(); Calc_ToOctave(); // Call after Calc_ToFrequency(). Update_Choice_FromPitch(); Update_Choice_ToPitch(); Update_Spin_FromOctave(); Update_Spin_ToOctave(); Update_Text_SemitonesChange(); Update_Text_FromFrequency(); Update_Text_ToFrequency(); Update_Text_PercentChange(); Update_Slider_PercentChange(); m_bLoopDetect = false; return true; }
bool EffectChangeSpeed::TransferDataToWindow() { mbLoopDetect = true; if (!mUIParent->TransferDataToWindow()) { return false; } if (mFromVinyl == kVinyl_NA) { mFromVinyl = kVinyl_33AndAThird; } Update_Text_PercentChange(); Update_Text_Multiplier(); Update_Slider_PercentChange(); Update_TimeCtrl_ToLength(); // Set from/to Vinyl controls - mFromVinyl must be set first. mpChoice_FromVinyl->SetSelection(mFromVinyl); // Then update to get correct mToVinyl. Update_Vinyl(); // Then update ToVinyl control. mpChoice_ToVinyl->SetSelection(mToVinyl); // Set From Length control. // Set the format first so we can get sample accuracy. mpFromLengthCtrl->SetFormatName(mFormat); mpFromLengthCtrl->SetValue(mFromLength); mbLoopDetect = false; return true; }
void EffectChangeSpeed::OnText_Multiplier(wxCommandEvent & WXUNUSED(evt)) { if (mbLoopDetect) return; mpTextCtrl_Multiplier->GetValidator()->TransferFromWindow(); m_PercentChange = 100 * (mMultiplier - 1); UpdateUI(); mbLoopDetect = true; Update_Text_PercentChange(); Update_Slider_PercentChange(); Update_Vinyl(); Update_TimeCtrl_ToLength(); mbLoopDetect = false; }
void EffectChangeTempo::OnSlider_PercentChange(wxCommandEvent & WXUNUSED(evt)) { if (m_bLoopDetect) return; m_PercentChange = (double)(m_pSlider_PercentChange->GetValue()); // Warp positive values to actually go up faster & further than negatives. if (m_PercentChange > 0.0) m_PercentChange = pow(m_PercentChange, kSliderWarp); m_bLoopDetect = true; Update_Text_PercentChange(); Update_Text_ToBPM(); Update_Text_ToLength(); m_bLoopDetect = false; }
void EffectChangeSpeed::OnSlider_PercentChange(wxCommandEvent & WXUNUSED(evt)) { if (mbLoopDetect) return; m_PercentChange = (double)(mpSlider_PercentChange->GetValue()); // Warp positive values to actually go up faster & further than negatives. if (m_PercentChange > 0.0) m_PercentChange = pow(m_PercentChange, kSliderWarp); UpdateUI(); mbLoopDetect = true; Update_Text_PercentChange(); Update_Text_Multiplier(); Update_Vinyl(); Update_TimeCtrl_ToLength(); mbLoopDetect = false; }
void EffectChangeSpeed::OnTimeCtrl_ToLength(wxCommandEvent & WXUNUSED(evt)) { if (mbLoopDetect) return; mToLength = mpToLengthCtrl->GetValue(); m_PercentChange = ((mFromLength * 100.0) / mToLength) - 100.0; UpdateUI(); mbLoopDetect = true; Update_Text_PercentChange(); Update_Text_Multiplier(); Update_Slider_PercentChange(); Update_Vinyl(); mbLoopDetect = false; }
void EffectChangePitch::OnChoice_ToPitch(wxCommandEvent & WXUNUSED(evt)) { if (m_bLoopDetect) return; m_nToPitch = m_pChoice_ToPitch->GetSelection(); Calc_SemitonesChange_fromPitches(); Calc_PercentChange(); // Call *after* m_dSemitonesChange is updated. Calc_ToFrequency(); // Call *after* m_dPercentChange is updated. m_bLoopDetect = true; { Update_Text_SemitonesChange(); Update_Text_ToFrequency(); Update_Text_PercentChange(); Update_Slider_PercentChange(); } m_bLoopDetect = false; }
void EffectChangeSpeed::OnTimeCtrl_ToLength(wxCommandEvent & WXUNUSED(evt)) { if (mbLoopDetect) return; mToLength = mpToLengthCtrl->GetValue(); // Division by (double) 0.0 is not an error and we want to show "infinite" in // text controls, so take care that we handle infinite values when they occur. m_PercentChange = ((mFromLength * 100.0) / mToLength) - 100.0; UpdateUI(); mbLoopDetect = true; Update_Text_PercentChange(); Update_Text_Multiplier(); Update_Slider_PercentChange(); Update_Vinyl(); mbLoopDetect = false; }
void EffectChangeTempo::OnText_ToLength(wxCommandEvent & WXUNUSED(evt)) { if (m_bLoopDetect) return; m_pTextCtrl_ToLength->GetValidator()->TransferFromWindow(); if (m_ToLength != 0.0) { m_PercentChange = ((m_FromLength * 100.0) / m_ToLength) - 100.0; } m_bLoopDetect = true; Update_Text_PercentChange(); Update_Slider_PercentChange(); Update_Text_ToBPM(); m_bLoopDetect = false; }
void EffectChangeSpeed::OnChoice_Vinyl(wxCommandEvent & WXUNUSED(evt)) { // Treat mpChoice_FromVinyl and mpChoice_ToVinyl as one control since we need // both to calculate Percent Change. mFromVinyl = mpChoice_FromVinyl->GetSelection(); mToVinyl = mpChoice_ToVinyl->GetSelection(); // Use this as the 'preferred' choice. if (mFromVinyl != kVinyl_NA) { SetPrivateConfig(GetCurrentSettingsGroup(), wxT("VinylChoice"), mFromVinyl); } // If mFromVinyl & mToVinyl are set, then there's a NEW percent change. if ((mFromVinyl != kVinyl_NA) && (mToVinyl != kVinyl_NA)) { double fromRPM; double toRPM; switch (mFromVinyl) { default: case kVinyl_33AndAThird: fromRPM = 33.0 + (1.0 / 3.0); break; case kVinyl_45: fromRPM = 45.0; break; case kVinyl_78: fromRPM = 78; break; } switch (mToVinyl) { default: case kVinyl_33AndAThird: toRPM = 33.0 + (1.0 / 3.0); break; case kVinyl_45: toRPM = 45.0; break; case kVinyl_78: toRPM = 78; break; } m_PercentChange = ((toRPM * 100.0) / fromRPM) - 100.0; UpdateUI(); mbLoopDetect = true; Update_Text_PercentChange(); Update_Text_Multiplier(); Update_Slider_PercentChange(); Update_TimeCtrl_ToLength(); } mbLoopDetect = false; }
void EffectChangeTempo::OnText_ToBPM(wxCommandEvent & WXUNUSED(evt)) { if (m_bLoopDetect) return; m_pTextCtrl_ToBPM->GetValidator()->TransferFromWindow(); m_bLoopDetect = true; // If FromBPM has already been set, then there's a NEW percent change. if (m_FromBPM != 0.0 && m_ToBPM != 0.0) { m_PercentChange = ((m_ToBPM * 100.0) / m_FromBPM) - 100.0; Update_Text_PercentChange(); Update_Slider_PercentChange(); Update_Text_ToLength(); } m_bLoopDetect = false; }
void EffectChangePitch::OnText_ToFrequency(wxCommandEvent & WXUNUSED(evt)) { if (m_bLoopDetect) return; // Empty string causes unpredictable results with ToDouble() and later calculations. // Non-positive frequency makes no sense, but user might still be editing, // so it's not an error, but we do not want to update the values/controls. if (!m_pTextCtrl_ToFrequency->GetValidator()->TransferFromWindow()) { EnableApply(false); return; } m_dPercentChange = ((m_ToFrequency * 100.0) / m_FromFrequency) - 100.0; Calc_ToOctave(); // Call after Calc_ToFrequency(). Calc_SemitonesChange_fromPercentChange(); Calc_ToPitch(); // Call *after* m_dSemitonesChange is updated. m_bLoopDetect = true; { Update_Choice_ToPitch(); Update_Spin_ToOctave(); Update_Text_SemitonesChange(); Update_Text_PercentChange(); Update_Slider_PercentChange(); } m_bLoopDetect = false; // Success. Make sure OK and Preview are disabled if percent change is out of bounds. // Can happen while editing. // If the value is good, might also need to re-enable because of above clause. bool bIsGoodValue = (m_dPercentChange > MIN_Percentage) && (m_dPercentChange <= MAX_Percentage); EnableApply(bIsGoodValue); }