134 if (!(spec.sampleRate > 0.0))
return;
136 updateCoefficients();
147 const int nCh = std::min(buffer.getNumChannels(),
kMaxChannels);
148 const int nS = buffer.getNumSamples();
152 for (
int ch = 0; ch < nCh; ++ch)
154 T* data = buffer.getChannel(ch);
155 for (
int i = 0; i < nS; ++i)
156 data[i] = processOne(data[i], ch);
178 if (channel < 0 || channel >=
kMaxChannels)
return input;
179 return processOne(input, channel);
196 if (channel < 0 || channel >=
kMaxChannels)
return { input, T(0), T(0) };
197 return processCore(input, channel);
225 if (!std::isfinite(hz))
return;
227 updateCoefficients();
239 if (!std::isfinite(resonance))
return;
240 resonance_ = std::clamp(resonance, T(0), T(1));
243 R_ = T(1) / (T(2) * Q);
245 updateDerivedCoeffs();
259 if (!std::isfinite(q))
return;
260 q = std::max(q, T(0.01));
261 R_ = T(1) / (T(2) * q);
262 resonance_ = std::clamp((q - T(0.5)) / T(49.5), T(0), T(1));
264 updateDerivedCoeffs();
271 updateDerivedCoeffs();
280 if (!std::isfinite(dB))
return;
282 A_ = std::pow(T(10), std::abs(dB) / T(40));
284 updateDerivedCoeffs();
291 [[nodiscard]] T
getQ() const noexcept {
return T(1) / (T(2) *
R_); }
304 std::array<ChannelState, kMaxChannels>
state_ {};
328 void updateCoefficients() noexcept
334 g_ =
static_cast<T
>(std::tan(pi<double> *
static_cast<double>(
cutoff_)
338 updateDerivedCoeffs();
342 void updateBellR() noexcept
365 void updateDerivedCoeffs() noexcept
372 const T sqrtAs = std::sqrt((
gainDb_ >= T(0)) ?
A_ : T(1) /
A_);
377 a1_ = T(1) / (T(1) + T(2) *
effR_ * gEff + gEff * gEff);
383 [[nodiscard]] T processOne(T input,
int channel)
noexcept
385 const MultiOutput m = processCore(input, channel);
386 return selectOutput(input, m.lowpass, m.highpass, m.bandpass);
402 [[nodiscard]] MultiOutput processCore(T input,
int channel)
noexcept
404 auto& s =
state_[channel];
406 const T v3 = input - s.ic2eq;
407 const T v1 =
a1_ * s.ic1eq +
a2_ * v3;
408 const T v2 = s.ic2eq +
a2_ * s.ic1eq +
a3_ * v3;
410 s.ic1eq = T(2) * v1 - s.ic1eq;
411 s.ic2eq = T(2) * v2 - s.ic2eq;
413 return { v2, input - T(2) *
effR_ * v1 - v2, v1 };
416 [[nodiscard]] T selectOutput(T input, T lp, T hp, T bp)
const noexcept
436 const T k = T(2) *
Rbell_;
438 ? input + (
A_ *
A_ - T(1)) * k * bp
439 : input + (T(1) / (
A_ *
A_) - T(1)) * k * bp;
450 const T twoR = T(2) *
R_;
451 return As * As * lp + As * twoR * bp + hp;
458 const T twoR = T(2) *
R_;
459 return lp + As * twoR * bp + As * As * hp;
Owning audio buffer and non-owning view for real-time DSP processing.
Describes the audio processing environment (sample rate, block size, channels).
RAII scope guard that disables denormal (subnormal) float arithmetic.
Core mathematical utilities for digital signal processing.
Non-owning view over audio channel data.
RAII scope guard to disable denormalised (subnormal) floating-point numbers.
TPT State Variable Filter with simultaneous multi-output.
void setResonance(T resonance) noexcept
Sets the resonance amount.
void setCutoff(T hz) noexcept
Sets the cutoff/center frequency.
std::array< ChannelState, kMaxChannels > state_
void setQ(T q) noexcept
Sets the Q factor directly.
Mode getMode() const noexcept
T getGain() const noexcept
void reset() noexcept
Resets internal state.
~StateVariableFilter()=default
void setGain(T dB) noexcept
Sets gain for Bell/Shelf modes (in dB).
static constexpr int kMaxChannels
void setMode(Mode mode) noexcept
Sets the output mode.
MultiOutput processMultiOutput(T input, int channel) noexcept
Processes a single sample returning LP, HP, BP simultaneously.
void processBlock(AudioBufferView< T > buffer) noexcept
Processes an audio buffer in-place using the selected Mode.
Mode
Filter output mode for processBlock/processSample.
@ LowShelf
Low shelf (boost/cut below frequency).
@ BandPass
Bandpass (constant skirt gain).
@ AllPass
Allpass (phase shift, unity gain).
@ LowPass
2nd-order lowpass (12 dB/oct).
@ Bell
Parametric bell (boost/cut at frequency).
@ Notch
Band-reject (notch).
@ HighShelf
High shelf (boost/cut above frequency).
@ HighPass
2nd-order highpass (12 dB/oct).
T processSample(T input, int channel) noexcept
Processes a single sample (selected Mode output).
void prepare(const AudioSpec &spec) noexcept
Prepares the filter.
T getCutoff() const noexcept
T getResonance() const noexcept
Main namespace for the DSPark framework.
Describes the audio environment for a DSP processor.
double sampleRate
Sample rate in Hz.
T ic2eq
Second integrator state.
T ic1eq
First integrator state.
Result struct for simultaneous multi-output processing.