Toggle fx on/off (via mix:) while live coding?

Hi all
still having endless hours of fun here - we are commonly advised to use with_fx blocks outside any loops to avoid duplicating fx resources. I have found that I can’t use a ‘global’ variable to toggle fx on/off, unless I stop then restart my loops. I’d like to do this in real time, while loops are running.

onoff = 0

with_fx :slicer, phase: 0.125, mix: onoff do
  with_fx :reverb, room: 1, damp: 0.8, mix: onoff do
    live_loop :cor do
      sample :ambi_choir, rpitch: -3.3, pan: -0.7
      sample :ambi_choir, rpitch: -3.7, pan: 0.7
      sleep 8

Don’t forget to like and subscribe :smiley:

1 Like

This is a known problem, for which there is a bodge solution as follows:
First, the reason it occurse is that each time you press RUN a new fx wrapper is allocated, but the live loop still “sees” the initial one, so when you change the mix value that is not reflected and it doesn’t appear to change.
The solution is to use the code below, where the reference to the fx wrapper is stored in the |r| or |v"| for the two wrappers shown. Once you have pressed RUN and the code has started, then comment out the line set :r,r;set :v,v
Then use the two control lines to change the mix: or the amp: settings and this will work picking up the value set each time you press RUN. If you STOP all the code running, then uncomment the same line until you have pressed RUN again, and then comment it out again. A bit kludgy, but it works.
The alternative is to embed the fx within the live loop and put up with the overhead that will generate. Of course if you never want to change the fx settings then it doesn’t matter and teh external ones will work.

with_fx :level,amp: 1 do |v|#allow volume to be controlled. Set intial value here
  with_fx :reverb,room: 0.8,mix: 0.8 do |r|#allow the mix to be controlled, set intial value here
    set :r,r;set :v,v #comment immediately after first run.
    #uncomment line above when stop pressed, then recomment after next run started
    live_loop :test do
      control get(:r),mix: 0.8
      control get(:v),amp: 1
      play scale(:c4,:minor_pentatonic,num_octaves: 2).choose,release: 0.2
      sleep 0.2
1 Like


thank you for this Robin. If I read (and test) this correctly, it appears to work while running only once - in order to reinitialise I have to press stop. I was hoping to have live control of fx levels without using stop. I do understand precisely WHY this occurs (“the live loop only sees the initial fx wrapper”).

There is Sonic Pi expertise here beyond mine that has grappled with this but I’ll keep experimenting and breaking stuff :smiley:

Having watched a video recently of Sam (in Australia, at Software Art Thou) using define and control to vary parameters of a running loop, in my n00bness I thought there might be a soution to this using something like:

`define :bla do
s = fx in here

live_loop :smeg do
control s
sleep 0.125

Many thanks

Yeh, you can’t assign ‘with_ fx do/end’ to a variable. :man_facepalming:

Hmm. If you run then comment out the line specified, you can alter the mix and vol settings inside the live loop (not the values in the fx lines) and they will be used when you press run again. You only need to reinitialide by in commenting the line if you press STOP.
In other words you can change things as much as you like, pressing run to take up the new values without stopping the Live Loops running.

1 Like

Ah ok, thanks - I was prob testing it incorrectly; thanks Robin


I’m teaching myself how to use define in SPi, and this works for me, i.e. alter fx parameters without the need to press stop. Only question is, does it create a new fx wrapper each time I call the :notes function??:

define :notes do
  |pitch, del, mix|
  with_fx :ping_pong, phase: del, mix: mix do
    use_synth :bass_foundation
    play pitch

live_loop :sendToFunc do
  notes [72, 75, 77, 79, 82].pick, 0.625, 0.5 # << change mix level to > 0
  sleep 0.25

Yes I think it will define a new wrapper each call.