ChucK debugging and live recovery: from silent failures to panic patches
Learning objectives
- learner can identify and fix ChucK's four silent-failure modes — no time advance, broken dac path, un-triggered envelope, and clipping gain — before any sound leaves the speaker
- learner can classify a ChucK error as compile-time, runtime, or silent failure and apply the correct recovery action for each class without stopping the set
- learner can hand-roll pitch, scale, and rhythmic structures using `Std.mtof`, `int[]` arrays, and `dur` arithmetic to work around ChucK's absent higher-level primitives
- learner can deploy a minimal panic patch via `Machine.replace` to restore a stable drone within seconds of a catastrophic shred failure
Capstone — one whole task that evidences the objectives
Given a deliberately broken ChucK session — containing at least one silent infinite loop, one disconnected UGen chain, one un-triggered ADSR, one mis-cased UGen class name, one integer-division timing bug, and voices summed hot enough to clip — diagnose each failure class (compile-time vs runtime vs silent), apply targeted fixes in the running VM without restarting ChucK, then replace the session with a self-contained five-voice texture that uses hand-rolled scale quantization, sporked shreds with correct lifetimes, event-based synchronisation between voices, safe gain staging across all voices, and a tested panic patch swappable at any point via Machine.replace.
This module teaches ChucK from the angle that matters most in a live performance context: not what the language can do in theory, but why it silently fails in practice, and how to recover without stopping the set. ChucK’s strongly-timed model is a source of both its power and its most persistent bugs — the same => now idiom that gives sample-accurate control also means any loop without it pins the CPU and emits nothing, with no error to find. By the end of this module, learners have a systematic mental model of every common failure mode and a practiced recovery protocol.
The arc begins with the mechanics layer — the twelve L1 facts that encode ChucK’s distinctive rules. Before you can debug, you must know that => is context-sensitive (patch, assign, or control depending on operand types); that the DAC must be transitively reached or nothing plays; that integer literals divide as integers (1/2 == 0); that dur and time are typed and cannot mix with bare floats; that UGen class names are exact CamelCase checked against names/ugens.txt; that raw MIDI integers sent to .freq play that many Hz (use Std.mtof); and that ChucK has no native scale, chord, or euclidean primitive — these must be hand-rolled. This is the grammar of silence: knowing each rule is knowing one more way a program can be inexplicably quiet.
The middle arc introduces the debug classification framework from chuck-error-surface-modes: compile-time errors (shred never added, existing voices unaffected), runtime errors (offending shred removed, others survive), and silent failures (no error at all — the hardest class). The four canonical silent failure modes are then practised in isolation:
- No time advance —
chuck-silent-failure-no-time-advance: the VM appears frozen at 100% CPU. - Broken dac path —
chuck-dac-path-required: a beautifully-patched voice that the dac never sees. - Un-triggered envelope —
chuck-envelope-needs-gate-trigger: ADSR or STK instrument stays closed untilkeyOn/noteOn. - Gain clipping —
chuck-gain-staging-no-master-limiter: three voices at full gain sum to distortion with no warning.
These are practised first on minimal isolated patches (single-bug drills), then in combination on a “sabotaged session” — a provided set of three to five intentionally broken .ck files. Each drill has a diagnosis step (classify the failure mode, locate the line) and a repair step (apply the minimal fix, verify audio restores).
The shred-lifecycle cluster (chuck-shred-lifecycle, chuck-sporked-shred-lifetime, chuck-event-signal-vs-broadcast) is introduced in a concurrent-voices exercise: building a drum texture from sporked shreds that broadcast a shared downbeat event. Learners discover that sporked children die with their parent — so long-running voices must be sporked from a persistent top-level shred — and practise signal() versus broadcast() to selectively mute one voice without killing others.
The chuck-no-native-scale-chord atom drives the compositional section: learners hand-roll a pentatonic scale as an int[] of MIDI degrees, use Std.mtof for frequency lookup, and build a simple euclidean onset array for rhythmic placement. This is deliberately low-level — the point is that ChucK forces explicit data structures where Strudel offers one-liners, and that awareness prevents the mistake of looking for a function that does not exist.
The capstone synthesises every thread. A provided broken session contains exactly one instance of each silent failure class, plus an integer-division timing bug and a sporked-shred lifetime error. Learners diagnose and fix each in the running VM (using Machine.add, Machine.replace, Machine.remove) without restarting ChucK. They then rebuild the session as a five-voice texture — two melodic voices using hand-rolled scales, one percussion voice using a euclidean array, one event-synchronised accent voice, and one ambient drone — with gain staging across all voices verified to remain below clipping. The final step is writing and testing the panic patch: a minimal SinOsc => dac with a timed loop, no sample dependencies, and low gain, swappable via Machine.replace at any moment. The panic patch must survive all four silent-failure modes by design — its existence as a tested fallback is what makes live performance in ChucK sustainable.
The supporting atoms (chuck-strongly-timed, chuck-ugen-chuck-operator, chuck-shreds-sporking) are not gated by the capstone but are referenced throughout the narrative as the deeper conceptual grounding beneath the debug rules. Learners who reach this module without prior ChucK exposure should work through those atoms first.
Atoms in this module
Required — these gate the capstone
Supporting — enrichment, not gating