📄 phaser.cpp
字号:
/********************************************************************** Audacity: A Digital Audio Editor Phaser.cpp Effect programming: Nasca Octavian Paul UI programming: Dominic Mazzoni (with the help of wxDesigner) Vaughan Johnson (Preview)**********************************************************************/#include "Phaser.h"#include "../WaveTrack.h"#include "../FFT.h"#include <wx/button.h>#include <wx/textctrl.h>#include <wx/sizer.h>#include <wx/spinctrl.h>#include <wx/stattext.h>#include <math.h>#define ID_BUTTON_PREVIEW 10000//// EffectPhaser//#define phaserlfoshape 4.0// How many samples are processed before compute the lfo value again#define lfoskipsamples 20EffectPhaser::EffectPhaser(){ freq = (float)0.4; depth = 100; startphase = float(0.0); stages = 2; drywet = 128; fb = float(0.0);}wxString EffectPhaser::GetEffectDescription() { // Note: This is useful only after values have been set. return wxString::Format(_("Applied effect: %s %d stages, %.0f%% wet, frequency = %.1f Hz, start phase = %.0f deg, depth = %d, feedback = %.0f%%"), this->GetEffectName().c_str(), stages, float(drywet*100/255), freq, (startphase * 180 / M_PI), depth, fb); } bool EffectPhaser::PromptUser(){ PhaserDialog dlog(this, mParent, -1, _("Phaser")); dlog.freq = freq; dlog.startphase = startphase * 180 / M_PI; dlog.fb = fb; dlog.depth = depth; dlog.stages = stages; dlog.drywet = drywet; dlog.TransferDataToWindow(); dlog.CentreOnParent(); dlog.ShowModal(); if (!dlog.GetReturnCode()) return false; freq = dlog.freq; startphase = dlog.startphase * M_PI / 180; fb = dlog.fb; depth = dlog.depth; stages = dlog.stages; drywet = dlog.drywet; return true;}bool EffectPhaser::TransferParameters( Shuttle & shuttle ){ shuttle.TransferInt(wxT("Stages"),stages,2); shuttle.TransferInt(wxT("Wet"),drywet,128); shuttle.TransferFloat(wxT("Freq"),freq,0.4f); shuttle.TransferInt(wxT("Depth"),depth,100); shuttle.TransferFloat(wxT("Feedback"),fb,0.0f); return true;}bool EffectPhaser::NewTrackSimpleMono(){ for (int j = 0; j < stages; j++) old[j] = 0; skipcount = 0; gain = 0; fbout = 0; lfoskip = freq * 2 * M_PI / mCurRate; phase = startphase; if (mCurChannel == Track::RightChannel) phase += (float)M_PI; return true;}bool EffectPhaser::ProcessSimpleMono(float *buffer, sampleCount len){ float m, tmp, in, out; int i, j; for (i = 0; i < len; i++) { in = buffer[i]; m = in + fbout * fb / 100; if (((skipcount++) % lfoskipsamples) == 0) { //compute sine between 0 and 1 gain = (1 + cos(skipcount * lfoskip + phase)) / 2; // change lfo shape gain = (exp(gain * phaserlfoshape) - 1) / (exp(phaserlfoshape)-1); gain = 1 - gain / 255 * depth; // attenuate the lfo } // phasing routine for (j = 0; j < stages; j++) { tmp = old[j]; old[j] = gain * tmp + m; m = tmp - gain * old[j]; } fbout = m; out = (m * drywet + in * (255 - drywet)) / 255; // Prevents clipping if (out < -1.0) out = float(-1.0); else if (out > 1.0) out = float(1.0); buffer[i] = out; } return true;}// WDR: class implementations//----------------------------------------------------------------------------// PhaserDialog//----------------------------------------------------------------------------#define FREQ_MIN 1#define FREQ_MAX 40#define PHASE_MIN 0#define PHASE_MAX 359#define DEPTH_MIN 0#define DEPTH_MAX 255#define STAGES_MIN 2#define STAGES_MAX 24#define DRYWET_MIN 0#define DRYWET_MAX 255#define FB_MIN -100#define FB_MAX 100// WDR: event table for PhaserDialogBEGIN_EVENT_TABLE(PhaserDialog, wxDialog) EVT_BUTTON(wxID_OK, PhaserDialog::OnOk) EVT_BUTTON(wxID_CANCEL, PhaserDialog::OnCancel) EVT_TEXT(ID_FREQTEXT, PhaserDialog::OnFreqText) EVT_TEXT(ID_PHASETEXT, PhaserDialog::OnPhaseText) EVT_TEXT(ID_DEPTHTEXT, PhaserDialog::OnDepthText) EVT_TEXT(ID_FEEDBACKTEXT, PhaserDialog::OnFeedbackText) EVT_SLIDER(ID_FREQSLIDER, PhaserDialog::OnFreqSlider) EVT_SLIDER(ID_PHASESLIDER, PhaserDialog::OnPhaseSlider) EVT_SLIDER(ID_DEPTHSLIDER, PhaserDialog::OnDepthSlider) EVT_SLIDER(ID_FEEDBACKSLIDER, PhaserDialog::OnFeedbackSlider) EVT_BUTTON(ID_BUTTON_PREVIEW, PhaserDialog::OnPreview)END_EVENT_TABLE()PhaserDialog::PhaserDialog(EffectPhaser * effect, wxWindow * parent, wxWindowID id, const wxString & title, const wxPoint & position, const wxSize & size, long style):wxDialog(parent, id, title, position, size, style){ m_pEffect = effect; CreatePhaserDialog(this, TRUE);}bool PhaserDialog::Validate(){ return TRUE;}bool PhaserDialog::TransferDataToWindow(){ wxSlider *slider; slider = GetFreqSlider(); if (slider) slider->SetValue((int)(freq * 10)); slider = GetPhaseSlider(); if (slider) slider->SetValue((int)startphase); slider = GetDepthSlider(); if (slider) slider->SetValue((int)depth); slider = GetFeedbackSlider(); if (slider) slider->SetValue((int)fb); slider = GetDryWet(); if (slider) slider->SetValue((int)drywet); wxSpinCtrl *spin = GetStages(); if (spin) spin->SetValue(stages); wxTextCtrl *text = GetFreqText(); if (text) { wxString str; str.Printf(wxT("%.1f"), freq); text->SetValue(str); } text = GetPhaseText(); if (text) { wxString str; str.Printf(wxT("%d"), (int) startphase); text->SetValue(str); } text = GetDepthText(); if (text) { wxString str; str.Printf(wxT("%d"), (int) depth); text->SetValue(str); } text = GetFeedbackText(); if (text) { wxString str; str.Printf(wxT("%d"), (int) fb); text->SetValue(str); } return TRUE;}bool PhaserDialog::TransferDataFromWindow(){ wxTextCtrl *c; long x; c = GetFreqText(); if (c) { double d; c->GetValue().ToDouble(&d); freq = TrapDouble(d * 10, FREQ_MIN, FREQ_MAX) / 10; } c = GetPhaseText(); if (c) { c->GetValue().ToLong(&x); startphase = TrapLong(x, PHASE_MIN, PHASE_MAX); } c = GetDepthText(); if (c) { c->GetValue().ToLong(&x); depth = TrapLong(x, DEPTH_MIN, DEPTH_MAX); } c = GetFeedbackText(); if (c) { c->GetValue().ToLong(&x); fb = TrapLong(x, FB_MIN, FB_MAX); } wxSpinCtrl *p = GetStages(); if (p) { stages = TrapLong(p->GetValue(), STAGES_MIN, STAGES_MAX); if ((stages % 2) == 1) // must be even stages = TrapLong(stages - 1, STAGES_MIN, STAGES_MAX); } wxSlider *s = GetDryWet(); if (s) { drywet = TrapLong(s->GetValue(), DRYWET_MIN, DRYWET_MAX); } return TRUE;}// WDR: handler implementations for PhaserDialog
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -