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
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
end
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
end
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
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!