# Patterns + scenes — the live-arrangement model

Everything you've done so far in the grid lives in ONE pattern per track. The pattern model lets each track carry up to **8 patterns** (labelled A..H by default, renameable), and **scenes** capture whole-sequencer pattern combinations — the same multi-track "chorus / verse / bridge" mechanic familiar from Ableton's Session view, with FaustWave's own quantize + launch semantics.

This is the live-performance layer of the Sequencer. Once you understand it, you stop "writing a long song" and start "writing a few short patterns and launching them in real time".

## Patterns — per-track variation

Each track has a **pattern bank**. A new track starts with 4 patterns; you can add up to 8 with `sequencer.pattern.add`.

On the track's chip there's a pattern launcher — A / B / … pads. Each pattern has three states the launcher distinguishes:

- **Active** — the pattern the engine is playing. One per track at a time.
- **Edit** — the pattern the piano-roll editor is showing. Independent from active — you can edit pattern B while the engine plays pattern A.
- **Pending** — a pattern that was launched while playing, but is still waiting for its quantize point. Visual pulse until the swap commits.

Click a pattern pad to **launch** it. The behaviour depends on transport state:

- **Stopped**: launch is **immediate**. Next `sequencer.play` starts in the launched pattern.
- **Playing**: launch is **queued** and commits at the pattern's launch-quantize boundary (default: next bar).

> 🔘 **MCP**: `sequencer.pattern.active.set { pattern_id, track_id?, instance_id? }` is the launch. Returns immediately even if the actual swap is queued.

Independently from launching, you can change which pattern the editor is showing without affecting playback:

> 🔘 **MCP**: `sequencer.pattern.edit.set { pattern_id, track_id? }` is a **view-only** change. Useful when you want to fill in pattern D while the engine plays pattern A — set the edit pattern to D, paint, set it back to A (or just launch D).

## Per-pattern launch quantize

Each pattern carries its own launch quantize — the boundary the engine waits for before committing the launch. Five values:

| Quantize | Commits at |
|---|---|
| `instant` | Immediately (no quantize). Use for fills. |
| `next-beat` | Next beat boundary (every 4 × 16ths). |
| `next-bar` (default) | Next pattern wrap. |
| `next-2-bars` | Every second pattern wrap. |
| `next-4-bars` | Every fourth pattern wrap. |

Stopped sequencer always commits immediately regardless of this value.

> 🔘 **MCP**: `sequencer.pattern.quantize.set { pattern_id, quantize, track_id? }`.

Mixing quantizes inside one sequencer is fine — a fill pattern at `instant`, your main verse / chorus at `next-bar`, a long-form variation at `next-4-bars`. The launcher visuals reflect the quantize so you can tell at a glance.

## Renaming patterns

Default labels are A..H (positional). Rename via right-click → Rename, or:

> 🔘 **MCP**: `sequencer.pattern.rename { pattern_id, label, track_id? }`. The pattern id is positional and unchanged — only the display label moves.

A / B / C / D works for sketches; "verse / chorus / bridge / fill" works for live sets.

## Removing patterns

> 🔘 **MCP**: `sequencer.pattern.remove { pattern_id, track_id? }`. Refuses on the last pattern (a track always keeps ≥ 1). If the removed pattern was active, edit, or pending, those references fall back to the first remaining pattern.

## Scenes — whole-sequencer combinations

A scene captures "which pattern is active on each track" as a single named handle. Launch a scene → every assigned track queues its scene's pattern (using each track's own per-pattern quantize). The combination commits at each track's next quantize point, so you can swap from "verse combo" to "chorus combo" with one launch.

### Building a scene

The usual flow: dial up a combination by launching patterns track-by-track, then save it:

> 🔘 **MCP**: `sequencer.scene.add { from_current: true (default), label? }` snapshots the current `activePatternId` of every track as the scene's assignments. Returns `{ ok, scene_id }`.

Default label = `Scene N`. Rename via:

> 🔘 **MCP**: `sequencer.scene.rename { scene_id, label }`.

### Launching a scene

> 🔘 **MCP**: `sequencer.scene.launch { scene_id }`. Queues each assigned track's pattern via the same pendingPatternId mechanism as `sequencer.pattern.active.set` (next-bar when playing, immediate when stopped). Tracks NOT in the scene's assignments are left untouched.

Sets `active_scene_id` so the panel highlights the active scene.

### Removing a scene

> 🔘 **MCP**: `sequencer.scene.remove { scene_id }`. If it was the active scene, `active_scene_id` clears.

## A live-perf chain

```yaml
actions:
  - action_id: sequencer.track.add
    input: { name: "Patterns demo" }
    save_as: t
    label: "▶ 0. Add a demo track (leaves your tracks alone)"
  - action_id: sequencer.pattern.add
    input: { track_id: "{{t.track_id}}" }
    save_as: chorus
    label: "▶ 1. Add a 'chorus' pattern to it"
  - action_id: sequencer.pattern.rename
    input:
      pattern_id: "{{chorus.pattern_id}}"
      label: "Chorus"
      track_id: "{{t.track_id}}"
    label: "▶ 2. Rename it 'Chorus'"
  - action_id: sequencer.pattern.quantize.set
    input:
      pattern_id: "{{chorus.pattern_id}}"
      quantize: next-2-bars
      track_id: "{{t.track_id}}"
    label: "▶ 3. Launch on a 2-bar boundary"
  - action_id: sequencer.pattern.active.set
    input:
      pattern_id: "{{chorus.pattern_id}}"
      track_id: "{{t.track_id}}"
    label: "▶ 4. Launch the chorus"
  - action_id: sequencer.scene.add
    input: { from_current: true, label: "All-Chorus" }
    label: "■ 5. Snapshot the current combo as a scene"
```

> 🟦 **HANDS-FREE PATH**: step 1 adds a new pattern; step 2 renames it; step 3 sets a 2-bar launch quantize so the user has enough time to react; step 4 queues the launch (it commits at the next 2-bar wrap when the engine is playing); step 5 snapshots the resulting state as a scene named "All-Chorus". Adapt to your own track/pattern ids from `sequencer.state`.

## When to scene vs launch directly

- **Just one or two tracks change at a section boundary**: per-track pattern launch is simpler. Fewer concepts in play.
- **Three or more tracks change at the same boundary**: scenes save the gesture. One launch → every track moves to its assigned pattern.
- **You need to A/B different combinations live**: scenes win — name them, launch them, return to neutral.

The Edit Pattern mechanic lets you fill in upcoming sections without disturbing what's playing. The combination + scene model lets you stage transitions cleanly.

## Perform mode — the layout for live

> 🔘 **MCP**: `surface.open { surface: "faustwave-bundled/sequencer#patterns" }`. UI: the **PATTERNS** button in the Sequencer header, or the Patterns row in the launcher.

Track cards, enlarged pattern pads, direct mute/solo, scenes — bigger touch targets and less visual noise. If you operate the Sequencer with one finger on a touchscreen or one hand on a controller, this is the surface you keep open; the roll can stay open next to it, or not.

Flip back to `edit` whenever you need to compose; the pattern bank survives unchanged.

Next section: the full MCP surface, with a multi-track build-from-scratch chain.
