How do subdivide a beat?

I am wondering why this does not work as expected:

live_loop :bd do
  sample :bd_boom
  sleep 1
end

live_loop :cymb do
  sync :bd
  4.times do
    sample :drum_cymbal_soft
    sleep 0.25
  end
end

It plays 4 cymbal hits, followed by a full beat of nothing, then repeats. I expect a steady flow of quarter cymbal hits.

I can write it like this but this new code is less clear:

live_loop :bd do
  sample :bd_boom
  sleep 1
end

live_loop :cymb do
  sync :bd
  sample :drum_cymbal_soft
  3.times do
    sleep 0.25
    sample :drum_cymbal_soft
  end
end

What is the “correct” way to subdivide a beat?

The problem is that both live loops run for the same length of time, so by the time :cymb syncs to :bd, the cue might have already been sent, so it has to wait another iteration of the loop.

One way to fix this, is to only sync once when the :cymb live loop starts up. There is built-in functionality to do this by adding it as a parameter to the loop like this:

live_loop :cymb, sync: :bd do
  4.times do
    sample :drum_cymbal_soft
    sleep 0.25
  end
end

Another way is to add a small negative sleep at the end of the loop, so it “goes back in time” and is already waiting by the time the cue is sent (it might be surprising that this works, but due to the way Sonic Pi’s timing system works it is indeed possible):

live_loop :cymb do
  sync :bd
  4.times do
    sample :drum_cymbal_soft
    sleep 0.25
  end
  sleep -0.1
end
2 Likes

The ’ sleep ’ times does the syncronizing

live_loop :bd do
  sample :bd_boom
  sleep 1
end

live_loop :cymb do
  sample :drum_cymbal_soft
  sleep 0.25
end

@emlyn , thanks! That solves my problem. I also looked it up in the help, can’t believe I missed it there. That negative sleep is one clever trick but I’m going to avoid it as it makes the code more confusing (I give workshops once in a while and don’t want to confuse the students more than I have to :smile: )

@hitsware, that is not correct. If I have the :bd loop running before I write the :cymb loop, the :cymb loop will be out of sync when I run it (unless I time it really really well). I tried it with a longer loop, sleep 4 and hitting the cymbals with an interval of 1. It’s very hard to make them land exactly on the beat unless you stop the program and restart it so the live_loops start together.

@RTL
"
It’s very hard to make them land exactly on the beat
unless you stop the program and restart it so the
live_loops start together.
"

Ahh … O.K… I always start everything together so
have no problem ( I use S.Pi to compose rather than perform )

1 Like