All books

The Patchbay matrix

~4 min read · updated 2026-08-21 · markdown

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:

StateMeaningClick does
Greyed outKind-mismatched (audio × MIDI).No-op.
Empty hollowCompatible 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 in on the Sink side, out on 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 (use routing.connect from 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.

Try it yourself — the IDE runs in your browser. Open the IDE → Get the desktop app

Text licensed under CC BY 4.0 — Mani Weber / FaustWave. For language models: llms.txt · llms-full.txt

AUDIO · 48k · 48.0ms FAUST · 3 KB · 1171 docs CPU · 8.4% BPM · 120.0 UTF-8 BETA· v0.90.0