Your first instrument (5 minutes)
actions:
- action_id: documents.add
input:
type: builder
title: "My first instrument"
save_as: b
label: "▶ 1. Spawn a Builder"
- action_id: builder.graph.node.add
input:
module_id: "{{b.module_id}}"
kind: osc
x: 80
y: 120
save_as: osc
label: "▶ 2. Add an oscillator"
- action_id: builder.graph.node.add
input:
module_id: "{{b.module_id}}"
kind: output
x: 320
y: 120
save_as: out
label: "▶ 3. Add an output node"
- action_id: builder.graph.connect
input:
module_id: "{{b.module_id}}"
source_node_id: "{{osc}}"
target_node_id: "{{out}}"
target_port: in_l
label: "▶ 4. Wire osc → output"
- action_id: documents.save
input:
module_id: "{{b.module_id}}"
label: "▶ 5. Save it into the project"
By the end of this chapter you'll hear a sine wave you wrote by wiring two nodes. That's intentionally trivial — the same workflow scales to a full polyphonic synth or a guitar amp simulator. We start small so you learn the gestures.
Every step below also lists the MCP action behind it (action_id { input }). You can ignore those on a first read — they're there so a future reader running this as a playable Book tutorial sees the same actions a click would fire, and so anyone driving FaustWave from Claude Desktop knows what to call.
Open FaustWave
When the app boots you land on the workspace. The Documents rail icon (top of the left rail — it looks like a stack of papers) has three sections: OPEN (the document tabs open right now), PROJECT (every file saved in your project — click to open, trash to delete), and NEW (spawn a fresh module).
If you've never opened FaustWave before, you have an empty project (FaustWave generates a project name automatically — typically something like A-AAA-1). That's fine — we'll create our DSP directly here.
Step 1 — Start a Builder
Click the Documents rail icon. Under the NEW section, click Builder. A new Builder tab opens with an empty canvas.
For AI & automation · MCP
documents.add { type: "builder" }
The Builder is FaustWave's visual graph editor. You drop nodes, you wire them, and the Builder generates Faust source from your graph in real time. You can see the generated source any time via the canvas right-click menu → Show Faust source.
Step 2 — Add an oscillator
Right-click anywhere on the canvas. A node picker opens at your cursor. Type osc in the search box and hit Enter — or scroll down to the Source category and pick Osc.
You should see a single oscillator node on the canvas with one knob (freq, default 440 Hz) and one output port (out).
For AI & automation · MCP
builder.graph.node.add { module_id: <your builder id>, kind: "osc" }
Click the freq knob and drag up or down. The value changes in real time but you don't hear anything yet — the oscillator is unconnected. Sound flows from your nodes through an Output node, which is what writes to the master mixer.
Step 3 — Add an output
Right-click the area to the right of your osc, search output, pick Output.
For AI & automation · MCP
builder.graph.node.add { module_id, kind: "output" }
The Output node has paired stereo inputs (in_l + in_r; a mono signal into in_l fans out to both channels) and represents the DSP's audio out — it makes the Builder a routable audio Source. It does NOT reach the speakers on its own yet: you add the DSP to the mixer in Step 6 (the Builder routes into a MixerTrack, which routes to master). See FaustWave — Mixer & Master for the tracks + master FX + master meter that sit downstream.
Step 4 — Connect them
Click the out port on the right side of the Osc node, drag your mouse to the in_l port on the left side of the Output node, release. A cyan line (a "cable") appears between them. (Mono into in_l reaches both speakers — in_r is for true-stereo instruments.)
For AI & automation · MCP
builder.graph.connect { module_id, source_node_id: <osc id>, target_node_id: <output id>, target_port: "in_l" } — ports default to out → in, but the Output node's inputs are in_l/in_r, so name the target port. When unsure about a kind's port ids, builder.kind.describe lists them.
Step 5 — Save it
Before it can reach the speakers it has to be a project file — the mixer's "+ ADD AUDIO" picker lists project files. From the Builder's footer, click the Save icon (disk). The DSP saves to your active project's assets/ folder as untitled-XXXX.builder (FaustWave generates a unique suffix). It now appears under PROJECT in the Documents panel and auto-saves from here on.
For AI & automation · MCP
documents.save { module_id }
Step 6 — Add it to the mixer
A Builder's Output node makes it a routable Source, but nothing reaches the master until you put that source on a MixerTrack. Open the right-side Master Control panel (Sliders icon in the topbar, or via the Outputs rail) and click "+ ADD AUDIO". Pick your just-saved DSP. FaustWave attaches its output to a MixerTrack — auto-creating one named after the DSP — so its audio finally has a path to the master bus and your speakers.
Step 7 — Play it
Two ways. Either:
A) Press Play in the master Transport Widget at the top centre — the big play arrow next to the BPM display. This starts the global transport, which all transport-following modules (your Builder among them) wake up to. You should hear a steady sine wave at 440 Hz.
For AI & automation · MCP
transport.play {}
B) Press the local RUN button in the Builder's footer (bottom right of the Builder panel). This starts only your Builder; the global transport stays stopped. Useful for soloing a single DSP while everything else stays quiet.
For AI & automation · MCP
dsp.run { module_id }
Stop the same way (Play → Stop, RUN → STOP).
Drag the freq knob while the DSP is running — the pitch follows your finger. You just wrote, compiled, routed, and played your own DSP code.
What you actually did
When you clicked Play, FaustWave:
- Walked your graph (
osc → output) and generated Faust source. Roughly:
A stereo sine.process = os.osc(hslider("freq", 440, 20, 20000, 0.01)) <: _, _; - Sent that source to the Faust compiler (running in a Web Worker, libfaust under the hood), which produced WebAssembly bytecode.
- Loaded the bytecode into an AudioWorklet running on the audio thread, wired the worklet's output through the MixerTrack you added in Step 6 → the master bus → your output device.
You can inspect each step:
| What | How |
|---|---|
| The graph | Visible on the canvas. Click the </> button in the Builder toolbar to copy the live Faust source to your clipboard — paste anywhere. |
| The compiler | Open the Faust Compiler rail panel — compile history + time per compile |
| The routing | Open the Patchbay rail panel — see your Builder's output → its MixerTrack → master → speakers in the live audio routing table |
Troubleshooting
I clicked Play but I hear nothing.
- Did you "+ ADD AUDIO" the DSP? This is the #1 cause. A Builder that's open + running is NOT on the mixer until you add it (Step 6). No track = no path to master = silence. Open Master Control and check there's a track for your DSP.
- Check the Master Volume on the right-side Master Control panel — if it's at 0, raise it.
- Check your DSP's MixerTrack — make sure it's not muted, and that another track isn't soloed (solo wins over mute).
- Check your OS audio device. The Audio Inputs rail panel (left) and Audio Outputs rail panel (right) show the devices FaustWave is using; if you plugged in headphones after launch, re-select the output device in Audio Outputs.
- Check the master meter at the top of the Master Control panel — if it's lit up but you hear nothing, the audio path is fine and the problem is OS-side.
The Run button shows "Run failed".
- Open the Activity rail panel (right rail) and look for the failed
dsp.compile/dsp.runentry. The actual compile error or runtime error is in the entry's result. - Most common: a graph with no Output node (nothing to route to), or a poly-mode DSP with multiple
midi_notenodes (only one allowed).
The freq knob doesn't move.
- Audio engine might not be running. Click Play first, then drag.
- The knob is bound via
setParamValue— if the worklet isn't compiled yet, changes are staged but not audible until the next run.
Where to go from here
- Add a
gainnode between osc and output and anadsrenvelope — start sculpting the sound. See FaustWave — Builder. - Add a
midi_notenode + connect a MIDI keyboard or the on-screen Keyboard → your osc plays per note. Continue to § Your first pattern in this book. - Tap the DSP into the sequencer to drive it from a step grid. See FaustWave — Sequencer.