📄 changepitch.cpp
字号:
// from/to frequency controls if (m_pTextCtrl_FromFrequency) { wxString str; if (m_FromFrequency > 0.0) str.Printf(wxT("%.3f"), m_FromFrequency); else str = wxT(""); m_pTextCtrl_FromFrequency->SetValue(str); } this->Update_Text_ToFrequency(); // percent change controls this->Update_Text_PercentChange(); this->Update_Slider_PercentChange(); m_bLoopDetect = false; return true;}bool ChangePitchDialog::TransferDataFromWindow(){ double newDouble; wxString str; // from/to pitch controls if (m_pChoice_FromPitch) m_FromPitchIndex = m_pChoice_FromPitch->GetSelection(); if (m_pRadioBox_PitchUpDown) m_bWantPitchDown = (m_pRadioBox_PitchUpDown->GetSelection() == 1); if (m_pChoice_ToPitch) m_ToPitchIndex = m_pChoice_ToPitch->GetSelection(); // semitones change control if (m_pTextCtrl_SemitonesChange) { str = m_pTextCtrl_SemitonesChange->GetValue(); str.ToDouble(&newDouble); m_SemitonesChange = newDouble; } // from/to frequency controls if (m_pTextCtrl_FromFrequency) { str = m_pTextCtrl_FromFrequency->GetValue(); str.ToDouble(&newDouble); m_FromFrequency = newDouble; } if (m_pTextCtrl_ToFrequency) { str = m_pTextCtrl_ToFrequency->GetValue(); str.ToDouble(&newDouble); m_ToFrequency = newDouble; } // percent change controls if (m_pTextCtrl_PercentChange) { str = m_pTextCtrl_PercentChange->GetValue(); str.ToDouble(&newDouble); m_PercentChange = newDouble; } // Ignore Slider_PercentChange because TextCtrl_PercentChange // always tracks it & is more precise (decimal points). return true;}// calculationsvoid ChangePitchDialog::Calc_ToFrequency(){ m_ToFrequency = (m_FromFrequency * (100.0 + m_PercentChange)) / 100.0;}void ChangePitchDialog::Calc_ToPitchIndex(){ m_ToPitchIndex = (m_FromPitchIndex + (int)(m_SemitonesChange + // Round in the right direction. ((m_bWantPitchDown ? -1.0 : 1.0) * 0.5))) % 12;}void ChangePitchDialog::Calc_SemitonesChange_fromPitches(){ int sign = m_bWantPitchDown ? -1 : 1; m_SemitonesChange = sign * (((sign * (m_ToPitchIndex - m_FromPitchIndex)) + 12) % 12); }void ChangePitchDialog::Calc_SemitonesChange_fromPercentChange(){ // Use m_PercentChange rather than m_FromFrequency & m_ToFrequency, because // they start out uninitialized, but m_PercentChange is always valid. m_SemitonesChange = (12.0 * log((100.0 + m_PercentChange) / 100.0)) / log(2.0);}void ChangePitchDialog::Calc_PercentChange(){ m_PercentChange = 100.0 * (pow(2.0, (m_SemitonesChange / 12.0)) - 1.0);}// handlersvoid ChangePitchDialog::OnChoice_FromPitch(wxCommandEvent & event){ if (m_bLoopDetect) return; if (m_pChoice_FromPitch) { m_FromPitchIndex = m_pChoice_FromPitch->GetSelection(); this->Calc_ToPitchIndex(); m_bLoopDetect = true; this->Update_Choice_ToPitch(); m_bLoopDetect = false; }}void ChangePitchDialog::OnRadioBox_PitchUpDown(wxCommandEvent & event){ if (m_bLoopDetect) return; if (m_pRadioBox_PitchUpDown) { m_bWantPitchDown = (m_pRadioBox_PitchUpDown->GetSelection() == 1); this->Calc_SemitonesChange_fromPitches(); this->Calc_PercentChange(); // Call *after* m_SemitonesChange is updated. this->Calc_ToFrequency(); // Call *after* m_PercentChange is updated. m_bLoopDetect = true; this->Update_Text_SemitonesChange(); this->Update_Text_ToFrequency(); this->Update_Text_PercentChange(); this->Update_Slider_PercentChange(); m_bLoopDetect = false; }}void ChangePitchDialog::OnChoice_ToPitch(wxCommandEvent & event){ if (m_bLoopDetect) return; if (m_pChoice_ToPitch) { m_ToPitchIndex = m_pChoice_ToPitch->GetSelection(); this->Calc_SemitonesChange_fromPitches(); this->Calc_PercentChange(); // Call *after* m_SemitonesChange is updated. this->Calc_ToFrequency(); // Call *after* m_PercentChange is updated. m_bLoopDetect = true; this->Update_Text_SemitonesChange(); this->Update_Text_ToFrequency(); this->Update_Text_PercentChange(); this->Update_Slider_PercentChange(); m_bLoopDetect = false; }}void ChangePitchDialog::OnText_SemitonesChange(wxCommandEvent & event){ if (m_bLoopDetect) return; if (m_pTextCtrl_SemitonesChange) { wxString str = m_pTextCtrl_SemitonesChange->GetValue(); double newValue = 0; str.ToDouble(&newValue); m_SemitonesChange = newValue; this->Calc_PercentChange(); this->Calc_ToFrequency(); // Call *after* m_PercentChange is updated. m_bWantPitchDown = (m_ToFrequency < m_FromFrequency); this->Calc_ToPitchIndex(); // Call *after* m_bWantPitchDown is updated. m_bLoopDetect = true; this->Update_RadioBox_PitchUpDown(); if (m_pTextCtrl_SemitonesChange->IsModified()) // See note at implementation of Update_RadioBox_PitchUpDown. m_pTextCtrl_SemitonesChange->SetFocus(); this->Update_Choice_ToPitch(); this->Update_Text_ToFrequency(); this->Update_Text_PercentChange(); this->Update_Slider_PercentChange(); m_bLoopDetect = false; }}void ChangePitchDialog::OnText_FromFrequency(wxCommandEvent & event){ if (m_bLoopDetect) return; if (m_pTextCtrl_FromFrequency) { wxString str = m_pTextCtrl_FromFrequency->GetValue(); double newDouble; str.ToDouble(&newDouble); m_FromFrequency = newDouble; m_FromPitchIndex = PitchIndex(Freq2Pitch(m_FromFrequency)); this->Calc_ToFrequency(); m_bWantPitchDown = (m_ToFrequency < m_FromFrequency); this->Calc_ToPitchIndex(); // Call *after* m_bWantPitchDown is updated. m_bLoopDetect = true; this->Update_RadioBox_PitchUpDown(); if (m_pTextCtrl_FromFrequency->IsModified()) // See note at implementation of Update_RadioBox_PitchUpDown. m_pTextCtrl_FromFrequency->SetFocus(); this->Update_Choice_ToPitch(); this->Update_Text_ToFrequency(); m_bLoopDetect = false; }}void ChangePitchDialog::OnText_ToFrequency(wxCommandEvent & event){ if (m_bLoopDetect) return; if (m_pTextCtrl_ToFrequency) { wxString str = m_pTextCtrl_ToFrequency->GetValue(); double newDouble; str.ToDouble(&newDouble); m_ToFrequency = newDouble; m_PercentChange = (((double)(m_ToFrequency) * 100.0) / (double)(m_FromFrequency)) - 100.0; this->Calc_SemitonesChange_fromPercentChange(); this->Calc_ToPitchIndex(); // Call *after* m_SemitonesChange is updated. m_bWantPitchDown = (m_ToFrequency < m_FromFrequency); m_bLoopDetect = true; this->Update_RadioBox_PitchUpDown(); if (m_pTextCtrl_ToFrequency->IsModified()) // See note at implementation of Update_RadioBox_PitchUpDown. m_pTextCtrl_ToFrequency->SetFocus(); this->Update_Choice_ToPitch(); this->Update_Text_SemitonesChange(); this->Update_Text_PercentChange(); this->Update_Slider_PercentChange(); m_bLoopDetect = false; }}void ChangePitchDialog::OnText_PercentChange(wxCommandEvent & event){ if (m_bLoopDetect) return; if (m_pTextCtrl_PercentChange) { wxString str = m_pTextCtrl_PercentChange->GetValue(); double newValue = 0; str.ToDouble(&newValue); m_PercentChange = newValue; this->Calc_SemitonesChange_fromPercentChange(); this->Calc_ToPitchIndex(); // Call *after* m_SemitonesChange is updated. this->Calc_ToFrequency(); m_bWantPitchDown = (m_ToFrequency < m_FromFrequency); m_bLoopDetect = true; this->Update_RadioBox_PitchUpDown(); if (m_pTextCtrl_PercentChange->IsModified()) // See note at implementation of Update_RadioBox_PitchUpDown. m_pTextCtrl_PercentChange->SetFocus(); this->Update_Choice_ToPitch(); this->Update_Text_SemitonesChange(); this->Update_Text_ToFrequency(); this->Update_Slider_PercentChange(); m_bLoopDetect = false; //v Probably better to override wxTextValidator to disallow negative values. // See comment in ChangePitchDialog::ChangePitchDialog. this->FindWindow(wxID_OK)->Enable(m_PercentChange > -100.0); }}void ChangePitchDialog::OnSlider_PercentChange(wxCommandEvent & event){ if (m_bLoopDetect) return; if (m_pSlider_PercentChange) { 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, PERCENTCHANGE_SLIDER_WARP); this->Calc_SemitonesChange_fromPercentChange(); this->Calc_ToPitchIndex(); // Call *after* m_SemitonesChange is updated. this->Calc_ToFrequency(); m_bWantPitchDown = (m_ToFrequency < m_FromFrequency); m_bLoopDetect = true; this->Update_RadioBox_PitchUpDown(); this->Update_Choice_ToPitch(); this->Update_Text_SemitonesChange(); this->Update_Text_ToFrequency(); this->Update_Text_PercentChange(); m_bLoopDetect = false; }}void ChangePitchDialog::OnPreview(wxCommandEvent &event){ TransferDataFromWindow(); // Save & restore parameters around Preview, because we didn't do OK. double oldSemitonesChange = m_SemitonesChange; m_pEffect->m_SemitonesChange = m_SemitonesChange; m_pEffect->Preview(); m_pEffect->m_SemitonesChange = oldSemitonesChange;}void ChangePitchDialog::OnOk(wxCommandEvent & event){ TransferDataFromWindow(); if (Validate()) EndModal(true); else event.Skip();}void ChangePitchDialog::OnCancel(wxCommandEvent & event){ EndModal(false);}// helper fns// NOTE: wxWindows ref (C:\wxWindows_2.4.0\docs\htmlhelp) says // wxRadioBox::SetSelection "does not cause a // wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted", but it // calls SetFocus, which sure as heck DOES select the radio button.//// So, any wxTextCtrl handler that calls Update_RadioBox_PitchUpDown // needs to call wxTextCtrl::SetFocus afterward, to return the // focus to the wxTextCtrl so the user can keep typing.//// Also, it turns out the wxTextCtrl handlers are sometimes // called before the dialog is displayed, so those SetFocus calls // need to be conditionalized on wxTextCtrl::IsModified.void ChangePitchDialog::Update_RadioBox_PitchUpDown() { if (m_pRadioBox_PitchUpDown) m_pRadioBox_PitchUpDown->SetSelection((int)(m_bWantPitchDown));}void ChangePitchDialog::Update_Choice_ToPitch() { if (m_pChoice_ToPitch) m_pChoice_ToPitch->SetSelection(m_ToPitchIndex);}void ChangePitchDialog::Update_Text_SemitonesChange(){ if (m_pTextCtrl_SemitonesChange) { wxString str; str.Printf(wxT("%.2f"), m_SemitonesChange); m_pTextCtrl_SemitonesChange->SetValue(str); }}void ChangePitchDialog::Update_Text_ToFrequency() { if (m_pTextCtrl_ToFrequency) { wxString str; if (m_ToFrequency > 0.0) str.Printf(wxT("%.3f"), m_ToFrequency); else str = wxT(""); m_pTextCtrl_ToFrequency->SetValue(str); }}void ChangePitchDialog::Update_Text_PercentChange(){ if (m_pTextCtrl_PercentChange) { wxString str; str.Printf(wxT("%.3f"), m_PercentChange); m_pTextCtrl_PercentChange->SetValue(str); }}void ChangePitchDialog::Update_Slider_PercentChange(){ if (m_pSlider_PercentChange) { double unwarped = m_PercentChange; if (unwarped > 0.0) // Un-warp values above zero to actually go up to PERCENTCHANGE_MAX. unwarped = pow(m_PercentChange, (1.0 / PERCENTCHANGE_SLIDER_WARP)); // Add 0.5 to unwarped so trunc -> round. m_pSlider_PercentChange->SetValue((int)(unwarped + 0.5)); }}#endif // USE_SOUNDTOUCH// Indentation settings for Vim and Emacs and unique identifier for Arch, a// version control system. Please do not modify past this point.//// Local Variables:// c-basic-offset: 3// indent-tabs-mode: nil// End://// vim: et sts=3 sw=3// arch-tag: 0b070f91-579c-4b57-bc29-82ceb6775355
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -