Backing tracks
80% of MT cabarets, tours, and school productions run backing tracks for orchestral parts the live band can’t cover. Backing tracks are the second-biggest MainStage gap after sandboxing. v0.13.0 closes it.
Why “a play button on a patch” is wrong
The naive design is to put a play button on a patch. It’s wrong. Backing tracks aren’t patches — they’re a per-song resource with a transport, and patches interact with the transport rather than being the transport.
Counterexample: a single song has 4 patches the keyboardist switches between, all over one continuous orchestral track. The transport is one thing; the patches are four things. The transport doesn’t restart when a patch changes.
So the data model treats tracks as song-level, and patches as opt-in interactors with the transport.
Data model
// Song gains:tracks: Track[]transport: SongTransport
Track { id, label, file, stemType: "click" | "guide" | "orchestral" | "vocal" | "fx" | "custom", busOutput: BusId, gain, pan, mute, startOffsetMs: number // negative = pre-roll}
SongTransport { bpm, timeSignature, cuePoints: { id, label, positionMs }[], followClick: boolean // if true, click is master tempo for band — sends MIDI clock}
// Patch gains optional:transportTriggers: TransportTriggers
TransportTriggers { onEnter: "none" | "play" | "pause" | "stop" | "jumpToCue:<cueId>" onExit: "none" | "pause" | "stop" | "fadeOut:<ms>"}The workflow
A walk-through of using backing tracks for one song.
- Setup → Show Settings → Buses — configure FOH (stereo 1–2), IEM-click (mono 3), IEM-band (stereo 4–5)
- Program → Song → Tracks tab — drop in
click.wav,orch.wav,guide.wav. Assign click to IEM-click bus, orch to FOH, guide to nothing (mute default) - Program → Song → Cue points — scrub orch track, mark “Verse 1”, “Chorus”, “Bridge”, “Vamp out”
- Program → Patch (first patch of song) — in Settings, set
onEnter: playso transport starts when patch is selected - Program → Patch (vamp patch) — set
onEnter: jumpToCue:vampso selecting it during an extended vamp resyncs - Perform → Layout — add Transport widget (play/pause/stop/position/cue jump dropdown) and per-track Mute widget so MD can mute guide vocal mid-song
- Live — hit first patch, transport rolls. Switch patches as needed (transport keeps playing). Hit vamp patch during extended scene — transport jumps to vamp cue. Bridge patch’s
onExitfades out orch over 4 seconds
Per-song tracks tab
The song’s Backing sub-tab is a per-track row editor:
| Column | What |
|---|---|
| File | Path to audio file, drag-drop supported |
| Label | Display name in transport widget |
| Stem type | Click / guide / orchestral / vocal / FX / custom |
| Bus output | Which bus this track routes to (defaults vary by stem type) |
| Gain | Per-track gain trim (dB) |
| Pan | Per-track pan |
| Mute | Boolean |
| Start offset | Sample-accurate offset from song start (negative = pre-roll) |
A song can have any number of tracks. Common shape: 4–8 stems + a click.
Audio decoding
Pure-Rust via symphonia:
- mp3
- wav (PCM 16 / 24 / 32-bit)
- flac
- ogg vorbis
Sample rates and channel counts mismatched against the engine are converted on load (cubic resample) — not on the realtime path.
Song transport
A first-class engine concept (introduced for click in v0.8.0, extended for tracks in v0.13.0):
- Play / Pause / Stop / Seek
- Position (bar:beat or seconds)
- Sample-accurate cue jump — decode forward seek
- MIDI clock sync — clock send tracks the transport BPM, song-level (not per-track)
The transport panel in Program mode lets you scrub during authoring; in Perform mode, the transport widget exposes play/pause/jump plus the position display.
Patch transport triggers
Optional per-patch hooks:
onEnter— when this patch becomes active, fire a transport command (play / jump-to-cue / etc.)onExit— when this patch becomes inactive, same
Off by default. When on, they make patch advances ↔ track positions a coupled system; powerful but error-prone in performance, so it’s opt-in per patch.
Vamp interplay with the click track
Vamps in the click track (authored in v0.12.0) are regions of time that loop. With backing tracks:
- A vamp region in the click track also loops the transport over the same region
- A footswitch action “end vamp at next loop point” marks the vamp as “exit at the next bar boundary”
- The transport completes the current loop and proceeds past the vamp’s end marker
- Patches can subscribe to the “exit vamp” event for auto-advance
This makes “vamp until the conductor cues end” a usable workflow without the MD mashing a button at a specific bar.
MIDI recording + audio bounce (same version)
Coupled with backing tracks because the infrastructure overlaps.
What’s cheap (ships v0.13.0):
- MIDI capture from rig → write to song track: ~3 days (engine already captures MIDI)
- Audio bounce (render MIDI through patches to audio file): ~1 week (uses the offline-render plumbing built for the balance tool)
- Multi-take support: ~3 days
What’s expensive (deferred to v1.x):
- Piano-roll editor (note grid, drag/drop, velocity edit, quantize, swing): ~3–4 weeks basic, 8+ production-quality
- Timeline editor (audio waveform display, region edit): ~3 weeks
v0.13.0 ships: record MIDI → bounce to audio. v1.x: piano roll.
Why it matters: an MD can record an orchestra part live in Pit (playing through their patches), bounce it to an audio file, and use the result as a stem in the same show. Positions Pit as more than a host — a lightweight production environment for MT pit work.
What this gets you over MainStage Playback
- Patches drive transport — not a separate Playback plugin. Feels native.
- Cue points tied to patches let you handle vamps / codas / conductor variations cleanly
- Per-bus stem routing is first-class — MainStage requires manual channel-strip plumbing
- MIDI recording + bounce in the same app — no DAW round-trip needed for ad-hoc stems
Bundle file format migration (same version)
Backing tracks force the file-format issue. Audio files don’t belong inline in JSON; they belong as assets. v0.13.0 migrates from single .stardustshow JSON file to the .stardustshow/ bundle directory:
my-show.stardustshow/├── show.json├── libraries/├── assets/│ ├── audio/ # backing track stems│ ├── images/│ └── samples/└── thumbnails/Opt-in .zip export for sharing. Old single-JSON shows migrate cleanly on first open.
See Patch library for the bundle structure details.
What’s deferred
- Real-time time-stretching to follow a conductor with tracks — v2.0+
- Full DAW MIDI import — multi-track SMF → click + per-instrument tracks. v1.x
- Track stem mixing UI in Perform mode beyond basic per-track mute — the full mixer is v0.10.0’s Pit Mixer
- Piano-roll editor for recorded MIDI — v1.x
Related pages
- Click track editor
- Pit Mixer
- Cue system
- Balance tool — shares the offline-render plumbing