The Patchbay matrix
The routing table from § 1 has a UI: the Patchbay rail panel renders the routing table as a JACK-style Sources × Sinks matrix. One row per Source, one column per Sink, and a cell at every intersection where a connection is possible.
Opening it
actions:
- action_id: patchbay.toggle
input: { open: true }
label: "▶ Open the Patchbay"
Click the Patchbay icon in the left rail (the cable icon) — or the button above. The panel opens at the right edge of the rail.
The footer shows the current connection count (e.g. 7 connections), so you can tell at a glance whether your project is sparsely wired or full of routing.
Reading the matrix
The matrix splits cleanly into two zones:
- Audio block (top-left) — audio Sources × audio Sinks.
- MIDI block (bottom-right) — MIDI Sources × MIDI Sinks.
- The off-diagonal quadrants (audio Source × MIDI Sink and vice versa) are greyed out — kind-mismatched cells can't connect, by construction.
A cell has three possible states:
| State | Meaning | Click does |
|---|---|---|
| Greyed out | Kind-mismatched (audio × MIDI). | No-op. |
| Empty hollow | Compatible kinds, NOT currently connected. | Creates the connection. |
| Filled (cyan for audio, purple for MIDI) | Currently connected. | Disconnects. |
Row + column headers use the entity's label (e.g. "Builder: bass-acid-303.builder", "Track: Bass") so you don't need to read raw module ids. The kind icon (audio waveform vs music note) sits next to each header for a quick scan.
V1 takes the first port
Most Sources expose a single out port; most Sinks a single in. The matrix V1 takes the first declared port of each entity as the canonical one, so each Source / Sink gets exactly one row / column:
- Builders / Faust DSPs use
out. - Master + Recorder use
inon the Sink side,outon the Source side. - Send slots (when present) use
send-in. - An installed instrument exposes one MIDI port (
in) AND a modulation port per param — the matrix V1 doesn't render the per-param modulation column (userouting.connectfrom the MCP side, or the Modulators panel UI).
Multi-port matrices (one column per port for entities that expose several) are a future polish; today the matrix is one row / one column per entity.
Making + breaking a connection
Three real-world tasks, one click each:
Sending a Builder to the mixer
The normal way is the Master panel's "+ ADD AUDIO" picker — it creates a MixerTrack and wires the Builder into it in one step. In the matrix you can do the same by hand: open the Builder, wait for its source to appear, then click the cell at (Builder row, <track>:in column) in the audio block (a track must exist first). The cell fills cyan; the Builder now feeds that track, which sums into master.
A Builder does not auto-wire to master on its own anymore — opening/running it only registers the Source. You attach it to a MixerTrack explicitly (via "+ ADD AUDIO" or the matrix). Once attached the route persists across re-opens.
Routing the Keyboard to your own Builder
Your Builder uses a midi_note node (so it accepts MIDI in). Find the Builder in the MIDI block as a Sink — it appears once the midi_note node binds. Click the cell at (keyboard-default row, your-Builder column). The cell fills purple. Pressing a key on the Keyboard now drives your Builder, alongside any other sink keyboard-default is wired to.
Disconnecting a hung wire
A filled cell stays connected even when its underlying entity is gone (e.g. if you closed the project before disconnecting). Re-open the project, click the still-filled cell, the wire's gone. Routing-engine reconciliation handles this without ceremony.
What the matrix DOESN'T show
A few routing-table features live outside the V1 matrix:
- Per-cable gain — the matrix is a Boolean on/off editor. Adjust audio connection gain via the Mixer panel (one fader per Source-to-master connection) or via
routing.set { connection_id, gain }from MCP. - Modulation cables — the per-param modulation Sinks aren't columns in V1. Use the Modulators panel (LFO bind UI) or
routing.connect { kind: "modulation", amount: ... }. - Cable suspend (enabled flag) — no UI hook in V1.
routing.set { connection_id, enabled: false }to mute a wire without removing it; useful for A/B comparisons.
If you find yourself wanting any of these as a click, file an issue on the project — the V2 matrix is on the roadmap once the V1 UX has soaked.
The audible-consumer hint, revisited
When the matrix has zero audio paths reaching master (or every reaching MixerTrack is muted), the Mixer panel surfaces a Smart Mute Hint badge. It's the matrix's quiet way of telling you "you're playing but no path will be heard". Common cause: you haven't added the source to a MixerTrack yet ("+ ADD AUDIO"), or every track is muted.
Activity gets every edit
Every click in the matrix routes through api.actions.run('routing.connect' | 'routing.disconnect'), so the Activity rail panel (right side) shows each connect / disconnect as a discrete log entry. Useful for:
- Auditing what just happened — if a colleague (or the AI) was wiring and you want to see the trail.
- Spotting a misclick — if you accidentally disconnected something, Activity shows the previous connect + the rogue disconnect, ready to recreate.
Next section: the differences between audio, MIDI, and modulation cables — gain, amount, the enabled flag, and which one to reach for.