ENGINE=filter · src/engine/filter/ · generated from filter.dsp + filter.json

A dual resonant filter - and the worked example of the parallel (DoubleMono) dual-deck generated path: one mono resonant low-pass kernel, run as two independent instances, deck A on the left channel and deck B on the right. Each deck has its own cutoff / resonance / drive / mix, and the two channels never interact. Authored as a Faust .dsp plus a JSON manifest with no hand-written C++ (the generator emits the wrapper on the shared FaustEngine<Traits> template, decks = 2). See docs/dev/engine-gen.md §9 for the dual-deck design and docs/engine-types/faust.md for the Faust path.


Controls

Dual filter control surface
Dual filter control surface - open full size download PDF

_Generated from docs/diagrams/controls/filter.json via make diagrams._

Each deck (A and B) carries the same four controls, addressing its own channel:

ControlParamIdFaust sliderEffect
PITCHSpeedcutofflow-pass cutoff (~40 Hz – 20 kHz)
POSPosresoresonance / Q
SIZESizedrivepre-filter saturation
SOSMixmixdry/wet

Deck A's knobs filter the left channel; deck B's filter the right. The crossfader is unused (the two decks are independent channels, not an A/B blend). The LED rings show a per-deck output-level meter.


Authoring (the parallel dual-deck path)

The whole engine is two files in src/engine/filter/:

{ "engine": "filter", "backend": "faust", "deck_mode": "parallel",
  "knobs": { "Pitch": "cutoff", "Position": "reso", "Size": "drive", "Mix (SOS)": "mix" },
  "features": { "meter": true, "color": "0xff8833" } }

Then:

make faust-engine MANIFEST=src/engine/filter/filter.json   # kernel + wrapper + build + diagram
make -j8 ENGINE=filter                                    # build (~83% SRAM_EXEC)
make engine-filter                                        # clean + build + DFU flash
make -C host test-filter                                  # host test (per-deck independence)

The kernel must be mono for DoubleMono (deck A=L, deck B=R). filter_engine.h and the generated kernel are checked in (a normal build needs no cyfaust); regenerate the wrapper with --force-glue.