Panning stops on re-run (Did I find a bug or am I doing something wrong?)

Using this code:

with_fx :pan do |p|
  use_random_seed 13
  
  live_loop :saw do
    use_synth :prophet
    8.times do
      play (scale :c, :minor_pentatonic).pick,
        amp: 0.6,
        release: 0.2
      sleep 1.0/8
    end
    
  end
  
  pans = ((range 1.0, -1.0, 1.0/8) + (range -1.0, 1.0, 1.0/8))
  
  live_loop :pan do
    dist = 0.6
    
    
    control p, pan: (pans.tick * dist)
    sleep 1.0/8
    
  end
  
  
  pnotes = [:c4, :c4-1, :c4+4.5, :c4+2.7]
  live_loop :prop, sync: :saw do
    use_synth :prophet
    play pnotes.tick, release: 4.0
    sleep 2.0
  end
  
  
  live_loop :ting, sync: :saw do
    a=0
    use_synth :pretty_bell
    16.times do
      a+=1
      time_warp 0.0/8 do
        play :c9-0.3, amp: 0.3, on: ([1,2,4,6,8,10,12,13,15].include? a)
      end
      
      sleep 1.0/8
    end
  end

when I run the program the first time, the panning works just fine, but if I try to re-run the code to preview a change, the panning stops working and stays on the value it was last at, even though the readout still continues to show the pan value shifting… have I found a bug, or am I doing something improperly when it comes to panning a track?

This is because each time you run the value of p is changed, but the original wrapper is the one you need to change. You can save and preserve this in the time state using the code below.
with the program stopped (ie before first run) set :flag,true. Once the program is running change the line to set :flag,false. You can then rerun the program (without stopping it first) and it will control the original fx wrapper which is still active. When you stop the program, you need to reset the flag. It is a bit kludgy but works.

#run with flag set true, then change to flag false be fore rerun.
set :flag,true
with_fx :pan do |p|
  
  set :p,p if get(:flag)
  
  
  use_random_seed 13
  
  live_loop :saw do
    use_synth :prophet
    8.times do
      play (scale :c, :minor_pentatonic).pick,
        amp: 0.6,
        release: 0.2
      sleep 1.0/8
    end
    
  end
  
  pans = ((range 1.0, -1.0, 1.0/8) + (range -1.0, 1.0, 1.0/8))
  
  live_loop :pan do
    dist = 0.6
    p = get(:p)
    
    control p, pan: (pans.tick * dist)
    sleep 1.0/8
    
  end
  
  
  pnotes = [:c4, :c4-1, :c4+4.5, :c4+2.7]
  live_loop :prop, sync: :saw do
    use_synth :prophet
    play pnotes.tick, release: 4.0
    sleep 2.0
  end
  
  
  live_loop :ting, sync: :saw do
    a=0
    use_synth :pretty_bell
    16.times do
      a+=1
      time_warp 0.0/8 do
        play :c9-0.3, amp: 0.3, on: ([1,2,4,6,8,10,12,13,15].include? a)
      end
      
      sleep 1.0/8
    end
  end
end
1 Like

okay, I think I understand… because the threads are persistent, when I do another “with_fx” it actually creates a new thread, thus invalidating my reference to the old one which is still playing but no longer gets inputs. therefore, I need to capture that first reference and use it rather than expecting my p to refer to it.

it turns out you can’t detect running after a stop, so you have to manually set the variable yourself

I found a hacky way to do it lazily which is to assume a low CPU means the program isn’t currently running already, but it would be nice to be able to detect when the program is starting from a stop as opposed to a “first run” or an on the fly “rerun”

thank you for the help

I would basically still say it’s a bug. As a user, I would definitely expect your original code just to work. live_loop should be taught to do something like what @robin.newman demonstrated internally.