25#define SVFMODES_VALIST "LowPass", "HighPass", "BandPass", "Notch", "Peak", "Bell", "LowPassShelf", "HighPassShelf"
27template<
typename T =
double,
int NC = 1>
45 SVF(EMode mode = kLowPass,
double freqCPS = 1000.)
47 mNewState.mode = mState.mode = mode;
48 mNewState.freq = mState.freq = freqCPS;
52 static double PlotResponse(
double freqCPS,
double Q, EMode mode,
double x,
double gain = 0.,
double minHz = 1.,
double maxHz = 20000)
54 using cdouble = std::complex<double>;
56 const double g = freqCPS;
57 const double k = 1.0 / Q;
60 static double minLogHz = std::log10(minHz);
61 static double maxLogHz = std::log10(maxHz);
62 static const cdouble _1j = std::sqrt(cdouble(-1, 0));
64 const double w = std::pow(10., (x * (maxLogHz - minLogHz)) + minHz);
65 const cdouble s = _1j * w;
70 case kLowPass: result = g * g / (g * g + g * k * s + s * s);
break;
71 case kBandPass: result = g * s / (g * g + g * k * s + s * s);
break;
72 case kHighPass: result = s * s / (g * g + g * k * s + s * s);
break;
74 case kPeak: result = (g - s) * (g + s) / (g * g + g * k * s + s * s);
break;
81 const double magnitude = 20. * std::log10(std::abs(std::real(result)));
88 void SetFreqCPS(
double freqCPS) { mNewState.freq =
Clip(freqCPS, 10.0, 20000.); }
90 void SetQ(
double Q) { mNewState.Q =
Clip(Q, 0.1, 100.0); }
92 void SetGain(
double gainDB) { mNewState.gain =
Clip(gainDB, -36.0, 36.0); }
94 void SetMode(EMode mode) { mNewState.mode = mode; }
96 void SetSampleRate(
double sampleRate) { mNewState.sampleRate = sampleRate; }
98 void ProcessBlock(T** inputs, T** outputs,
int nChans,
int nFrames)
100 assert(nChans <= NC);
102 if(mState != mNewState)
103 UpdateCoefficients();
105 for (
auto c = 0; c < nChans; c++)
107 for (
auto s = 0; s < nFrames; s++)
109 const double v0 =
static_cast<double>(inputs[c][s]);
111 mV3[c] = v0 - mIc2eq[c];
112 mV1[c] = m_a1 * mIc1eq[c] + m_a2*mV3[c];
113 mV2[c] = mIc2eq[c] + m_a2 * mIc1eq[c] + m_a3 * mV3[c];
114 mIc1eq[c] = 2.0 * mV1[c] - mIc1eq[c];
115 mIc2eq[c] = 2.0 * mV2[c] - mIc2eq[c];
117 outputs[c][s] =
static_cast<T
>(m_m0) *
static_cast<T
>(v0) +
118 static_cast<T
>(m_m1) *
static_cast<T
>(mV1[c]) +
119 static_cast<T
>(m_m2) *
static_cast<T
>(mV2[c]);
126 for (
auto c = 0; c < NC; c++)
137 void UpdateCoefficients()
141 const double w = std::tan(PI * mState.freq/mState.sampleRate);
148 const double k = 1. / mState.Q;
149 m_a1 = 1./(1. + g * (g + k));
160 const double k = 1. / mState.Q;
161 m_a1 = 1./(1. + g * (g + k));
172 const double k = 1. / mState.Q;
173 m_a1 = 1./(1. + g * (g + k));
184 const double k = 1. / mState.Q;
185 m_a1 = 1./(1. + g * (g + k));
196 const double k = 1. / mState.Q;
197 m_a1 = 1./(1. + g * (g + k));
207 const double A = std::pow(10., mState.gain/40.);
209 const double k = 1 / mState.Q;
210 m_a1 = 1./(1. + g * (g + k));
214 m_m1 = k * (A * A - 1.);
220 const double A = std::pow(10., mState.gain/40.);
221 const double g = w / std::sqrt(A);
222 const double k = 1. / mState.Q;
223 m_a1 = 1./(1. + g * (g + k));
233 const double A = std::pow(10., mState.gain/40.);
234 const double g = w / std::sqrt(A);
235 const double k = 1. / mState.Q;
236 m_a1 = 1./(1. + g * (g + k));
253 double mIc1eq[NC] = {};
254 double mIc2eq[NC] = {};
268 double sampleRate = 44100.;
270 bool operator != (
const Settings &other)
const
272 return !(mode == other.mode && freq == other.freq && Q == other.Q && gain == other.gain && sampleRate == other.sampleRate);
276 Settings mState, mNewState;
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.