This is a gen~ implementation of the 2/4-pole mixing state-variable filter with variable saturation, based on the core filter implementation in the 2-Osc instrument for Reaktor 5.9. Resonance is not gain compensated at higher Q values.

Stage Variable Filter
Stage Variable Filter

Instead of implementing gain compensation inside the filter, you may wish to consider addingthe fast-response limiter on this site to reduce audio output to unity gain when the filter is self oscillating.

Design Notes

The SVF implementation uses param inputs for all the control signals. The design may be encapsulated and the param signals passed into a gen~ subpatch without increasing CPU utilization. To so so, pass the control signals into the subpatch with thesetparam object.

Passing param Values into a Filter Subpatch
Passing param Values into a Filter Subpatch

This SVF uses internal subpatches to simplify design and mortification. It was implemented in Max v6.1.8

SVF Top-Level Structure
SVF Top-Level Structure

Note:As of Max version 6.1.8, the samplerate object does not reissue a new value upon change of the audio driver to a new audio frequency until the patch is reloaded.

The upsampling and downsampling sections are similar. While it is possible to use gen~'sbuilt-in interpolation functions, this implementation calculates the upsample and downsample coefficients coefficients from constants, so they are only calculated once during initialization. The audio path only contains eight multiplies and six adds for the up and down stages, so besides instruction reordering, it is not possible for the up and down stages to be more efficient during run time.

3x Upsampling Stage
3x Upsampling Stage

For the filtering itself, the SVF subpatch is relatively simple, and repeated six times: the two sets of 2-pole filters, each repeated thrice for the upsampling, are identical.

2-Pole Filter Stage
2-Pole Filter Stage

The mixer block after each filter stage is also identical for each of the upsampling columns. In the first implementation, the mixer logic is repeated thrice as it was considered low overhead for control paths. Since the initial release, audio-rate modulation of control params has been requested, so this will be optimized on a subsequent release. The second-stage scan subobjects contain an additional control for emulating a 2/4 pole mix with dynamic mix-level control.

Dynamic LP/BP/HP and 2/4-Pole Mixing
Dynamic LP/BP/HP and 2/4-Pole Mixing

Zippering on param Inputs

The design implements gen~ params for filter controls to reduce CPU utilization. The param signals are not smoothed, because doing so converts the param signals to audio-rate signals which are recalculated on every audio clock cycle, increasing CPU utilization. If you experience zippering on param changes, because you are modulating the control signals outside ~gen, then you can add an interator to the required param inputs. The design will pass the audio-rate signals correctly without other modification. Here is an illustration of a simple integrator design.

Signal Smoothing with an Integrator
Signal Smoothing with an Integrator

This is the first in a series for the Cycling'74 community. Please check back for additional versions.

Version History

  • 9/20//2014: First implementation.
  • 9/22//2014: Optimized Mixer Control Path; encapsulated Filter Object; added optional smoother object

Download

A demonstration patch is available in the Synthcore2 bundle.

buy

Synthcore2 Bundle (Max7)

Cost: $5.00