DSPark 1.6.1
Header-only audio DSP framework in pure C++20 — zero dependencies
Loading...
Searching...
No Matches
StateVariableFilter.h File Reference

Topology-Preserving Transform (TPT) State Variable Filter. More...

#include "DspMath.h"
#include "AudioSpec.h"
#include "AudioBuffer.h"
#include "DenormalGuard.h"
#include <algorithm>
#include <array>
#include <cmath>
Include dependency graph for StateVariableFilter.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  dspark::StateVariableFilter< T >
 TPT State Variable Filter with simultaneous multi-output. More...
 
struct  dspark::StateVariableFilter< T >::MultiOutput
 Result struct for simultaneous multi-output processing. More...
 
struct  dspark::StateVariableFilter< T >::ChannelState
 

Namespaces

namespace  dspark
 Main namespace for the DSPark framework.
 

Detailed Description

Topology-Preserving Transform (TPT) State Variable Filter.

A 2nd-order multimode filter based on the Zavalishin/SVF topology. Produces lowpass, highpass, bandpass, notch, allpass, bell, low-shelf, and high-shelf outputs - all from the same structure, often simultaneously.

This is the fundamental building block for modular filter design. Unlike cascaded biquads, the SVF:

  • Is modulation-friendly (cutoff can change every sample without artifacts)
  • Provides simultaneous multi-output (LP + HP + BP in one processSample call)
  • Uses zero-delay feedback (no unit-delay in the loop)
  • Is numerically stable at all frequencies

Three levels of API complexity:

  • Level 1: svf.setCutoff(1000); svf.setMode(LP); svf.processBlock(buf);
  • Level 2: auto [lp,hp,bp] = svf.processMultiOutput(x, ch);
  • Level 3: Inherit, access g_/R_/ic1eq_/ic2eq_ for custom topologies.

References:

  • Zavalishin, "The Art of VA Filter Design" (2018), ch. 3-4
  • Simper, "Solving the continuous SVF equations using trapezoidal integration" (cytomic technical paper, 2013)

Threading: owner-managed. prepare/reset are setup-time; all setters and process calls belong to the owning audio thread (see the class note). processBlock installs a DenormalGuard; per-sample callers are expected to guard their own callback (framework convention) - resonant tails decay through the denormal range otherwise.

Dependencies: DspMath.h, AudioSpec.h, AudioBuffer.h, DenormalGuard.h.

// Level 1 - simple usage:
svf.prepare(spec);
svf.setCutoff(2000.0f);
svf.setResonance(0.5f);
svf.processBlock(buffer);
// Level 2 - multi-output (all 3 outputs at once):
auto [lp, hp, bp] = svf.processMultiOutput(sample, channel);
// Level 3 - per-sample modulation:
for (int i = 0; i < numSamples; ++i) {
svf.setCutoff(lfo.getNextSample() * 2000 + 500); // No artifacts
output[i] = svf.processSample(input[i], 0);
}
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.
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.
T processSample(T input, int channel) noexcept
Processes a single sample (selected Mode output).
void prepare(const AudioSpec &spec) noexcept
Prepares the filter.

Definition in file StateVariableFilter.h.