# Your first instrument (5 minutes)

```yaml
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.

> 🟦 **HANDS-FREE PATH**: the Action buttons above build + save the Builder — Spawn → Add osc → Add output → Wire → Save. The last two steps that make it audible — **"+ ADD AUDIO"** (route it onto a MixerTrack) and **Play** — are walked in the prose below; "+ ADD AUDIO" is a UI picker over your project files (its MCP mirror is `mixer.tracks.input.set`, see **FaustWave — Reference**), and Play is `transport.play {}`.

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.

> 🟦 **WHY A PROJECT?** A FaustWave project is a folder on disk that holds your instruments, your samples, your sequencer state, and the routing between them. Everything auto-saves to the active project, so there's no Cmd+S anxiety. You can have many projects; switch between them from the project pill in the topbar.

## 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.

> 🔘 **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`).

> 🔘 **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.

> 🟦 **NEW TO DSP?** A node in the Builder represents one Faust expression. The Osc node is essentially `os.osc(freq)` — Faust's sine oscillator with a frequency input. The `freq` knob you drag is a Faust `hslider` that gets wired into the compiled source. There's no plugin host, no MIDI mapper, nothing between you and the math.

## Step 3 — Add an output

Right-click the area to the right of your osc, search `output`, pick **Output**.

> 🔘 **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.)

> 🔘 **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.

> 🟦 **CABLE COLOURS**: cyan = audio, purple = control / parameter, orange = MIDI trigger. You'll learn to read these at a glance — see **FaustWave — Builder** § 1 *Cables* for the full palette.

## 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.

> 🔘 **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.

> 🟦 **WHY THE EXTRA STEP?** FaustWave doesn't auto-route every Builder to the master — you decide what's in the mix, like adding a track in a DAW. Open a DSP to work on it; **"+ ADD AUDIO"** it when you want to hear it. Once attached, the route is remembered — re-opening the DSP restores it. (MCP mirror: `mixer.tracks.input.set`.)

## 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.

> 🔘 **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.

> 🔘 **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:

1. **Walked your graph** (`osc → output`) and generated Faust source. Roughly:
   ```faust
   process = os.osc(hslider("freq", 440, 20, 20000, 0.01)) <: _, _;
   ```
   A stereo sine.
2. **Sent that source to the Faust compiler** (running in a Web Worker, libfaust under the hood), which produced WebAssembly bytecode.
3. **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.run` entry. 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_note` nodes (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 `gain` node between osc and output and an `adsr` envelope — start sculpting the sound. See **FaustWave — Builder**.
- Add a `midi_note` node + 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**.
