Sonic Pi v4.0.2, beat variable returns the elapsed time rather than the beat

Sonic Pi v4.0.2, beat variable returns the elapsed time rather than the beat.

Lang
#Example 1

use_bpm 120
puts beat
sleep 1
puts beat
use_bpm 2000
sleep 2
puts beat

{run: 3, time: 0.0}
└─ 484.0354919433594

{run: 3, time: 0.5}
└─ 485.0354919433594

{run: 3, time: 0.56}
└─ 487.0354919433594

Hi @H_Tachibana,

unfortunately, since we integrated the Link metronome we can no longer assume that the beat starts at 0, or even is a whole number.

However other than the initial starting position, the beat will behave exactly as before - assuming the metronome sticks to 60.

I understand.
This was OK.

use_bpm 120
beat0=beat
puts beat-beat0
sleep 1
puts beat-beat0
use_bpm 2000
sleep 2
puts beat-beat0

{run: 4, time: 0.0}
└─ 0.0

{run: 4, time: 0.5}
└─ 1.0

{run: 4, time: 0.56}
└─ 3.0


loop do
sample :drum_cymbal_closed
sample :drum_bass_soft if (beat-beat0).to_i % 2 == 1
sleep 1
end

For this kind of musical behaviour, you might want to explore tick and look which are thread local counters that you manually increment and give you a lot of control.

For example:

live_loop :drums do
  sample :drum_cymbal_closed
  sample :drum_bass_soft, on: tick % 2
  sleep 1
end

Thank you, tick is better.
But, my objective was if statements for an introduction to programming.

In that case you can also use tick with if statements:

live_loop :drums do
  sample :drum_cymbal_closed
  sample :drum_bass_soft if tick % 2 == 1
  sleep 1
end

EDIT: changed if tick % 2 into if tick % 2 == 1 in case anyone else comes across this later.

Thank you!
But handling tick seems difficult in a one-hour introduction to programming.

actually, this is required when using if. Ruby doesn’t see 0 as being false - only nil and false are considered falsey. That’s one of the benefits of on: as it relaxes this to also include 0 in addition to not requiring to be at the end of the line.

You therefore need the following if you want to use if (which, to be honest I rarely do).

live_loop :drums do
  sample :drum_cymbal_closed
  sample :drum_bass_soft if tick % 2 == 0
  sleep 1
end
1 Like

I’m not sure how it’s more tricky than beat which already requires learners to know about an internal counter associated with sleep.

tick just increments a counter every time it is called and returns the latest value of that counter. It’s basically a code version of a hand-held click-counter used to count the number of people entering a room (and it only counts upwards). It’s independent of sleep and only increments when you call it, so you get more control.

Indeed it is, but for loop may be appropriate.

for i in 1…8
sample :drum_cymbal_closed
sample :drum_bass_soft if i % 4 == 1
sample :drum_snare_soft if i % 4 == 3
sleep 1
end

1 Like