Asynchronous Time. Run a block at the given time(s)

at  times (list), params (list)

Given a list of times, run the block once after waiting each given time. If passed an optional params list, will pass each param individually to each block call. If size of params list is smaller than the times list, the param values will act as rings (rotate through). If the block is given 1 arg, the times are fed through. If the block is given 2 args, both the times and the params are fed through. A third block arg will receive the index of the time.

Note, all code within the block is executed in its own thread. Therefore despite inheriting all thread locals such as the random stream and ticks, modifications will be isolated to the block and will not affect external code.

at is just-in-time scheduling using multiple isolated threads. See time_warp for ahead-of-time scheduling within the current thread.

Introduced in v2.1

Examples

# Example 1

at 4 do
    sample :ambi_choir   
  end



 
# play sample after waiting for 4 beats
 



# Example 2

at [1, 2, 4] do 
    play 75          
  end                



# plays a note after waiting 1 beat,
# then after 1 more beat,
# then after 2 more beats (4 beats total)



# Example 3

at [1, 2, 3], [75, 76, 77] do |n| 
    play n
  end



# plays 3 different notes
 
 



# Example 4

at [1, 2, 3],
      [{:amp=>0.5}, {:amp=> 0.8}] do |p|
    sample :drum_cymbal_open, p         
  end



 
# alternate soft and loud
# cymbal hits three times
 



# Example 5

at [0, 1, 2] do |t|
    puts t
  end



# when no params are given to at, the times are fed through to the block
#=> prints 0, 1, then 2
 



# Example 6

at [0, 1, 2], [:a, :b] do |t, b| 
    puts [t, b]
  end



#If you specify the block with 2 args, it will pass through both the time and the param
#=> prints out [0, :a], [1, :b], then [2, :a]
 



# Example 7

at [0, 0.5, 2] do |t, idx| 
    puts [t, idx]
  end



#If you specify the block with 2 args, and no param list to at, it will pass through both the time and the index
#=> prints out [0, 0], [0.5, 1], then [2, 2]
 



# Example 8

at [0, 0.5, 2], [:a, :b] do |t, b, idx| 
    puts [t, b, idx]
  end



#If you specify the block with 3 args, it will pass through the time, the param and the index
#=> prints out [0, :a, 0], [0.5, :b, 1], then [2, :a, 2]
 



# Example 9


puts "main: ", rand 
rand_back
at 1 do        
               
  puts "at:", rand
  puts "at:", rand
end
sleep 2
puts "main: ", rand



# at does not consume & interfere with the outer random stream
# 0.75006103515625
 
# the random stream inside the at block is separate and
# isolated from the outer stream.
# 0.9287109375
# 0.1043701171875
 
 
# value is still 0.75006103515625



# Example 10


at [1, 2] do
           
  puts rand
  puts rand
end
           
           
           



# Each block run within at has its own isolated random stream:
 
# first time round (after 1 beat) prints:
# 0.9287109375
# 0.1043701171875
 
# second time round (after 2 beats) prints:
# 0.1043701171875
# 0.764617919921875