Debugging and recovery in Strudel
Learning objectives
- learner can identify the five silent-failure patterns in Strudel — wrong sample names, locked AudioContext, missing .analyze('hydra'), orbit sharing, and gain clipping — and apply the correct fix for each
- learner can distinguish error-throwing failures (shown in #err, old pattern kept playing) from silent failures (no exception, no audio or no reactivity) and choose the right diagnostic step for each surface
- learner can write correct mini-notation using * vs !, polymeter {…}%n, and pattern/signal arguments in place of thunks, and read tempo correctly via setcpm
- learner can recover a broken or runaway Strudel mix live — using hush() then a minimal synth-only AV groove — and explain why failed evaluates leave the previous pattern running
Capstone — one whole task that evidences the objectives
Take a seeded Strudel session file containing at least ten bugs — an unknown sample name (silent, no exception), a locked-AudioContext startup sequence, a missing .analyze('hydra') tag, a thunk passed where a signal is required, a * / ! notation swap that changes the rhythm, a polymeter {…} group missing its %n suffix so it inherits the wrong step count, an unbalanced mini-notation bracket that throws in #err while the old pattern keeps playing, a crush call using a 0–1 value instead of a 1–16 bit-depth, a setcpm call set to raw BPM, and a multi-voice session where all orbits share a single bus — and, without looking up solutions, diagnose each failure using the two-surface model (check #err first, then reason from symptom), classifying each as throwing vs silent. Fix every bug by re-saving edits into the gaplessly re-evaluating session (never restarting the page), then write a complete panic recovery block: hush() followed by a minimal three-voice groove (synth bass, hi-hat, pad) at the correct tempo with each voice on its own $: line, independent orbits, gain in the 0.6–0.8 range, and the audio-reactive voice tagged with .analyze('hydra'). Annotate each fix and each line of the panic block with the rule it satisfies, and explain why a failed evaluate leaves the previous pattern running rather than cutting audio.
Prerequisite modules
This module is built around one professional reality: silence is ambiguous. In a Strudel session — at an algorave, a classroom, a bedroom stream — a voice that plays nothing gives you no error, no dialog box, no stack trace. It might be a wrong sample name, a still-locked AudioContext, a missing .analyze('hydra') tag, a method that received a thunk instead of a signal, or a mix gone quiet because gain staging collapsed. Knowing which silent-failure pattern you are in, and what the diagnostic step is for each, is the fluency that separates a working browser performer from someone who restarts the page.
The twenty-one atoms here span two interlocking layers. The first (L1 gotchas) covers failures you hit in the first hour of Strudel: sample names that must match exact folder names in the dirt-samples bank (bd not kick; cp not clap); the browser autoplay policy that keeps audio silent until the first user click; the Strudel→Hydra FFT bridge that reads zero unless the driving pattern carries .analyze('hydra'); mini-notation traps where * speeds hits into one step while ! replicates across steps, or where a polymeter {…} group silently adopts the wrong step count without the %n suffix; the cross-DSL mistake of passing a thunk () => … where Strudel expects a pattern or signal (sine.range(200, 2000)); the tempo trap of calling setcpm(120) and getting a very fast two-cycles-per-second pulse instead of a 30-BPM feel; orbit sharing where all voices default to orbit(0) and accidentally pool their reverb and delay sends; and multiplicative gain stacking that clips silently as voices accumulate.
The second layer (L5 debug) teaches you to use the error surface systematically. Strudel errors split into two classes: those that throw — a syntax error, an undefined method, unbalanced mini-notation brackets — and those that do not. Throwing errors appear in the on-page #err element as strudel: <message>; the previous pattern keeps playing and nothing is installed. Silent failures (unknown sample, locked AudioContext, missing bridge tag) throw nothing — #err stays clear, but a voice is mute or a visual is static. The diagnostic loop is short: check #err first; if clear, match the symptom to the five known silent-failure patterns. “Check #err first; if empty, reason from symptom” is the complete procedure.
Panic recovery enters as a first-class skill. When the mix is unrecoverable — runaway gain, wrong samples, broken patterns all firing at once — hush() stops every registered voice immediately, the equivalent of stopping all live_loops in Sonic Pi. The canonical recovery sequence is hush() followed by a minimal synth-only groove (no sample bank dependency) with .analyze('hydra') so the visual bridge stays alive through the reset. This sequence can be typed in under ten seconds and should be drilled until automatic.
The capstone exercises all four objectives together under no-scaffold conditions. The learner receives a seeded bug file, must work through the two-surface diagnostic loop without hints, fix every bug, and write their own panic block from memory. The annotation requirement forces explicit reasoning: each fix names the failure class and the rule it violates; each line of the panic block names the constraint it satisfies. That documentation becomes a personal recovery protocol the performer can revisit before any set.
Atoms in this module
Required — these gate the capstone
Supporting — enrichment, not gating
Part of curricula
- Audio-Visual Performer — integrated, synced live AV — The integrated set (north star) recommended
- Live Coder — zero to performing live-coded music — Performing Live required
Unlocks — modules that require this one