Pads — the composable controller surface
The Pads panel is an on-screen MIDI controller you can compose yourself: a list of widgets — pads, knobs, faders, buttons — each with its own MIDI mapping. It is a sender, nothing else: it produces exactly the bytes a hardware controller would, and everything it "does" is decided by whatever you route it to in the Patchbay. Master the virtual device and you have mastered the real one: when hardware arrives, re-route the same Patchbay edges from the pads-default source to the hardware input and nothing downstream changes.
Add it to the left rail via the + in the MIDI-sources area (same picker as Sequencer and Keyboard).
The widget types
- Pad — sends a note: press = note-on (velocity 110), release = note-off. For drums, triggers, and controller bindings.
- Knob — sends a CC as you turn it (a rotary knob in byte form: "controller N is now at value"). Rendered as the same audio knob every FaustWave parameter uses — drag vertically to turn it.
- Fader — same as a knob, rendered as a slider.
- Button — a momentary CC switch: press sends its
max, release sends itsmin. For sustain-style switches and CC-triggered bindings.
Each widget carries its own mapping: note/CC number, a channel (0 = follow the device channel set in the header chip; 1–16 = per-widget override, the way multi-engine controllers send per-section channels), a min..max range for CC widgets (limit a sweep to e.g. 20..100), and an optional label.
The default surface
A fresh Pads panel is pre-composed as a BeatStep-class device: 16 pads on notes 36–51 — the GM drum anchor (kick 36, snare 38, closed hat 42, open hat 46) that the bundled Drum Kit Electro and the C64 Drum Machine gate on — plus 8 knobs on CC 71–78 (the classic sound-controller block; CC 74 is the conventional filter cutoff/brightness). Route Pads → <drum instrument>:midi-in and the grid plays drums with zero configuration.
EDIT mode — composing your surface
The EDIT button in the panel footer opens the authoring layer:
- Add widgets with the per-type footer buttons (max 64).
- Click a widget to select it (amber outline) — its configuration opens as a popover right at the click point: number, channel, min/max for CC widgets, label.
- For CC widgets the popover has a MAP button — the project's CC map: which CC numbers already have a listener (a
midi_ccnode in a Builder DSP, a[midi:ctrl]-tagged slider in a .dsp source, a controller binding), what the standard name is (CC 1 Mod Wheel, 64 Sustain, 74 Brightness…), and the last value the bus saw on that CC. Click a row to assign it — no more guessing numbers. - Reorder with the popover's arrow buttons, remove with its trash button.
- Leave EDIT mode (or press Esc to dismiss the popover) and the surface is playable again.
The whole configuration persists with the project — your live-set surface travels in the project file, and a saved surface is the future device template (share a "my BeatStep layout" via the Hub — planned).
What a widget does NOT do
A widget only sends. It does nothing audible until a receiver listens:
- Notes → an instrument's
:midi-in(drums, synths) or the Controller Actions sink (controller.bind.addmaps notes to IDE commands — scenes, transport). - CCs → a
midi_ccnode in a Builder DSP or a[midi:ctrl N]-tagged slider in a .dsp source — see FaustWave — Patchbay & Routing § External clock sync & controller actions.
Silence from a knob means "no receiver has that CC number", not "broken" — the MIDI Devices panel's MONITOR shows every byte the surface sends ([Pads] ch1 CC CC 74 = 96) and settles the question in seconds.
Scripting (palette.run)
pads.state (read FIRST — widget ids) · pads.widget.add { type, number?, channel?, label?, min?, max? } · pads.widget.set { widget_id, … } · pads.widget.remove / pads.widget.move · pads.widget.value.set { widget_id, value } (turn a knob = send its CC) · pads.press { widget_id, velocity? } (press gesture with timed release) · pads.channel.set { channel } (releases held pads on the old channel first — no stuck notes) · midi.cc.map (the project CC map as text — who listens to which CC; read it before choosing a CC number).