'bad values' - tips to avoid timing warnings (calculated sleep)

Hi!

I’ve just tried playing with the loops that comprise ‘Cloud Beat’ by SonicPit, first loop type iterates over divisors to get time length, a great example that answers one of my first quandries on how to play with beat lengths :+1:

# HIHAT
define :hihat do
  use_synth :pnoise
  with_fx :hpf, cutoff: 120 do
    play release: 0.01, amp: 13
  end
end

live_loop :hihat_loop do
  divisors = ring 2, 4, 2, 2, 2, 2, 2, 6
  divisors.tick.times do
    hihat
    sleep 1.0 / divisors.look
  end
end

After the first few reruns with increased divisor on the last tick (6 => 7,17,177!) I ran into timing errors. As it’s a live loop there’s nothing like scheduled_time to play with, but I’m not sure if even that or time_warp would help!

So the loop is sleeping for an amount of time, which results in timing issues
I see there’s an assert_equal , and wondered

:thinking: is there any way to identify what will result in a timing warning, or out of time error?

I’m not sure if there’s a command (or collection of) , or if even just theoretically (and not recommended) you can do something like 'value a if success, else a-1", recursively, or anything similar/related.

  • I imagine the thresholds may vary on environment
  • Am not sure if there’s a rough approximation, eg a range of time sleep values below which SP may encounter issues, on certain machines or at certain bpms, or with certain ‘loads’

I tried to get a baseline with a bpm tick and some logging, but the results are inconclusive - unless my math is wrong (a likelihood), some timing values are ok at some bpms*, whilst issues occur later with same / higher values… or is it also partly a rounding issue?!

my shoddy debug code -

live_loop :hihat_loop do
  
  bpms.tick.times do
    use_bpm bpms.look
    divisors = ring 2, 4, 7, 15, 25, 35, 55
    divisors.tick.times do
      hihat
      sleep_time = 1.0 / divisors.look
      puts "step #{vt} sleeping for #{sleep_time} at #{current_bpm}, rt #{rt sleep_time}"
      sleep sleep_time
    end
  end
end

I then tried to improve the code and values by starting with lowest bpm then repeatedly doubling, but this also produced unexpected results… not sure if the times blocks are preventing values being shared… basically I’m trying to play each note n times, sleep for 1/n (n is each in divisor ring), then double the bpm after each run (each cycle of the divisor ring) (When I looked at the look value it appeared to be doubling)

# Cloud Beat

# Coded by SonicPit
#
# Taken from "Beats basteln wie die Großen"
# c't 13/2017

# Note: requires a powerful machine to run smoothly.


# HISS
live_loop :hiss_loop do
  sample :vinyl_hiss, amp: 2
  sleep sample_duration :vinyl_hiss
end

# HIHAT
define :hihat do
  use_synth :pnoise
  with_fx :hpf, cutoff: 120 do
    play release: 0.01, amp: 13
  end
end

use_bpm 20
live_loop :hihat_loop do
  
  divisors = ring 2, 4, 7, 15, 25, 35, 55
  divisors.length.times do
    
    divisors.tick.times do
      hihat
      sleep_time = 1.0 / divisors.look
      puts "step #{vt} sleeping for #{sleep_time} at #{current_bpm}, rt #{rt sleep_time} [#{divisors.look}]"
      sleep sleep_time
    end
    
    use_bpm (current_bpm.to_f * 2)
  end
end

Is it possible to “predict errors” (using assert or something, assuming not possible with begin rescue)
If not are there any guidelines, apart from the perhaps kind-of obvious but kind-of vague “don’t use silly sleep values” ?

THANK YOU!