Playing a sound multiple times without using 'sleep'

I have 2 arrays:

  beat =      [1,0,0,0,0,0,0,3,2,0,0,0,3,0,0,0]
  bassline1 = [0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0]

I scan through them like this and they run in sync, so far so good:

  live_loop :mainbeat do
    16.times do |i|
      sync :tick
      kick if beat[i] == 1
      kickfill if beat [i]== 3
      snare1 if beat[i] == 2
    end
  end
  
  #read bass
  live_loop :bassline1 do
    16.times do |i|
      sync :tick
      sample basses, 5  if bassline1[i] ==1
    end
  end
end```

however there are 2 functions (kickfill and snare1) which include a sleep inside them, so when they are called they cause the arrays to be out of sync.

For example, this is how the function snare1 looks:
```#snare
  define :snare1 do
    with_fx :reverb do
      if one_in 8
        sample :sn_generic, sustain: 0.18, room: 1
        sleep 0.175
        sample :sn_generic, sustain: 0.18, room: 1, amp: 0.4
        sleep 0.175
        sample :sn_generic, sustain: 0.18, room: 1, amp: 0.2
      else
        sample :sn_generic, sustain: 0.18, room: 1
      end
    end
  end```
I'm trying to have a randomised mini-snare-roll, but when that one_in 8 happens, the sync goes out.

Which brings me to my question:
can I delay an event without using 'sleep'?

I have a similar issue in kickfill, where a one_in triggers a randomly delayed kick...

If I understand what you want to do correctly, then in your kickfill and snare functions, you can run the sounds inside another thread, complete with their own sleeps. They will play sounds in time, but return right away so not upset the time of you main loop. You can put whatever you like in kickfill.

Is that it? Something like

define :kickfill do
  in_thread do
    3.times do
      sleep 0.33
      sample :drum_bass_soft, amp: 0.2
    end
  end
end

live_loop :drums do
  sample :drum_bass_soft, amp: 0.2
  sleep 1
  sample :drum_snare_hard, amp: 0.2
  sleep 1
  sample :drum_bass_soft, amp: 0.2
  sleep 1
  sample :drum_snare_hard, amp: 0.2
  kickfill if one_in(2)
  sleep 1
end
2 Likes

That worked, thanks!

1 Like

Hi, you have also an other way to get this, + some more params to include (that is what i am using right now) check this out:

use_bpm 150
pattern_kick =    "9---8---8---8---".ring

live_loop :kick do
      sample :bd_haus, amp: (pattern_kick[look].to_f / 9) if (pattern_kick[tick] != "-")
      sleep 4/pattern_kick.length.to_f
    end

notes: with this technique, you can set the drum beat, as well as the volume of each note/kick :wink:

using this method, you will be able to switch between “patterns” with a simple variable :wink:
there is maybe a better way to archieve this, but i started sonic pi recently and i am not aware of every classes and prototypes. At least, it works for me during performance and compos.

have a nice day
uriel

1 Like