Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::signal::OtaCascadeFilterT< SampleType > Class Template Reference

Voicing-neutral four-pole nonlinear cascade with fixed-storage oversampling. More...

#include <ota_cascade_filter.hpp>

Public Types

enum class  Mode { lowpass24 , lowpass12 , highpass4 , bandpass4 }
 Output tap combination selected from the shared four-pole cascade. More...

Public Member Functions

 OtaCascadeFilterT () noexcept
 Constructs a 44.1 kHz, 2x, 24 dB/octave low-pass filter.
void set_sample_rate (double sample_rate) noexcept
 Sets the base sample rate in Hz and resets all DSP history.
void set_oversampling (int factor) noexcept
 Sets the oversampling factor to 1, 2, 4, 8, or 16.
void set_pole_frequency (double pole_hz) noexcept
 Sets the one-pole corner frequency in Hz.
void set_resonance (double normalized) noexcept
 Sets normalized resonance in [0, 1].
void set_k_max (double k_max) noexcept
 Sets the non-negative maximum feedback coefficient.
void set_drive_db (double drive_db) noexcept
 Sets input drive in decibels, clamped to [-96, 72] dB.
void set_saturation_headroom (double headroom) noexcept
 Sets nonlinear-junction headroom, clamped to [0.25, 16].
void set_bias (double bias) noexcept
 Sets dimensionless asymmetric saturation bias, clamped to [-2, 2].
void set_compensation (double amount) noexcept
 Sets resonance-dependent passband compensation in [0, 1].
void set_output_gain (double gain) noexcept
 Sets a non-negative linear output-gain multiplier.
void set_cross_modulation (double depth, double drive=2.0) noexcept
 Sets nonlinear output cross-modulation.
void set_mode (Mode mode) noexcept
 Selects the output tap combination without resetting cascade history.
void set_smoothing_time_ms (double milliseconds) noexcept
 Sets the base-rate coefficient-smoothing time in milliseconds.
void set_drift (double cutoff_cents, double resonance_fraction, double cutoff_rate_hz=1.5, double resonance_rate_hz=0.0) noexcept
 Configures deterministic low-rate cutoff and resonance drift.
SampleType process (SampleType input) noexcept
 Processes one base-rate sample and returns one base-rate sample.
void process (SampleType *buffer, int num_samples) noexcept
 Processes num_samples base-rate samples in place.
void reset () noexcept
 Clears cascade and oversampler history while preserving configuration.
int latency_samples () const noexcept
 Returns the current round-trip oversampling latency in base-rate samples.
int oversampling () const noexcept
 Returns the active oversampling factor: 1, 2, 4, 8, or 16.
double sample_rate () const noexcept
 Returns the active base sample rate in Hz, after the 64 Hz floor.

Static Public Member Functions

static constexpr int latency_samples_for_oversampling (int factor) noexcept
 Returns round-trip FIR latency for an oversampling factor.

Detailed Description

template<typename SampleType = float>
class pulp::signal::OtaCascadeFilterT< SampleType >

Voicing-neutral four-pole nonlinear cascade with fixed-storage oversampling.

Configuration, reset, and processing are allocation-free and noexcept. An instance is suitable for an audio thread, but provides no synchronization; do not mutate it concurrently from another thread. SampleType selects the public sample type while internal state and coefficient calculations use double precision.

Member Enumeration Documentation

◆ Mode

template<typename SampleType = float>
enum class pulp::signal::OtaCascadeFilterT::Mode
strong

Output tap combination selected from the shared four-pole cascade.

Enumerator
lowpass24 

Four-pole low-pass response (nominal 24 dB/octave).

lowpass12 

Two-pole low-pass response (nominal 12 dB/octave).

highpass4 

Four-pole high-pass response.

bandpass4 

Four-pole band-pass response.

Constructor & Destructor Documentation

◆ OtaCascadeFilterT()

template<typename SampleType = float>
pulp::signal::OtaCascadeFilterT< SampleType >::OtaCascadeFilterT ( )
inlinenoexcept

Constructs a 44.1 kHz, 2x, 24 dB/octave low-pass filter.

Defaults are a 1 kHz pole, zero resonance, a 4.3 feedback ceiling, unity drive/headroom/output gain, zero bias/compensation/cross-modulation/ drift, and zero smoothing time. Coefficients start snapped to those targets. Construction allocates no memory.

Member Function Documentation

◆ latency_samples()

template<typename SampleType = float>
int pulp::signal::OtaCascadeFilterT< SampleType >::latency_samples ( ) const
inlinenoexcept

Returns the current round-trip oversampling latency in base-rate samples.

◆ latency_samples_for_oversampling()

template<typename SampleType = float>
constexpr int pulp::signal::OtaCascadeFilterT< SampleType >::latency_samples_for_oversampling ( int factor)
inlinestaticconstexprnoexcept

Returns round-trip FIR latency for an oversampling factor.

The result is expressed in base-rate samples: 1x -> 0, 2x -> 32, 4x -> 48, 8x -> 56, and 16x -> 60. Returns -1 for any invalid factor.

◆ oversampling()

template<typename SampleType = float>
int pulp::signal::OtaCascadeFilterT< SampleType >::oversampling ( ) const
inlinenoexcept

Returns the active oversampling factor: 1, 2, 4, 8, or 16.

◆ process() [1/2]

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::process ( SampleType * buffer,
int num_samples )
inlinenoexcept

Processes num_samples base-rate samples in place.

A null buffer or non-positive num_samples is a no-op. Otherwise this is equivalent to calling the scalar process() for each sample and is allocation-free.

◆ process() [2/2]

template<typename SampleType = float>
SampleType pulp::signal::OtaCascadeFilterT< SampleType >::process ( SampleType input)
inlinenoexcept

Processes one base-rate sample and returns one base-rate sample.

Advances smoothing, deterministic drift, FIR oversampling, and cascade state. The method is allocation-free and real-time safe for an instance exclusively owned by the calling audio thread.

◆ reset()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::reset ( )
inlinenoexcept

Clears cascade and oversampler history while preserving configuration.

Restores the fixed drift seed and zero drift state, then snaps all smoothed coefficients to their current targets. The next sample therefore begins the same deterministic drift sequence for identical settings.

◆ sample_rate()

template<typename SampleType = float>
double pulp::signal::OtaCascadeFilterT< SampleType >::sample_rate ( ) const
inlinenoexcept

Returns the active base sample rate in Hz, after the 64 Hz floor.

◆ set_bias()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_bias ( double bias)
inlinenoexcept

Sets dimensionless asymmetric saturation bias, clamped to [-2, 2].

The value becomes a smoothed target.

◆ set_compensation()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_compensation ( double amount)
inlinenoexcept

Sets resonance-dependent passband compensation in [0, 1].

Zero disables compensation and one applies the full feedback-dependent gain. High-pass mode intentionally remains at unity compensation.

◆ set_cross_modulation()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_cross_modulation ( double depth,
double drive = 2.0 )
inlinenoexcept

Sets nonlinear output cross-modulation.

depth is clamped to [-1, 1]; drive is clamped to [0.1, 16] and defaults to 2. Both are dimensionless smoothed targets. A zero depth disables the effect.

◆ set_drift()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_drift ( double cutoff_cents,
double resonance_fraction,
double cutoff_rate_hz = 1.5,
double resonance_rate_hz = 0.0 )
inlinenoexcept

Configures deterministic low-rate cutoff and resonance drift.

cutoff_cents is clamped to [0, 100]; resonance_fraction to [0, 0.1]; and cutoff_rate_hz to [0.05, 20] Hz. A positive resonance_rate_hz is clamped to [0.05, 40] Hz, while zero or a negative value makes resonance drift follow the cutoff rate. Both depths at zero disable drift and restore unity drift multipliers. Randomness is instance-local and reproducible after reset().

◆ set_drive_db()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_drive_db ( double drive_db)
inlinenoexcept

Sets input drive in decibels, clamped to [-96, 72] dB.

The corresponding linear gain becomes a smoothed target.

◆ set_k_max()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_k_max ( double k_max)
inlinenoexcept

Sets the non-negative maximum feedback coefficient.

Negative values become zero. The resonance target is recomputed as resonance * k_max without clearing DSP history.

◆ set_mode()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_mode ( Mode mode)
inlinenoexcept

Selects the output tap combination without resetting cascade history.

The compensation target is updated; high-pass mode forces unity compensation while selected.

◆ set_output_gain()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_output_gain ( double gain)
inlinenoexcept

Sets a non-negative linear output-gain multiplier.

Negative values become zero. The value becomes a smoothed target.

◆ set_oversampling()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_oversampling ( int factor)
inlinenoexcept

Sets the oversampling factor to 1, 2, 4, 8, or 16.

Any other value selects 2x. An effective factor change recomputes the internal rate and pole target and resets filter, FIR, smoothing, and drift state. Selecting the already-active effective factor is a no-op.

◆ set_pole_frequency()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_pole_frequency ( double pole_hz)
inlinenoexcept

Sets the one-pole corner frequency in Hz.

The value is clamped to [20, 0.45 * sample_rate()] at the base rate. Updates the smoothed coefficient target without clearing DSP history.

◆ set_resonance()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_resonance ( double normalized)
inlinenoexcept

Sets normalized resonance in [0, 1].

Values outside the range are clamped. The resulting feedback target is normalized * k_max; changing it does not clear DSP history.

◆ set_sample_rate()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_sample_rate ( double sample_rate)
inlinenoexcept

Sets the base sample rate in Hz and resets all DSP history.

Values below 64 Hz (including negative values) become 64 Hz so the mandatory 20 Hz pole floor remains below the Nyquist-derived ceiling. Recomputes the internal oversampled rate, smoothing, and pole target.

◆ set_saturation_headroom()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_saturation_headroom ( double headroom)
inlinenoexcept

Sets nonlinear-junction headroom, clamped to [0.25, 16].

The value is dimensionless and becomes a smoothed target.

◆ set_smoothing_time_ms()

template<typename SampleType = float>
void pulp::signal::OtaCascadeFilterT< SampleType >::set_smoothing_time_ms ( double milliseconds)
inlinenoexcept

Sets the base-rate coefficient-smoothing time in milliseconds.

Negative values become zero; zero snaps controls to their targets on the next processed sample. This changes smoothing behavior without immediately snapping coefficients or clearing DSP history.


The documentation for this class was generated from the following file: