Some loops do not start with sync command when changing stop to #stop

Hey, my first post! I’m trying to sync my live_loops using “sync:” in the opts of the live_loop itself. It works for simple live_loops, like drums. I can change “stop” to “#stop” on the fly and the loops start playing after 1 bar. However, my melody, containing “3.times do” etc. doesn’t start when I place the # before the stop during live coding. To be more precise, if I start with “stop” and I change it on the fly to “#stop”, it will start playing. But if I stop it again, refresh, and then #stop, refresh, it doesn’t start playing. How can I make this work? Thanks in advance for your help!

use_bpm 120

# the metronome contains a bleep sound to indicate the moment of the "cue"

live_loop :metronome do
  sleep 4
  cue :clock
  play 84, amp: 0.3
end

# this is the main melodie

live_loop :melody, sync: :clock do
  #stop
  with_fx :reverb, mix: 0.5, room: 0.9 do
    use_synth (ring :prophet, :saw).tick
    3.times do
      play :C4, cutoff: rrand(60,80)
      sleep 0.5
      play :G3, cutoff: rrand(60,90)
      sleep 0.5
      play :C4, cutoff: rrand(60,70)
      sleep 0.5
      play :Gs3, cutoff: rrand(60,80)
      sleep 0.25
      play :Gs3, cutoff: rrand(70,100)
      sleep 0.25
    end
    1.times do
      play :c4, cutoff: rrand(60,80), release: 1
      sleep 0.5
      play :g4, cutoff: rrand(60,90), release: 1
      sleep 0.5
      play :c4, cutoff: rrand(60,70), release: 1
      sleep 0.5
      play :gs3 + 7, cutoff: rrand(80,100), release: 1
      sleep 0.5
    end
  end
end


# drums

live_loop :kick, sync: :clock  do
  #stop
  sample :bd_haus
  sleep 1.5
  sample :bd_haus
  sleep 1
  sample :bd_haus
  sleep 1
  sample :bd_haus
  sleep 0.5
end


live_loop :tom, sync: :clock  do
  #stop
  sample :drum_tom_lo_soft
  sleep 0.5
end


live_loop :snap, sync: :clock  do
  #stop
  sleep 1
  sample :perc_snap
  sleep 1
end
1 Like

I think it is because of the with_fx :reverb inside the melody loop that this does not work. One solution which seems to work is to kill this fx after each pass. That then allows the live loop to restart cleanly.
replace your melody loop with this and try again.

live_loop :melody, sync: :clock do
  #stop
  with_fx :reverb, mix: 0.5, room: 0.9 do |k|
    
    use_synth (ring :prophet, :saw).tick
    3.times do
      play :C4, cutoff: rrand(60,80)
      sleep 0.5
      play :G3, cutoff: rrand(60,90)
      sleep 0.5
      play :C4, cutoff: rrand(60,70)
      sleep 0.5
      play :Gs3, cutoff: rrand(60,80)
      sleep 0.25
      play :Gs3, cutoff: rrand(70,100)
      sleep 0.25
    end
    1.times do
      play :c4, cutoff: rrand(60,80), release: 1
      sleep 0.5
      play :g4, cutoff: rrand(60,90), release: 1
      sleep 0.5
      play :c4, cutoff: rrand(60,70), release: 1
      sleep 0.5
      play :gs3 + 7, cutoff: rrand(80,100), release: 1
      sleep 0.5
    end
    kill k
  end

It uses the undocumented kill command, so @samaaron may suggest a better way that doesn’t use this

Is this what happened to the sync into the wonderful Aerodynamic Daft Punk example provided here : https://aimxhaisse.com/aerodynamic-en.html
? Seems to be a rather unfortunate bug that may limit expressive use. I hope that some of these sync issues can be figured out soon!

Yes, this is definitely a bug, sorry about that.

@TheHappyNoise - rather than hoping the sync issues can be figured out soon please consider helping me fund sustainable development on Patreon. Unfortunately most of my time right now is spent looking for further funding rather than developing and fixing Sonic Pi :frowning:

Robin, thanks for this solution, it works! The “|k|” is called an argument right? Any idea where I can find more info about arguments? I want to teach this concept to teenagers during a workshop.

Sam, I increased the Patreon support, hope you’ll find enough funding to focus on the more fun stuff.

1 Like

@menno_keij what do you mean by “lkl”?

In Sonic Pi there are ‘opts’ for synths/samples etc (which are optional) and some functions require arguments.

For example, play has one argument (the note to play) and a number of different opts (things which can change the call such as the amp, timbre settings etc).

play 60, amp: 2

In the above example, the note is 60 with is an argument (it’s required - without it the function call will fail) and one opt: amp: 2 which is a key-value pair of the opt name amp: and the opt value 2. You can add more than one opt by separating them with commas:

play 60, amp: 2, release: 0.1

Here we’ve added a release: opt with a value of 0.1 which makes the note much shorter than the default release: value of 1.

You can see more information for each function’s args and opts in their respective documentation. Just hit the help button and navigate to the Lang tab:

Thank-you also for your generous support of my work :slight_smile:

Hi Sam, thanks for your super quick response and explanation. What I meant with |k| was this:

with_fx :reverb, mix: 0.5, room: 0.9 do |k|
#stuff to execute
kill k
end

How would you call the “k” in this script? I understand that it sends the “kill” command to the top row of code, so the whole “reverb” script gets thrown out of the memory.

Hi @menno_keij, as far as I understand the k is a reference to the reverb. So, any time you would like to address this or some other effect, you’d have to have a way to access it.

A common scenario is also the use of control such as:

live_loop :someloop do
  with_fx :reverb, room: 0.75, mix: 0.0 do |rev| # instead of 'k' I am using 'rev'
    control rev, mix: 0.75, mix_slide, 1
    play :c, release: 1.0
    sleep 4
  end
end

Hope this helps.

1 Like

For extra detail, please see sections 5.5 and 7.2 of the bulit-in tutorial :slight_smile: