Summary
A high‑pass filter defined outside a live_loop in Sonic Pi does not update its parameters when you press Alt‑R because the FX node is created once and its arguments are fixed at creation time. Re‑running the buffer does not recreate the FX node unless the audio graph is rebuilt, which only happens when you stop and restart.
Root Cause
- FX nodes in Sonic Pi are immutable after creation. Their parameters are evaluated once when the FX block is instantiated.
Alt‑Rreloads code but does not rebuild the running audio graph if the FX block is outside alive_loop.- The FX block is not inside a loop, so it never re‑executes and therefore never receives updated parameters.
Why This Happens in Real Systems
- Audio engines like SuperCollider (which Sonic Pi uses) create UGens (audio processing units) that are not dynamically reconfigured unless explicitly rebuilt.
- Long‑lived FX nodes are designed for performance stability, not dynamic reconfiguration.
- Rebuilding the audio graph on every code reload would cause audio dropouts and glitches, so Sonic Pi avoids doing this automatically.
Real-World Impact
- Parameter changes appear to “do nothing” unless the FX block is recreated.
- Live coding performances become confusing because visual code changes do not match audible output.
- Engineers mistakenly assume the filter is “broken” when the issue is actually graph immutability.
Example or Code (if necessary and relevant)
A correct pattern for dynamically controllable master FX is to use a control bus or a live FX:
set :cutoff_val, 100
with_fx :hpf, cutoff: get(:cutoff_val) do |fx|
live_loop :control_cutoff do
control fx, cutoff: get(:cutoff_val)
sleep 0.1
end
live_loop :drums do
sample :bd_haus
sleep 1
sample :bd_haus
sleep 1
end
end
Changing the value:
set :cutoff_val, 20
…will update the filter without stopping audio.
How Senior Engineers Fix It
- Use
controlto update FX parameters instead of recreating FX nodes. - Separate control logic from audio logic, using a dedicated loop to push parameter changes.
- Store parameters in named state (
set/get) so they can be updated live. - Avoid placing FX outside loops unless they are meant to be static.
Why Juniors Miss It
- They assume FX behave like variables and update automatically.
- They misunderstand how Sonic Pi’s audio graph differs from its Ruby-like code execution.
- They rely on documentation examples without realizing the lifecycle of FX nodes.
- They expect
Alt‑Rto “refresh everything,” not knowing that FX nodes persist until explicitly rebuilt.
Would you like a version that supports multiple FX parameters (cutoff, resonance, mix) all controllable in real time?