31#ifndef SBL_DSP_WIDGETS_SVF_HPP_
32#define SBL_DSP_WIDGETS_SVF_HPP_
93 cd_resonance_.
reset(su);
133 const float* cutoff_mod =
nullptr,
float mod_depth = 0.0f) {
135 float freq_target = target_freq_hz_;
136 float q_target = target_q_;
139 float s1 = state_1_, s2 = state_2_;
141 for (uint16_t i = 0; i < frames; ++i) {
143 float center = cd_cutoff_.
process(freq_target);
144 float q = cd_resonance_.
process(q_target);
147 float freq = (cutoff_mod !=
nullptr)
154 if (f > 0.497f) f = 0.497f;
156 float r = (1.0f - q) * 2.0f;
157 float h = 1.0f / (1.0f + r * g + g * g);
160 float comp = (ck > 0.0f) ? 1.0f / (1.0f + q * ck) : 1.0f;
163 float x = buf[i] * comp;
164 float hp = (x - r * s1 - g * s1 - s2) * h;
165 float bp = g * hp + s1;
167 float lp = g * bp + s2;
175 default: buf[i] = lp;
break;
182 sync_cached_coefficients();
196 void set_cutoff(
float freq_hz) {
197 target_freq_hz_ = freq_hz;
198 cd_cutoff_.
reset(freq_hz);
199 apply_cutoff(freq_hz);
204 void set_resonance(
float q) {
206 cd_resonance_.
reset(q);
211 void apply_cutoff(
float freq_hz) {
213 if (f > 0.497f) f = 0.497f;
215 h_ = 1.0f / (1.0f + r_ * g_ + g_ * g_);
218 void apply_resonance(
float q) {
220 r_ = (1.0f - q) * 2.0f;
221 h_ = 1.0f / (1.0f + r_ * g_ + g_ * g_);
225 void update_comp_gain() {
226 comp_gain_ = (comp_k_ > 0.0f)
227 ? 1.0f / (1.0f + q_ * comp_k_)
231 void ensure_smoothers() {
232 if (!smoothers_configured_) {
235 cd_cutoff_.
reset(target_freq_hz_);
236 cd_resonance_.
reset(target_q_);
237 smoothers_configured_ =
true;
241 void sync_cached_coefficients() {
242 q_ = cd_resonance_.
value();
243 r_ = (1.0f - q_) * 2.0f;
245 if (f > 0.497f) f = 0.497f;
247 h_ = 1.0f / (1.0f + r_ * g_ + g_ * g_);
248 comp_gain_ = (comp_k_ > 0.0f) ? 1.0f / (1.0f + q_ * comp_k_) : 1.0f;
256 float comp_k_ = 0.0f;
257 float comp_gain_ = 1.0f;
258 float state_1_ = 0.0f;
259 float state_2_ = 0.0f;
263 primitives::CriticalDamp cd_cutoff_;
264 primitives::CriticalDamp cd_resonance_;
265 float target_freq_hz_ = 0.0f;
266 float target_q_ = 0.0f;
267 bool cutoff_init_ =
false;
268 bool reso_init_ =
false;
269 bool smoothers_configured_ =
false;
Clamping (Cross-cutting — Math)
float value() const
Current output value.
void set_time_ms(float ms, float rate_hz)
Set settling time in milliseconds.
void reset()
Reset to zero.
float process(float target)
Process one sample toward target.
Critically damped 2nd-order parameter smoother.
Exponential modulation converter (Signal layer)
Fast analytical approximations (Audio Stack — Atoms)
Fixed-point constants and audio sample types.
constexpr float clamp01(float x)
x held to [0, 1]; NaN → 0.
float exp_mod(float base, float mod, float depth, float lo=20.0f, float hi=20000.0f)
float fast_tan_pif(float f)
float su_to_hz(float su, float min_hz, float octaves)