⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 changepitch.cpp

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************  Audacity: A Digital Audio Editor  ChangePitch.cpp  Vaughan Johnson, Dominic Mazzoni    Change Pitch effect provides raising or lowering   the pitch without changing the tempo.**********************************************************************/#include "../Audacity.h" // for USE_SOUNDTOUCH#if USE_SOUNDTOUCH#include "SoundTouch.h"#include "ChangePitch.h"#include "../PitchName.h"#include "../Spectrum.h"#include "../WaveTrack.h"#include <math.h>#include <wx/button.h>#include <wx/choice.h>#include <wx/radiobox.h>#include <wx/sizer.h>#include <wx/stattext.h>#include <wx/textctrl.h>#include <wx/valtext.h>//// EffectChangePitch//EffectChangePitch::EffectChangePitch(){	m_FromPitchIndex = -1;		// -1 => uninitialized	m_bWantPitchDown = false;	m_ToPitchIndex = -1;			// -1 => uninitialized	m_SemitonesChange = 0.0;   m_FromFrequency = 0.0;		// 0.0 => uninitialized   m_ToFrequency = 0.0;			// 0.0 => uninitialized	m_PercentChange = 0.0;}wxString EffectChangePitch::GetEffectDescription() {    // Note: This is useful only after change amount has been set.    return wxString::Format(_("Applied effect: %s %.2f semitones"),                            this->GetEffectName().c_str(), 									m_SemitonesChange); } bool EffectChangePitch::Init(){   mSoundTouch = NULL;	return true;}// DeduceFrequencies is Dominic's extremely cool trick (Vaughan sez so!) // to set deduce m_FromFrequency from the samples at the beginning of // the selection. Then we set some other params accordingly.void EffectChangePitch::DeduceFrequencies(){   // As a neat trick, attempt to get the frequency of the note at the   // beginning of the selection.   TrackListIterator iter(mWaveTracks);   WaveTrack *track = (WaveTrack *) iter.First();   if (track) {      const int windowSize = 1024;      const int analyzeSize = 8192;      const int numWindows = analyzeSize / windowSize;      double trackStart = track->GetStartTime();      double t0 = mT0 < trackStart? trackStart: mT0;      longSampleCount start = track->TimeToLongSamples(t0);      double rate = track->GetRate();      float buffer[analyzeSize];      float freq[windowSize/2];      float freqa[windowSize/2];      int i, j, argmax;      int lag;      for(j=0; j<windowSize/2; j++)         freqa[j] = 0;      track->Get((samplePtr) buffer, floatSample, start, analyzeSize);      for(i=0; i<numWindows; i++) {         ComputeSpectrum(buffer+i*windowSize, windowSize, windowSize/2,                         (int)rate, windowSize, rate, freq, true);         for(j=0; j<windowSize/2; j++)            freqa[j] += freq[j];      }      argmax=0;      for(j=1; j<windowSize/2; j++)         if (freqa[j] > freqa[argmax])            argmax = j;      lag = (windowSize/2 - 1) - argmax;      m_FromFrequency = rate / lag;		m_ToFrequency = (m_FromFrequency * (100.0 + m_PercentChange)) / 100.0;		// Now we can set the pitch control values. 		m_FromPitchIndex = PitchIndex(Freq2Pitch(m_FromFrequency));		m_bWantPitchDown = (m_ToFrequency < m_FromFrequency);		m_ToPitchIndex = PitchIndex(Freq2Pitch(m_ToFrequency));   }}bool EffectChangePitch::PromptUser(){	this->DeduceFrequencies(); // Set frequency-related control values based on sample.   ChangePitchDialog dlog(this, mParent, -1, _("Change Pitch"));   dlog.m_FromPitchIndex = m_FromPitchIndex;   dlog.m_bWantPitchDown = m_bWantPitchDown;   dlog.m_ToPitchIndex = m_ToPitchIndex;	dlog.m_SemitonesChange = m_SemitonesChange;   dlog.m_FromFrequency = m_FromFrequency;   dlog.m_ToFrequency = m_ToFrequency;   dlog.m_PercentChange = m_PercentChange;	// Don't need to call TransferDataToWindow, although other 	//	Audacity dialogs (from which I derived this one) do it, because 	//	ShowModal calls stuff that eventually calls wxWindowBase::OnInitDialog, 	//	which calls dlog.TransferDataToWindow();   dlog.CentreOnParent();   dlog.ShowModal();   if (!dlog.GetReturnCode())      return false;   m_FromPitchIndex = dlog.m_FromPitchIndex;   m_bWantPitchDown = dlog.m_bWantPitchDown;   m_ToPitchIndex = dlog.m_ToPitchIndex;	m_SemitonesChange = dlog.m_SemitonesChange;   m_FromFrequency = dlog.m_FromFrequency;   m_ToFrequency = dlog.m_ToFrequency;   m_PercentChange = dlog.m_PercentChange;   return true;}bool EffectChangePitch::TransferParameters( Shuttle & shuttle ){     shuttle.TransferDouble(wxT("Percentage"),m_PercentChange,0.0);   return true;}bool EffectChangePitch::Process(){   mSoundTouch = new SoundTouch();   mSoundTouch->setPitchSemiTones((float)(m_SemitonesChange));   return this->EffectSoundTouch::Process();}//----------------------------------------------------------------------------// ChangePitchDialog//----------------------------------------------------------------------------#define PERCENTCHANGE_MIN -99#define PERCENTCHANGE_MAX 100 // warped above zero to actually go up to 400%#define PERCENTCHANGE_SLIDER_WARP 1.30105 // warp power takes max from 100 to 400.enum {   ID_TEXT_PERCENTCHANGE = 10001,   ID_SLIDER_PERCENTCHANGE,   ID_CHOICE_FROMPITCH,   ID_RADIOBOX_PITCHUPDOWN,   ID_CHOICE_TOPITCH,   ID_TEXT_SEMITONESCHANGE,   ID_TEXT_FROMFREQUENCY,   ID_TEXT_TOFREQUENCY,	ID_BUTTON_PREVIEW};// event table for ChangePitchDialogBEGIN_EVENT_TABLE(ChangePitchDialog, wxDialog)	EVT_BUTTON(wxID_OK, ChangePitchDialog::OnOk)	EVT_BUTTON(wxID_CANCEL, ChangePitchDialog::OnCancel)	EVT_CHOICE(ID_CHOICE_FROMPITCH, ChangePitchDialog::OnChoice_FromPitch)	EVT_RADIOBOX(ID_RADIOBOX_PITCHUPDOWN, ChangePitchDialog::OnRadioBox_PitchUpDown)	EVT_CHOICE(ID_CHOICE_TOPITCH, ChangePitchDialog::OnChoice_ToPitch)	EVT_TEXT(ID_TEXT_SEMITONESCHANGE, ChangePitchDialog::OnText_SemitonesChange)	EVT_TEXT(ID_TEXT_FROMFREQUENCY, ChangePitchDialog::OnText_FromFrequency)	EVT_TEXT(ID_TEXT_TOFREQUENCY, ChangePitchDialog::OnText_ToFrequency)	EVT_TEXT(ID_TEXT_PERCENTCHANGE, ChangePitchDialog::OnText_PercentChange)	EVT_SLIDER(ID_SLIDER_PERCENTCHANGE, ChangePitchDialog::OnSlider_PercentChange)	EVT_BUTTON(ID_BUTTON_PREVIEW, ChangePitchDialog::OnPreview)END_EVENT_TABLE()ChangePitchDialog::ChangePitchDialog(EffectChangePitch * effect, 												 wxWindow * parent, wxWindowID id, 												 const wxString & title, 												 const wxPoint & position, 												 const wxSize & size, 												 long style): wxDialog(parent, id, title, position, size, style){   m_bLoopDetect = false;	m_pEffect = effect;	// NULL out these control members because there are some cases where the 	// event table handlers get called during this method, and those handlers that 	// can cause trouble check for NULL.   m_pChoice_FromPitch = NULL;	m_pRadioBox_PitchUpDown = NULL;	m_pChoice_ToPitch = NULL;   	m_pTextCtrl_SemitonesChange = NULL;	m_pTextCtrl_FromFrequency = NULL;	m_pTextCtrl_ToFrequency = NULL;   	m_pTextCtrl_PercentChange = NULL;	m_pSlider_PercentChange = NULL;	// effect parameters	m_FromPitchIndex = -1;		// -1 => uninitialized	m_bWantPitchDown = false;	m_ToPitchIndex = -1;			// -1 => uninitialized	m_SemitonesChange = 0.0;   m_FromFrequency = 0.0;		// 0.0 => uninitialized   m_ToFrequency = 0.0;			// 0.0 => uninitialized	m_PercentChange = 0.0;		// CREATE THE CONTROLS PROGRAMMATICALLY.	wxStaticText * pStaticText;   wxBoxSizer * pBoxSizer_Dialog = new wxBoxSizer(wxVERTICAL);	// heading   pStaticText = new wxStaticText(this, -1, 												_("Change Pitch without Changing Tempo"),												wxDefaultPosition, wxDefaultSize, 0);   pBoxSizer_Dialog->Add(pStaticText, 0, wxALIGN_CENTER | wxALL, 8);   pStaticText = new wxStaticText(this, -1, 												_("by Vaughan Johnson && Dominic Mazzoni"),												wxDefaultPosition, wxDefaultSize, 0);   pBoxSizer_Dialog->Add(pStaticText, 0, wxALIGN_CENTER | wxTOP | wxLEFT | wxRIGHT, 8);   pStaticText = new wxStaticText(this, -1, 												_("using SoundTouch, by Olli Parviainen"),												wxDefaultPosition, wxDefaultSize, 0);   pBoxSizer_Dialog->Add(pStaticText, 0, wxALIGN_CENTER | wxBOTTOM | wxLEFT | wxRIGHT, 8);   pBoxSizer_Dialog->Add(0, 8, 0); // spacer	// from/to pitch controls   wxBoxSizer * pBoxSizer_Pitch = new wxBoxSizer(wxHORIZONTAL);      pStaticText = new wxStaticText(this, -1, _("Pitch:   from"),												wxDefaultPosition, wxDefaultSize, 0);   pBoxSizer_Pitch->Add(pStaticText, 0, 								wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 4);	const wxString strArray_PitchNames[] = 		{wxT("C"), wxT("C#/Db"), wxT("D"), wxT("D#/Eb"), wxT("E"), wxT("F"),        wxT("F#/Gb"), wxT("G"), wxT("G#/Ab"), wxT("A"), wxT("A#/Bb"), wxT("B")};	const int numChoicesPitchNames = 12;   m_pChoice_FromPitch = 		new wxChoice(this, ID_CHOICE_FROMPITCH, wxDefaultPosition, wxSize(64, -1), 							numChoicesPitchNames, strArray_PitchNames);   pBoxSizer_Pitch->Add(m_pChoice_FromPitch, 0, 								wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 4);	const wxString strArray_RadioPitchUpDown[] = {_("up"), _("down")};	m_pRadioBox_PitchUpDown = 		new wxRadioBox(this, ID_RADIOBOX_PITCHUPDOWN, wxT(""), wxDefaultPosition, wxDefaultSize, 								2, strArray_RadioPitchUpDown, 1);   pBoxSizer_Pitch->Add(m_pRadioBox_PitchUpDown, 0, 								wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 4);   	pStaticText = new wxStaticText(this, -1, _("to"), wxDefaultPosition, wxDefaultSize, 0);   pBoxSizer_Pitch->Add(pStaticText, 0, 								wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 4);   m_pChoice_ToPitch = 		new wxChoice(this, ID_CHOICE_TOPITCH, wxDefaultPosition, wxSize(64, -1), 							numChoicesPitchNames, strArray_PitchNames);   pBoxSizer_Pitch->Add(m_pChoice_ToPitch, 0, 								wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 4);   pBoxSizer_Dialog->Add(pBoxSizer_Pitch, 0, wxALIGN_CENTER | wxALL, 4);	// semitones change controls   wxBoxSizer * pBoxSizer_SemitonesChange = new wxBoxSizer(wxHORIZONTAL);   pStaticText = new wxStaticText(this, -1, _("Semitones (half-steps):"),												wxDefaultPosition, wxDefaultSize, 0);   pBoxSizer_SemitonesChange->Add(pStaticText, 0, 												wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 4);   m_pTextCtrl_SemitonesChange = 		new wxTextCtrl(this, ID_TEXT_SEMITONESCHANGE, wxT("0.0"), 							wxDefaultPosition, wxSize(40, -1), 0, 							wxTextValidator(wxFILTER_NUMERIC));   pBoxSizer_SemitonesChange->Add(m_pTextCtrl_SemitonesChange, 0, 												wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 4);   pBoxSizer_Dialog->Add(pBoxSizer_SemitonesChange, 0, wxALIGN_CENTER | wxALL, 4);		// from/to frequency controls   pBoxSizer_Dialog->Add(0, 8, 0); // spacer   wxBoxSizer * pBoxSizer_Frequency = new wxBoxSizer(wxHORIZONTAL);      pStaticText = new wxStaticText(this, -1, _("Frequency (Hz):   from"),									       wxDefaultPosition, wxDefaultSize, 0);   pBoxSizer_Frequency->Add(pStaticText, 0, 									wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 4);   m_pTextCtrl_FromFrequency = 		new wxTextCtrl(this, ID_TEXT_FROMFREQUENCY, wxT(""), 							wxDefaultPosition, wxSize(64, -1), 0,							wxTextValidator(wxFILTER_NUMERIC));   pBoxSizer_Frequency->Add(m_pTextCtrl_FromFrequency, 0, 									wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 4);   pStaticText = new wxStaticText(this, -1, _("to"),									       wxDefaultPosition, wxDefaultSize, 0);   pBoxSizer_Frequency->Add(pStaticText, 0, 									wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 4);   m_pTextCtrl_ToFrequency = 		new wxTextCtrl(this, ID_TEXT_TOFREQUENCY, wxT(""), 							wxDefaultPosition, wxSize(64, -1), 0,							wxTextValidator(wxFILTER_NUMERIC));   pBoxSizer_Frequency->Add(m_pTextCtrl_ToFrequency, 0, 										wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 4);   pBoxSizer_Dialog->Add(pBoxSizer_Frequency, 0, wxALIGN_CENTER | wxALL, 4);	// percent change control		// Group percent controls with spacers, 	// rather than static box, so they don't look isolated.   pBoxSizer_Dialog->Add(0, 8, 0); // spacer   wxBoxSizer * pBoxSizer_PercentChange = new wxBoxSizer(wxHORIZONTAL);      pStaticText = new wxStaticText(this, -1, _("Percent Change:"),												wxDefaultPosition, wxDefaultSize, 0);   pBoxSizer_PercentChange->Add(pStaticText, 0, 											wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 4);	//v Override wxTextValidator to disallow negative values < -100.0?   m_pTextCtrl_PercentChange = 		new wxTextCtrl(this, ID_TEXT_PERCENTCHANGE, wxT("0.0"), 							wxDefaultPosition, wxSize(40, -1), 0,							wxTextValidator(wxFILTER_NUMERIC));   pBoxSizer_PercentChange->Add(m_pTextCtrl_PercentChange, 0, 											wxALIGN_CENTER_VERTICAL | wxALL, 4);   pBoxSizer_Dialog->Add(pBoxSizer_PercentChange, 0, wxALIGN_CENTER | wxALL, 4);   m_pSlider_PercentChange = 		new wxSlider(this, ID_SLIDER_PERCENTCHANGE, 							0, PERCENTCHANGE_MIN, PERCENTCHANGE_MAX,							wxDefaultPosition, wxSize(100, -1), wxSL_HORIZONTAL);   pBoxSizer_Dialog->Add(m_pSlider_PercentChange, 1, 									wxGROW | wxALIGN_CENTER | wxLEFT | wxRIGHT, 4);   pBoxSizer_Dialog->Add(0, 8, 0); // spacer	// Preview, OK, & Cancel buttons   pBoxSizer_Dialog->Add(0, 8, 0); // spacer   wxBoxSizer * pBoxSizer_OK = new wxBoxSizer(wxHORIZONTAL);   wxButton * pButton_Preview = 		new wxButton(this, ID_BUTTON_PREVIEW, m_pEffect->GetPreviewName());   pBoxSizer_OK->Add(pButton_Preview, 0, wxALIGN_CENTER | wxALL, 4);   pBoxSizer_OK->Add(32, 8); // horizontal spacer   wxButton * pButton_Cancel =       new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0);   pBoxSizer_OK->Add(pButton_Cancel, 0, wxALIGN_CENTER | wxALL, 4);   wxButton * pButton_OK =       new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0);   pButton_OK->SetDefault();   pButton_OK->SetFocus();   pBoxSizer_OK->Add(pButton_OK, 0, wxALIGN_CENTER | wxALL, 4);   pBoxSizer_Dialog->Add(pBoxSizer_OK, 0, wxALIGN_CENTER | wxALL, 8);   this->SetAutoLayout(true);   this->SetSizer(pBoxSizer_Dialog);   pBoxSizer_Dialog->Fit(this);   pBoxSizer_Dialog->SetSizeHints(this);}bool ChangePitchDialog::Validate(){   return true; }bool ChangePitchDialog::TransferDataToWindow(){   m_bLoopDetect = true;	// from/to pitch controls	if (m_pChoice_FromPitch) 		m_pChoice_FromPitch->SetSelection(m_FromPitchIndex);	this->Update_RadioBox_PitchUpDown();	this->Update_Choice_ToPitch();	// semitones change control	this->Update_Text_SemitonesChange();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -