Rings not Working inside 'at'

Having a great time using the ‘at’ functions to trigger events on beat but not so much of a great time when trying to tick through rings inside of them. Code example below :slight_smile:

live_loop :do do
use_synth :blade
  use_random_seed 101
  x = (line 0.1,0.99,steps:64).tick
  at [0,1,2,3.5] do
    sample :loop_amen, onset: (ring 1,4).mirror.tick(:a), amp: 2
  end if(spread 1,8).tick(:b)
  at [0.5,1] do
    use_random_seed (ring 2000,2003).stretch(4).tick(:c)
    sample :drum_cymbal_closed, rate: (ring 1,-1,2,-1).pick(7).tick(:d), amp: 3
  play (scale :c4,:hungarian_minor).pick(5).tick(:e)+x, amp:2, sustain:0.01 if(spread 3,4).tick(:f)
  sample :loop_amen,onset:tick, rate: 4*(x*0.5), pan: (ring -0.8,0.8).tick(:pan) if(spread (ring 3,2).stretch(6).tick(:g),4).look
  sample :loop_amen,onset:look, amp: 4, rate: 0.8 if(spread (ring 3,2).stretch(6).tick(:h),4).look
  sleep 0.125

Hi @samconran,

one thing that’s subtle but very important about tick is that it is thread local. This means you can have multiple ticks in multiple live loops and they won’t interfere with each other :slight_smile:

However, it also means you need to be careful about mixing ticks and threads. at works by creating a new thread and running the code in that thread. In fact, it will create a separate thread for each time argument you give it. Each thread is isolated from each other. They may inherit the same starting values, but any modifications they make (and tick is a modification of the current thread’s counter) are isolated to that specific thread.

If you want to have a similar behaviour to at but with no isolation then you need to consider using time_warp which runs all the code in the current thread but modifies the current logical time so that each message (play, sample, midi etc) is scheduled accordingly.

The differences between at and time_warp are subtle but very important and well worth spending some time experimenting with and exploring.

Do let me know if you have any further questions!