Controller bindings, pads, and live effects
Modulation moves a parameter from inside the machine. A controller binding moves it from a hand — a pad, a knob, a hardware controller — and the two compose: the hand writes the base, the modulator swings around it.
Two kinds of binding
controller.bind.add binds one MIDI trigger to ONE target:
| Target | Input | Fires |
|---|---|---|
| Action | action_id + input | a note-on (type: "note") or a CC crossing 64 upwards (type: "cc") runs the action — sequencer.scene.launch { scene_id }, transport.stop, anything in the palette |
| Parameter | sink_id + path (+ min, max), CC only | the CC is followed continuously, 0..127 mapped into min..max (default: the parameter's own range), and written to the parameter's base |
channel is required — 1..16, or 0 = any channel. The demo puts its whole control map on channel 16 so it never collides with the instruments on 1–5; use 0 only when nothing else on that port sends the same number, since a hardware sequencer sharing the port would fire the binding on every step. The trigger must reach the Controller Actions sink (controller-actions:midi-in) — route your controller (or the Pads) onto it in the Patchbay; the cable is the enable switch.
actions:
- action_id: controller.bind.list
input: {}
label: "▶ Every binding in this project — action or parameter"
- action_id: midi.cc.map
input: {}
label: "▶ Who already listens to which CC (before you pick a number)"
Pads are an instrument
The Pads surface is a virtual controller on the bus — pads send notes, knobs and faders send CCs, buttons send a momentary max/min. It is a MIDI source like a hardware device, so everything above applies to it, and a hardware controller that sends the same numbers plays the same map. The demo's surface, 21 widgets:
- pads on channel 1/2 that play the Sample Kit and the 808 directly (a note into an instrument's
:midi-in); - knobs on channel 16 bound to parameters: CC 71 → the Earthquake macro's
value, CC 74 → the Hook Leadcutoff(base — the LFO keeps breathing around wherever the knob is); - buttons on channel 16 bound to parameters of a master insert: CC 80/81/82 →
stutter,brake,throwof the Live Pads slot; - pads on channel 16 bound to actions: five scenes and STOP.
actions:
- action_id: surface.open
input: { surface: faustwave-bundled/pads }
label: "▶ Open the Pads"
- action_id: pads.state
input: {}
label: "▶ The widget list with ids, numbers and channels"
The live-effects pattern: parameters, not MIDI
FX Live Pads.dsp in the demo is a master insert with a DJ filter, a beat-repeat stutter, a tape-stop brake, a bit crusher and a reverb throw — and it contains no MIDI at all. Every control is a plain slider:
filter = hslider("[0]filter", 0.5, 0, 1, 0.001) : si.smooth(ba.tau2pole(0.02));
stutter = hslider("[1]stutter", 0, 0, 1, 1);
brake = hslider("[2]brake", 0, 0, 1, 1);
bpm = hslider("bpm[bpm]", 130, 30, 300, 0.1); // the live tempo, for a stutter of exactly one eighth
Because they are parameters, the same DSP works from the Inspector, from a pads button through a binding, from a hardware controller through the same binding, and from a modulator through an edge — four hands on one knob, no code per hand. The binding for a button is one call:
actions:
- action_id: master.fx.slots.list
input: {}
label: "▶ Find the slot id and its parameter names"
then controller.bind.add { type: "cc", number: 80, channel: 16, sink_id: "pattern-live-pads", path: "/Live_Pads/stutter" } — the sink id is the slot's pattern-<slot_id>, the path the full Faust address (controller.bind.list shows the demo's thirteen). Three details that make it click-free: every gate inside the DSP is ramped (si.smooth) so a button press is not a step; the brake releases through a crossfade instead of snapping the delay line back; and the filter is a bit-exact bypass at its centre so "hands off" costs nothing.
What to try
- Open Perform, launch TRAP, hold Stutter on the pads for a beat, let go on the one.
- Turn Erdbeben to 0.6 — three 808 parameters move together; look at the Modulators pane while you do.
- Turn Hook Cutoff while the LFO breathes — you moved the base, the breath continues around it. That is the whole model.
- FaustWave — Pads — the widget types and EDIT mode.
- FaustWave — Patchbay & Routing § External clock sync and § MIDI Monitor — when a controller "does nothing".
- FaustWave — Mixer & Master § The Master FX rack — where an insert like Live Pads lives.