Fredemus / va-filter

Nonlinear models of analogue filters implemented as a plugin in Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

va-filter

Virtual analogue filters. implemented as a VST3 and Clap plugin in Rust, using Vizia for the GUI and nih-plug for all the plugin boilerplate stuff.

circuits

This plugin currently has 3 circuit models:

Transistor ladder filter

This is a 4-pole lowpass ladder filter loosely based on the ones found in Moog synthesizers. It distorts nicely and is capable of stable self-oscillation when k_ladder==4, and can output other slopes too.

Resonance is limited by the differential BJT buffers.

It converges very well, usually only taking 2 iterations, and almost never more than 4. Could just always do 2, especially when oversampled.

Circuit solved by applying KCL, finding the jacobian of the entire system and then applying newton's method.

State-variable filter

This is a 2-pole multimode filter loosely based on the one found in the edp wasp synthesizer. It's a good all-around filter that distorts nicely and keeps resonance well at high levels.

It's capable of outputting all basic filter modes (lowpass, highpass, bandpass, notch, etc.) and self-oscillation.

OTA core, nonlinear op-amp buffers. The EDP wasp uses inverters as a weird extremely nonlinear op-amp buffer, but I haven't looked into how to model that (in a way that converges well) yet. Resonance is limited by a diode clipper on the damping feedback, boosting it when gain is high, since it'd otherwise disappear because of the opamp nonlinearities, which would lead to the resonance completely dominating the signal.

Its convergence is generally good. The convergence gets a lot better when oversampled 2x or more, which I recommend anyway since it distorts.

Circuit solved by Holters & Zölzer's generalization of the DK-method. This method has a lot of advantages compared to the other approach, namely it's much better equipped for handling nonlinear voltage-controlled voltage sources such as op-amps and jacobian matrices are only necessary on a per-component basis, meaning it's not necessary to solve the whole system each iteration, speeding up iterations significantly. Special thanks to Martin Holters and his amazing circuit emulation tool ACME for the great work on circuit emulation and answering my questions when I got stuck.

The fast version is optimized by removing unnecessary operations and replacing the general solver with an analytic solution of the specific model. At some point I'll look into how a simd-optimized version would compare, since most of the operations are dot products anyway, but the current fast version is definitely fast enough for real-time use in DAW projects. Sadly convergence varies too much for using simd-lanes for processing left and right at the same time to bring a big performance benefit.

Sallen-key filter

This is a 2-pole lowpass filter loosely based on the one found in the second revision of the Korg MS20 synthesizer. It distorts really nicely and gets especially gnarly when resonance is high. My personal favorite.

It's able to self-oscillate and starts doing so when its resonance is above 0.8.

OTA core, nonlinear op-amp buffers. Resonance is limited by a diode clipper, but it disappears quite quickly at high drives.

Its convergence is generally good, but it does get a bit slower at high drives. The parameter vector for the nonlinear contributions is just 2 entries long, meaning that it might be reasonable to create a lookup table to guarantee stable, fast runtime. <- not as reasonable as I thought, also needs entries for g and res

Circuit solved by Holters & Zölzer's generalization of the DK-method.

The fast version is optimized by removing unnecessary operations and replacing the general solver with an analytic solution of the specific model. At some point I'll look into how a simd-optimized version would compare, since most of the operations are dot products anyway, but the current fast version is definitely fast enough for real-time use in DAW projects.

Build Instructions

The plugin uses simd operations which requires you to build it with nightly rust.

To build the plugin:

cargo +nightly xtask bundle -p va-filter --release

The plugin is then saved in the target/bundled folder

A standalone version can be run in jack:

cargo +nightly run --release

About

Nonlinear models of analogue filters implemented as a plugin in Rust

License:GNU General Public License v3.0


Languages

Language:Rust 99.0%Language:CSS 1.0%