Workflows + scripting
You know what the Recorder is and what it writes. Time for the real-world flows: the 30-second take, the DSP → sample round-trip, live-perf capture, and the MCP catalog with a multi-take chain.
The 30-second take
- Master Transport Widget → click the red Rec dot.
- Click Play (or just keep playing if already running). The capture starts from the moment Rec lit up.
- Let the loop run.
- Click Rec again to stop. The WAV writes to disk; a row appears in the Recorder panel.
The take lands in the rail panel — right rail → the Recorder icon. Three rows of preview / reveal / delete buttons.
The DSP → recording → sample round-trip
The killer pattern. Turn a synth voice into a sample-back texture without leaving FaustWave:
- Build a DSP — a poly-synth, a granular cloud, an FM pad.
- Record yourself playing it for 10–60 seconds.
- Re-import the recording into the sample-store.
- Drop a
soundfilenode in a new Builder + reference the imported sample. - Play the recording as a granular / looped / pitched sample-back instrument.
The sample sits keyed by sha256 — idempotent on re-import (same file twice = same entry). Lives alongside Builder graphs and KB-packs as a first-class project asset.
actions:
- action_id: recorder.start
input: {}
label: "▶ 1. Start recording the master"
- action_id: recorder.stop
input: {}
save_as: rec
label: "■ 2. Stop — returns the WAV path"
- action_id: samples.import
input:
file_path: "{{rec.path}}"
save_as: sample
label: "▶ 3. Import the recording into the sample store"
- action_id: documents.add
input:
type: builder
title: "Sample player"
save_as: b
label: "▶ 4. Spawn a fresh Builder"
- action_id: builder.graph.node.add
input:
module_id: "{{b.module_id}}"
kind: soundfile
save_as: sf
label: "▶ 5. Drop a soundfile node"
- action_id: builder.graph.node.ref.set
input:
module_id: "{{b.module_id}}"
node_id: "{{sf}}"
param: sha256
value: "{{sample.sha256}}"
label: "▶ 6. Bind the imported sample by sha"
More on the Builder side in FaustWave — Builder § 3 (Loading samples).
Capturing a live performance
The Recorder runs realtime — no faster-than-realtime bounce. For a 5-minute set:
- Press Rec.
- Set up your arrangement — the active slot per track, the sequencer key, the loop mode.
- Press Play.
- Perform for 5 minutes: live slot launches, scene swaps, param tweaks, mute/solo, master volume nudges.
- Press Rec to stop.
The file captures the actual realtime output including your live gestures. This is what "FaustWave as a live-performance instrument" means in practice — every gesture lands deterministically because the routing engine + the master clock + the dispatch path are all deterministic.
Capturing a parameter sweep
A scripted A/B comparison: same loop, different params. (Not a click-chain — the slot_id is YOUR reverb slot's id from master.fx.slots.list; ask the assistant to run the sweep against your rack.)
1. master.fx.slot.param.set { slot_id: "<your reverb slot>", param_name: "room", value: 0.1 }
2. recorder.start {}
3. sequencer.play {} ← one pass of your loop
4. recorder.stop {} → dry take path
5. master.fx.slot.param.set { slot_id: "<your reverb slot>", param_name: "room", value: 0.8 }
6. recorder.start {}
7. sequencer.play {}
8. recorder.stop {} → wet take path
Two takes, same source, different reverb. Compare via recordings.play or in your DAW after recordings.list + Reveal.
Common moves
- "Record only the next loop pass" — wait for the cursor to hit step 0, press Rec, wait one pattern length, press Rec. (
sequencer.stategives yousteps_per_patternandsteps_ms, so you can work out one pattern length.) - "Build up a take library of variations" — a chain that varies one param + records each variation. The library then has multiple sha-keyed sources you can A/B externally.
- "Mass-delete old takes" —
recordings.listthen iteraterecordings.delete { recording_id }filtered by date or size. No trash, no undo — confirm the filter before firing. - "Record while testing a Builder" — the Recorder runs even when no sequencer is playing. Hit Rec, click keys on the on-screen Keyboard, capture the doodle.
The full MCP surface
| Action | Purpose |
|---|---|
recorder.start | Begin recording. Idempotent re: already-recording (silent no-op). |
recorder.stop | End. Writes the file. Returns the WAV path. |
recorder.toggle | Flip start ↔ stop. The same action the UI button binds to. |
recordings.list | List the library (newest first). |
recordings.play { recording_id } | In-app preview. |
recordings.delete { recording_id } | Hard-delete. |
The Recorder has the smallest MCP surface of any major subsystem (6 actions) and the largest payload (the WAV file itself). Everything routes through one tap, one start, one stop — the simplicity is intentional.
What's not yet supported
Tracked, not delivered:
- In / out points — start at bar 3, stop at bar 11, quantized to bar boundaries.
- Auto-stop on a bar boundary — hit Rec, the engine completes the current loop and stops cleanly.
- Per-source dedicated taps — record one Builder dry without the routing dance.
- Faster-than-realtime bounce — render N bars as fast as the CPU can compute. Today recording IS realtime.
The Recorder is "barebones but reliable" today; the planned features are quality-of-life.
Where to go from here
- FaustWave — Builder § 3 (Loading samples) — the sample side of the round-trip.
- FaustWave — Mixer & Master § 1–2 — what's UPSTREAM of the Recorder tap (the strips, the FX rack).
- FaustWave — Patchbay § 4 — the routing.* primitives if you want to set up alternate taps.
- FaustWave — Getting Started § Your first recording — the 5-minute starter flow.