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
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
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 (
midi etc) is scheduled accordingly.
The differences between
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!