I just published a new tutorial video on how to achieve continuous, elastic tempo changes in TidalCycles.
The video covers techniques with two different functions: nudge
and spaceOut
.
nudge
You can use nudge
to move the timing of events into the future. Here, we schedule each of the four cp
samples with future times of 0, 0.7, 0.2, and 0.4 seconds, respectively:
d1 $ sound "cp*4" # nudge "0 0.7 0.2 0.4"
The above example isn’t very interesting. However, when you apply a sine function to nudge
, you can make time appear to stretch in a smooth way:
d1 $ sound "cp*4" # nudge (slow 8 $ sine)
Different pattern densities, scaling, and sine speeds interact with each other to create different results:
d1 $ sound "cp*8" # nudge (range 0 2 $ slow 16 $ sine)
spaceOut
The spaceOut
function lets you specify a list of cycle speed multipliers, and then plays the pattern exactly once at each speed:
d1 $ spaceOut [1, 0.5, 1.33, 0.1, 2] $ sound "cp*4 cp*2"
The above code will play the cp*4 cp*2
pattern at 1, then 0.5, 1.33, 0.1, and 2 times the normal cycle speed.
Where spaceOut
gets a little more interesting is when you use Haskell’s list syntax to build longer lists of linear (or non-linear) values. Consider this spaceOut
pattern that plays at speeds ranging from 1 to 3, incrementing by 0.1:
d1 $ spaceOut [1,1.1..3] $ sound "cp*4"
The above pattern has 30 different speeds (!) but with very little code.
You can achieve speed “oscillations” that resemble a triangle wave by adding two lists together with the ++
operator:
d1 $ spaceOut ([0.1,0.2..3] ++ [3,2.9..0.1]) $ sound "cp*4"
You can use many different Haskell features to build lists. Here is a different method that constructs lists of fractional values using map
:
d1 $ spaceOut (map (1/) [1,1.5..10]) $ sound "cp*4"
Thanks kindohm for all the tutorials — just starting out in this and your stuff is invaluable.
In case you’re a newb like me and come across this tutorial, note that
d1 $ sound “cp*8” # nudge (scale 0 2 $ slow 16 $ sine)
has now become
d1 $ sound “cp*8” # nudge (range 0 2 $ slow 16 $ sine)
As per the docs, prior to version 1.0.0, scale was a range operator. It now interprets note patterns.
Thank you for catching the change from `scale` to `range`! I’ve updated the post.