18 min_resonance_(kDefaultMinResonance), max_resonance_(kDefaultMaxResonance),
19 basic_(false), drive_compensation_(true) {
47 poly_float current_post_multiply = post_multiply_;
57 blends1.
reset(reset_mask, blends1_);
58 blends2.
reset(reset_mask, blends2_);
59 current_resonance =
utils::maskLoad(current_resonance, resonance_, reset_mask);
61 current_post_multiply =
utils::maskLoad(current_post_multiply, post_multiply_, reset_mask);
66 processBasic12(audio_in, num_samples, current_resonance, current_drive, current_post_multiply, blends1);
68 processDual(audio_in, num_samples, current_resonance, current_drive, current_post_multiply, blends1, blends2);
71 process12(audio_in, num_samples, current_resonance, current_drive, current_post_multiply, blends1);
73 process24(audio_in, num_samples, current_resonance, current_drive, current_post_multiply, blends1);
81 poly_float delta_resonance = (resonance_ - current_resonance) * sample_inc;
82 poly_float delta_drive = (drive_ - current_drive) * sample_inc;
83 poly_float delta_post_multiply = (post_multiply_ - current_post_multiply) * sample_inc;
88 poly_float base_midi = midi_cutoff_buffer[num_samples - 1];
91 for (
int i = 0; i < num_samples; ++i) {
97 current_resonance += delta_resonance;
98 current_drive += delta_drive;
99 current_post_multiply += delta_post_multiply;
101 audio_out[i] =
tick(audio_in[i], coefficient, current_resonance, current_drive, blends) * current_post_multiply;
111 poly_float delta_resonance = (resonance_ - current_resonance) * sample_inc;
112 poly_float delta_drive = (drive_ - current_drive) * sample_inc;
113 poly_float delta_post_multiply = (post_multiply_ - current_post_multiply) * sample_inc;
118 poly_float base_midi = midi_cutoff_buffer[num_samples - 1];
121 for (
int i = 0; i < num_samples; ++i) {
122 poly_float midi_delta = midi_cutoff_buffer[i] - base_midi;
127 current_resonance += delta_resonance;
128 current_drive += delta_drive;
129 current_post_multiply += delta_post_multiply;
131 audio_out[i] =
tickBasic(audio_in[i], coefficient, current_resonance, current_drive, blends) * current_post_multiply;
141 poly_float delta_resonance = (resonance_ - current_resonance) * sample_inc;
142 poly_float delta_drive = (drive_ - current_drive) * sample_inc;
143 poly_float delta_post_multiply = (post_multiply_ - current_post_multiply) * sample_inc;
148 poly_float base_midi = midi_cutoff_buffer[num_samples - 1];
151 for (
int i = 0; i < num_samples; ++i) {
152 poly_float midi_delta = midi_cutoff_buffer[i] - base_midi;
157 current_resonance += delta_resonance;
158 current_drive += delta_drive;
159 current_post_multiply += delta_post_multiply;
161 poly_float result =
tick24(audio_in[i], coefficient, current_resonance, current_drive, blends);
162 audio_out[i] = result * current_post_multiply;
172 poly_float delta_resonance = (resonance_ - current_resonance) * sample_inc;
173 poly_float delta_drive = (drive_ - current_drive) * sample_inc;
174 poly_float delta_post_multiply = (post_multiply_ - current_post_multiply) * sample_inc;
179 poly_float base_midi = midi_cutoff_buffer[num_samples - 1];
182 for (
int i = 0; i < num_samples; ++i) {
183 poly_float midi_delta = midi_cutoff_buffer[i] - base_midi;
188 current_resonance += delta_resonance;
189 current_drive += delta_drive;
190 current_post_multiply += delta_post_multiply;
193 audio_out[i] = result * current_post_multiply;
205 poly_float delta_resonance = (resonance_ - current_resonance) * sample_inc;
206 poly_float delta_drive = (drive_ - current_drive) * sample_inc;
207 poly_float delta_post_multiply = (post_multiply_ - current_post_multiply) * sample_inc;
212 poly_float base_midi = midi_cutoff_buffer[num_samples - 1];
215 for (
int i = 0; i < num_samples; ++i) {
216 poly_float midi_delta = midi_cutoff_buffer[i] - base_midi;
222 current_resonance += delta_resonance;
223 current_drive += delta_drive;
224 current_post_multiply += delta_post_multiply;
226 poly_float result =
tickDual(audio_in[i], coefficient, current_resonance, current_drive, blends1, blends2);
227 audio_out[i] = result * current_post_multiply;
248 poly_float resonance_adjust = resonance_percent * resonance_percent * resonance_percent;
250 if (drive_compensation_)
251 drive_ = filter_state.
drive / (resonance_adjust * 2.0f + 1.0f);
253 drive_ = filter_state.
drive;
277 low_amount_ =
utils::min(-blend + 1.0f, 1.0f);
279 high_amount_ =
utils::min(blend + 1.0f, 1.0f);
288 low_amount_ = mult * (peak_band_value + 1.0f);
289 band_amount_ = mult * (peak_band_value - blend + 1.0f) * 2.0f;
290 high_amount_ = low_amount_;
294 post_multiply_ = 1.0f;
305 band_amount_ = resonance_ * amplitude_sqrt *
utils::interpolate(1.0f, amplitude_sqrt, band_t);
311 low_amount_ = (-blend) & blend_mask;
312 high_amount_ = blend & ~blend_mask;
316 blends1_.
v1 = band_amount_;
317 blends1_.
v2 = low_amount_;
320 blends2_.
v1 = band_amount_;
321 blends2_.
v2 = high_amount_;
323 blends1_.
v0 += high_amount_;
324 blends1_.
v1 += -resonance_ * high_amount_;
325 blends1_.
v2 += -high_amount_;
327 blends2_.
v0 += low_amount_;
328 blends2_.
v1 += -resonance_ * low_amount_;
329 blends2_.
v2 += -low_amount_;
333 min_resonance_ = min;
334 max_resonance_ = max;
364 poly_float coefficient_squared = coefficient * coefficient;
366 poly_float coefficient_1 = coefficient_0 * coefficient;
367 poly_float coefficient_2 = coefficient_0 * coefficient_squared;
373 ic1eq_ = v1 * 2.0f - ic1eq_;
374 ic2eq_ = v2 * 2.0f - ic2eq_;
391 poly_float coefficient_squared = coefficient * coefficient;
393 poly_float pre_coefficient_1 = pre_coefficient_0 * coefficient;
394 poly_float pre_coefficient_2 = pre_coefficient_0 * coefficient_squared;
401 pre_coefficient_2, v3_pre);
402 ic1eq_pre_ = v1_pre * 2.0f - ic1eq_pre_;
403 ic2eq_pre_ = v2_pre * 2.0f - ic2eq_pre_;
423 poly_float coefficient_squared = coefficient * coefficient;
425 poly_float pre_coefficient_1 = pre_coefficient_0 * coefficient;
426 poly_float pre_coefficient_2 = pre_coefficient_0 * coefficient_squared;
431 pre_coefficient_2, v3_pre);
432 ic1eq_pre_ = v1_pre * 2.0f - ic1eq_pre_;
433 ic2eq_pre_ = v2_pre * 2.0f - ic2eq_pre_;
453 poly_float coefficient_squared = coefficient * coefficient;
455 poly_float pre_coefficient_1 = pre_coefficient_0 * coefficient;
456 poly_float pre_coefficient_2 = pre_coefficient_0 * coefficient_squared;
458 poly_float coefficient_1 = coefficient_0 * coefficient;
459 poly_float coefficient_2 = coefficient_0 * coefficient_squared;
466 pre_coefficient_2, v3_pre);
467 ic1eq_pre_ = v1_pre * 2.0f - ic1eq_pre_;
468 ic2eq_pre_ = v2_pre * 2.0f - ic2eq_pre_;
476 ic1eq_ = v1 * 2.0f - ic1eq_;
477 ic2eq_ = v2 * 2.0f - ic2eq_;
508 post_multiply_ = 0.0f;
A state-variable filter (SVF) implementation, supporting multiple filter types (12/24 dB,...
Definition digital_svf.h:17
void processDual(const poly_float *audio_in, int num_samples, poly_float current_resonance, poly_float current_drive, poly_float current_post_multiply, FilterValues &blends1, FilterValues &blends2)
Processes a dual filter mode, e.g., dual notch + band pass.
Definition digital_svf.cpp:198
force_inline poly_float tick(poly_float audio_in, poly_float coefficient, poly_float resonance, poly_float drive, FilterValues &blends)
Applies advanced distortion to the input while performing a single SVF tick (12 dB).
Definition digital_svf.cpp:347
static constexpr mono_float kMinCutoff
Minimum allowed cutoff frequency in Hz for the filter.
Definition digital_svf.h:32
static const SvfCoefficientLookup svf_coefficient_lookup_
A static global lookup table instance for SVF coefficients.
Definition digital_svf.h:66
void processBasic24(const poly_float *audio_in, int num_samples, poly_float current_resonance, poly_float current_drive, poly_float current_post_multiply, FilterValues &blends)
Processes a simpler 24 dB filter style, skipping advanced processing.
Definition digital_svf.cpp:167
force_inline poly_float tickBasic24(poly_float audio_in, poly_float coefficient, poly_float resonance, poly_float drive, FilterValues &blends)
A simpler 24 dB tick function without advanced distortion or color.
Definition digital_svf.cpp:421
static constexpr mono_float kMaxGain
Maximum gain in dB for shelf or gain-based operations.
Definition digital_svf.h:37
DigitalSvf()
Constructor that initializes the filter’s internal states.
Definition digital_svf.cpp:17
static const SvfCoefficientLookup * getSvfCoefficientLookup()
Retrieves a pointer to the global SVF coefficient lookup table.
Definition digital_svf.h:73
virtual void process(int num_samples) override
Processes a block of samples by pulling from the primary audio input and computing the SVF output....
Definition digital_svf.cpp:29
void setupFilter(const FilterState &filter_state) override
Configures this SVF based on a FilterState (cutoff, resonance, style, etc.).
Definition digital_svf.cpp:237
static constexpr mono_float kMinGain
Minimum gain in dB for shelf or gain-based operations.
Definition digital_svf.h:42
void processWithInput(const poly_float *audio_in, int num_samples) override
Processes a block of samples using a provided input buffer.
Definition digital_svf.cpp:41
void processBasic12(const poly_float *audio_in, int num_samples, poly_float current_resonance, poly_float current_drive, poly_float current_post_multiply, FilterValues &blends)
Processes a simpler 12 dB filter style, skipping extra color or overshoot logic.
Definition digital_svf.cpp:106
OneDimLookup< computeSvfOnePoleFilterCoefficient, 2048 > SvfCoefficientLookup
A lookup table type for quickly converting frequency ratios into filter coefficients.
Definition digital_svf.h:61
void reset(poly_mask reset_masks) override
Resets internal filter states for voices specified by the reset_masks.
Definition digital_svf.cpp:487
force_inline poly_float tickBasic(poly_float audio_in, poly_float coefficient, poly_float resonance, poly_float drive, FilterValues &blends)
A basic (non-distorting) single SVF tick for a 12 dB filter style.
Definition digital_svf.cpp:362
void process24(const poly_float *audio_in, int num_samples, poly_float current_resonance, poly_float current_drive, poly_float current_post_multiply, FilterValues &blends)
Processes a 24 dB filter style, adding additional stages.
Definition digital_svf.cpp:136
void hardReset() override
Performs a complete reset of the filter states for all voices.
Definition digital_svf.cpp:497
void setResonanceBounds(mono_float min, mono_float max)
Sets the minimum and maximum resonance for the filter (used in resonance interpolation).
Definition digital_svf.cpp:332
void process12(const poly_float *audio_in, int num_samples, poly_float current_resonance, poly_float current_drive, poly_float current_post_multiply, FilterValues &blends)
Processes a 12 dB filter style, iterating through the block.
Definition digital_svf.cpp:76
force_inline poly_float tick24(poly_float audio_in, poly_float coefficient, poly_float resonance, poly_float drive, FilterValues &blends)
Tick function for a 24 dB multi-stage filter, adding an additional pre-stage.
Definition digital_svf.cpp:389
force_inline poly_float tickDual(poly_float audio_in, poly_float coefficient, poly_float resonance, poly_float drive, FilterValues &blends1, FilterValues &blends2)
Tick function for a dual filter approach, e.g. notch + band, etc.
Definition digital_svf.cpp:450
A one-dimensional lookup table for a given function with a specified resolution.
Definition lookup_table.h:31
force_inline poly_float cubicLookup(poly_float value) const
Performs a cubic interpolation lookup on the precomputed data.
Definition lookup_table.h:61
Base class for all signal-processing units in Vital.
Definition processor.h:212
force_inline Input * input(unsigned int index=0) const
Retrieves the Input pointer at a given index.
Definition processor.h:587
force_inline int getSampleRate() const
Retrieves the current (effective) sample rate.
Definition processor.h:326
bool inputMatchesBufferSize(int input=0)
Checks whether the buffer size of a particular input matches the size needed by this Processor.
Definition processor.cpp:42
force_inline poly_mask getResetMask(int input_index) const
Retrieves a mask indicating which voices triggered a note-on event. Compares the input's trigger_valu...
Definition processor.h:360
force_inline Output * output(unsigned int index=0) const
Retrieves the Output pointer at a given index.
Definition processor.h:616
Holds the parameters necessary to configure a SynthFilter at runtime.
Definition synth_filter.h:92
void loadSettings(Processor *processor)
Loads state from a Processor’s input signals (MIDI cutoff, drive, style, etc.).
Definition synth_filter.cpp:30
const poly_float * midi_cutoff_buffer
Pointer to the buffer storing per-sample MIDI cutoff.
Definition synth_filter.h:111
poly_float pass_blend
Blend parameter in [0..2], controlling pass type.
Definition synth_filter.h:117
poly_float drive
Drive in linear magnitude.
Definition synth_filter.h:113
int style
Filter style enum (e.g., k12Db, k24Db)
Definition synth_filter.h:116
poly_float gain
Additional gain parameter.
Definition synth_filter.h:115
poly_float midi_cutoff
MIDI note-based cutoff value.
Definition synth_filter.h:110
poly_float resonance_percent
Resonance parameter in [0..1].
Definition synth_filter.h:112
@ kMidiCutoff
MIDI-based cutoff parameter.
Definition synth_filter.h:57
@ kReset
Reset signal.
Definition synth_filter.h:56
@ kAudio
Audio input index.
Definition synth_filter.h:55
FilterState filter_state_
Internal storage of the most recent FilterState, used by derived filters.
Definition synth_filter.h:151
@ kBandPeakNotch
Definition synth_filter.h:79
@ kNotchPassSwap
Definition synth_filter.h:77
@ kShelving
Definition synth_filter.h:80
@ k12Db
Definition synth_filter.h:75
@ kDualNotchBand
Definition synth_filter.h:78
#define VITAL_ASSERT(x)
Definition common.h:11
#define force_inline
Definition common.h:23
Contains faster but less accurate versions of utility math functions, such as exponential,...
const poly_mask kFullMask
A mask covering all lanes of a poly_float vector.
Definition synth_constants.h:257
force_inline poly_float hardTanh(poly_float value)
Another saturation function using half-range tanh.
Definition futils.h:373
force_inline poly_float midiOffsetToRatio(poly_float note_offset)
Converts a MIDI note offset to a frequency ratio.
Definition futils.h:184
force_inline mono_float pow(mono_float base, mono_float exponent)
Definition futils.h:141
force_inline poly_float clamp(poly_float value, mono_float min, mono_float max)
Clamps each lane of a vector to [min, max].
Definition poly_utils.h:306
force_inline bool isFinite(poly_float value)
Checks if all lanes in a poly_float are finite.
Definition poly_utils.h:610
force_inline poly_float mulAdd(poly_float a, poly_float b, poly_float c)
Performs a fused multiply-add on SIMD data: (a * b) + c.
Definition poly_utils.h:61
force_inline poly_float min(poly_float left, poly_float right)
Returns the minimum of two poly_floats lane-by-lane.
Definition poly_utils.h:334
force_inline poly_float dbToMagnitude(poly_float value)
Converts a dB value to linear magnitude (vectorized).
Definition poly_utils.h:149
force_inline poly_float ratioToMidiTranspose(poly_float value)
Converts a ratio to MIDI transpose (vectorized).
Definition poly_utils.h:109
force_inline poly_float max(poly_float left, poly_float right)
Returns the maximum of two poly_floats lane-by-lane.
Definition poly_utils.h:327
force_inline poly_float maskLoad(poly_float zero_value, poly_float one_value, poly_mask reset_mask)
Selects between two values (zero_value or one_value) based on a mask in each lane.
Definition poly_utils.h:351
force_inline poly_float midiNoteToFrequency(poly_float value)
Converts a MIDI note to a frequency (vectorized).
Definition poly_utils.h:123
force_inline poly_float sqrt(poly_float value)
Computes the square root of each element in a poly_float.
Definition poly_utils.h:169
force_inline poly_float interpolate(poly_float from, poly_float to, mono_float t)
Performs a linear interpolation between two poly_floats using a scalar t in [0..1].
Definition poly_utils.h:182
Contains classes and functions used within the Vital synthesizer framework.
constexpr mono_float kMinNyquistMult
Minimum ratio relative to Nyquist frequency.
Definition common.h:42
float mono_float
Definition common.h:33
Stores three filter state variables (v0, v1, v2) used for multi-mode mixing.
Definition digital_svf.h:79
FilterValues getDelta(const FilterValues &target, mono_float increment)
Computes the per-sample increments needed to move from this FilterValues state to target over a certa...
Definition digital_svf.h:114
poly_float v1
Typically the band or mid portion.
Definition digital_svf.h:81
poly_float v0
Additional mixing or amplitude value.
Definition digital_svf.h:80
poly_float v2
Typically the low or high portion.
Definition digital_svf.h:82
void reset(poly_mask reset_mask, const FilterValues &other)
Selectively resets values for voices specified by reset_mask, otherwise keeps the current values.
Definition digital_svf.h:100
void hardReset()
Resets all filter values to zero (for all voices).
Definition digital_svf.h:87
force_inline void increment(const FilterValues &delta)
Increments the filter values by the amounts specified in delta.
Definition digital_svf.h:127
poly_float * buffer
Pointer to the output buffer.
Definition processor.h:110
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600
static force_inline poly_mask vector_call lessThan(poly_float one, poly_float two)
Definition poly_values.h:1105
static force_inline simd_type vector_call min(simd_type one, simd_type two)
Returns the element-wise minimum of two SIMD float registers.
Definition poly_values.h:920
static force_inline simd_type vector_call abs(simd_type value)
Computes the absolute value of each element in the SIMD float register.
Definition poly_values.h:935
Represents a vector of integer values using SIMD instructions.
Definition poly_values.h:56
static force_inline uint32_t vector_call anyMask(simd_type value)
Returns a bitmask that indicates which bytes/elements in the register are non-zero.
Definition poly_values.h:352