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.
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.
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 the
This SVF uses internal subpatches to simplify design and mortification. It was implemented in Max v6.1.8
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.
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.
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.
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.
This is the first in a series for the Cycling'74 community. Please check back for additional versions.
- 9/20//2014: First implementation.
- 9/22//2014: Optimized Mixer Control Path; encapsulated Filter Object; added optional smoother object
A demonstration patch is available in the Synthcore2 bundle.