Live Workflow
Live coding in resonon is a conversation with a running session. You start with a blank runtime and build it up: set up a track, load an instrument, send it a pattern, hit play. Then you keep going — swap the pattern, add a layer, tweak a parameter — and hear each change without ever stopping the music. This page is about that loop: how edits land in time, how the transport behaves, and how to keep an eye on what’s playing.
If your editor isn’t connected yet, set that up first in
VSCode Extension. Everything here works the same
from the editor’s Cmd+Enter or the REPL.
Building a Session
Section titled “Building a Session”Here’s a whole starting point — a track, an instrument, a beat, and playback:
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.instrument(Sampler(Kit("CR-78")));drums << [bd sd bd sd];
PLAY;The runtime remembers all of this. The next time you evaluate code, drums
still exists — you don’t redefine it, you talk to it. That persistence is the
whole point of the live workflow: you grow a piece one evaluation at a time
instead of re-running a file from scratch.
Quantized Swaps
Section titled “Quantized Swaps”Now change the beat. With the session still playing, evaluate a new pattern for the same track:
drums << [bd _ sd _, hh hh hh hh];You won’t hear the swap happen mid-bar. A new pattern takes effect at the next cycle boundary — the current cycle finishes, then the new one starts. This is what keeps live edits musical: you can evaluate whenever you like and trust that the change lands on the downbeat, in time, never halfway through a note.
Because the swap is quantized and the session persists, the everyday rhythm of
live coding is: tweak the line, evaluate, listen, repeat. Layer more tracks the
same way — each is just another AudioTrack you send patterns to.
Changing the Rig, Not Just the Notes
Section titled “Changing the Rig, Not Just the Notes”Patterns aren’t the only thing you can swap mid-session. A track’s structure — its instrument, its effect chain, where it routes — is described the same declarative way, so re-evaluating the lines that build it makes the live graph match what you just wrote:
use "std/effects" { Lowpass, Delay };
drums.fx(#[Lowpass("lowpass", 4000)]);drums.fx(#[Lowpass("lowpass", 4000), Delay("delay", 0.25, 0.4)]); // delay inserted, filter untouchedAdd an effect to the array and it’s inserted; delete one and it’s removed; move
one and the chain reorders. Effects you left alone keep their live instances, so
their parameter values and any running modulation survive the edit. The same
holds for the track itself and for its instrument: AudioTrack("drums") returns
the track you already have, and re-attaching the instrument you already loaded
preserves it.
The upshot is that structural edits belong in the same loop as pattern edits.
You don’t need RESET; to add a plugin or re-order a chain — that’s the point of
writing the rig as a layout.
Transport Controls
Section titled “Transport Controls”Transport is the session-wide play head. You can drive it from code or, in the editor, from the keyboard.
| Action | Code | Keybinding |
|---|---|---|
| Play | PLAY; | F5 |
| Pause | PAUSE; | F5 (toggle) |
| Stop | STOP; | Shift+F5 |
| Reset | RESET; | Ctrl+Shift+F5 |
PLAY; // resume playback from where the play head sitsPAUSE; // pause where you are — sound stops, position is keptSTOP; // stop and return to the start; a third STOP kills all soundRESET; // wipe the whole session and start from a blank runtimeThe four differ in how much they tear down:
PLAYresumes playback. The play head picks up wherever it was paused, and cycle-based code is primed so it’s ready the instant the transport rolls.PAUSEstops playback but keeps your position, so the nextPLAYcontinues from the same spot. Sounding notes are released (all-notes-off) so nothing hangs.STOPis a harder stop: playback halts and the play head returns to the start. It stops the transport, not the sound — a reverb or delay still ringing goes on ringing, the same way it does in a DAW, and your master fader stays exactly where you put it. Your session — tracks, instruments, patterns — is untouched, soPLAYbrings it all back.STOPagain, and a third time, is the panic. Once the transport is already stopped, further stops escalate: the master fades to silence over a few milliseconds, every instrument and effect is flushed — reverb tanks, delay lines, sounding voices — and playback comes back from a genuinely clean graph. Nothing about your session is destroyed; only what was still making noise.RESETis the big one. It throws the entire session away — every variable, track, instrument, and effect — and gives you a fresh runtime. Reach for it when you want a clean slate, not when you just want silence.
Recording and Seeking
Section titled “Recording and Seeking”Two more transport commands cover deeper ground:
RECORD;resumes playback likePLAY, but also starts capturing audio on any armed tracks. With nothing armed it just plays. Arming tracks, choosing inputs, and pulling takes off disk are covered in Recording & Input.SEEK <expr>;jumps the play head to a cycle position —SEEK 16;moves to cycle 16. It comes into its own with timed arrangements; see Arrangements.
Watching the Session
Section titled “Watching the Session”While you play, you’ll want to see what’s going on — levels, routing, MIDI, plugin editors. Resonon gives you a few windows onto a running session.
Plugin editors. A third-party instrument or effect with a graphical editor
opens its own window with .show_gui() (and .hide_gui() to close it):
let synth = Instrument("Surge XT");let lead = AudioTrack("lead");lead.instrument(synth);
if synth.supports_gui() { synth.show_gui();}Built-in DSP effects have no GUI — you drive those with .params() and
param_set. See Plugins.
TUI views. From a terminal, resonon view <name> opens a text-mode panel
connected to a running server:
resonon view mixer # track levels and the masterresonon view routing # how audio and MIDI are wiredresonon view scope # an oscilloscope on the outputresonon view console # server output and shortcut hintsresonon view midi_monitor # live MIDI messagesIn the editor these are the same panels under the sidebar’s Views section. The mixer, routing, and scope views are also the quickest way to see a swap or a new layer take hold. For every option, see the CLI Reference.
Visuals. If your piece drives shaders, open the native render window with the
Open Visuals button (or screen.show_window()) once resonon server is
running. The visuals system itself is covered in
Audioreactive Shaders.
Next Steps
Section titled “Next Steps”You can build, swap, and steer a session live. Next, share that session — or learn when to drop the live loop entirely and render to a file.
- Server & Collaboration — run a server others can join
- Live Coding vs Offline Rendering — the two ways to run resonon, and when to use each