Alteration
This page will present you all the functions that can be used to manipulate and alter your patterns. Each function will be presented following the same model:
- Type signature: how the function is declared on the Haskell side.
- Description: verbal description of the function.
- Examples: a small list of examples that you can copy/paste in your editor.
Scaling
range
Type: range :: Num a => Pattern a -> Pattern a -> Pattern a -> Pattern a
range
will take a pattern which goes from 0
to 1
(such as sine
), and scale it to a different range - between the first and second arguments. In the below example, range 1 1.5
shifts the range of sine from 0 - 1
to 1 - 1.5
.
d1 $ jux (iter 4) $ sound "arpy arpy:2*2"
|+ speed (slow 4 $ range 1 1.5 sine)
The above is equivalent to the following:
d1 $ jux (iter 4) $ sound "arpy arpy:2*2"
|+ speed (slow 4 $ sine * 0.5 + 1)
rangex
Type: rangex :: (Floating b, Functor f) => b -> b -> f b -> f b
rangex
is an exponential version of range
described above, good to use for frequencies. For example, range 20 2000 "0.5"
will give 1010
- halfway between 20
and 2000
. But rangex 20 2000 0.5
will give 200
- halfway between on a logarithmic scale. This usually sounds better if you’re using the numbers as pitch frequencies. Since rangex uses logarithms, don’t try to scale things to zero or less!
quantise
Type: quantise :: (Functor f, RealFrac b) => b -> f b -> f b
quantise
is useful for rounding a collection of numbers to some particular base fraction. For example,
quantise 5 [0, 1.3 ,2.6,3.2,4.7,5]
It will round all the values to the nearest (1/5)=0.2
and thus will output the list [0.0,1.2,2.6,3.2,4.8,5.0]
. You can use this function to force a continuous pattern like sine into specific values. In the following example:
d1 $ s "superchip*8" # n (quantise 1 $ range (-10) (10) $ slow 8 $ cosine)
# release (quantise 5 $ slow 8 $ sine + 0.1)
all the releases selected be rounded to the nearest 0.1
and the notes selected to the nearest 1
.
quantise
with fractional inputs does the consistent thing: quantise 0.5
rounds values to the nearest 2
, quantise 0.25
rounds the nearest 4
, etc...
Degrade
degrade
Type: degrade :: Pattern a -> Pattern a
degrade
randomly removes events from a pattern, 50%
of the time. Example usage:
d1 $ slow 2 $ degrade $ sound "[[[feel:5*8,feel*3] feel:3*8], feel*4]"
# accelerate "-6"
# speed "2"
degradeBy
Type: degradeBy :: Double -> Pattern a -> Pattern a
Similarly to degrade
, degradeBy
allows you to control the percentage of events that are removed. For example, to remove events 90%
of the time:
d1 $ slow 2 $ degradeBy 0.9 $ sound "[[[feel:5*8,feel*3] feel:3*8], feel*4]"
# accelerate "-6"
# speed "2"
unDegradeBy
Type: unDegradeBy :: Double -> Pattern a -> Pattern a
unDegradeBy
is degradeBy
but with the percentage describing how many events to keep on average not remove.
Repetitions
ply
Type: ply :: Pattern Int -> Pattern a -> Pattern a
The ply
function repeats each event the given number of times. For example:
d1 $ ply 3 $ s "bd ~ sn cp"
... is equivalent to ...
d1 $ s "[bd bd bd] ~ [sn sn sn] [cp cp cp]"
The first parameter may be given as a pattern, so that:
d1 $ ply "2 3" $ s "bd ~ sn cp"
... is equivalent to ...
d1 $ s "[bd bd] ~ [sn sn sn] [cp cp cp]"
Here is an example of it being used conditionally:
d1 $ every 3 (ply 4) $ s "bd ~ sn cp"
stutter
Type: stutter :: Integral i => i -> Time -> Pattern a -> Pattern a
stutter
is like stut
that doesn't reduce the volume or ply
if you controlled the timing. stutter n t
repeats each event in the pattern n
times, separated by t
time (in fractions of a cycle).
d1 $ stutter 4 (1/16) $ s "bd cp"
is functionally equivalent to ...
d1 $ stut 4 1 (1/16) $ s "bd cp"
Specific conveniences functions that use stutter are:
echo = stutter (2 :: Int)
triple = stutter (3 :: Int)
quad = stutter (4 :: Int)
double = echo
stripe
Type: stripe :: Pattern Int -> Pattern a -> Pattern a
The stripe
function repeats a pattern at random speeds. The first parameter gives the number of cycles to operate over, for example stripe 2
will repeat a pattern twice, over two cycles. Each cycle will be played at a random speed, but in such a way that the total duration will be the same.
For example in the following example, the start of every third repetition of the d1
pattern will match with the clap on the d2 pattern.
d1 $ stripe 3 $ sound "bd sd ~ [mt ht]"
d2 $ sound "cp"
slowstripe
Type: slowstripe :: Pattern Int -> Pattern a -> Pattern a
The slowstripe
function is the same as stripe
but the result is also slowed down by n
time (where n
is the first parameter of the function. This means that the mean average duration of the stripes is exactly one cycle, and every nth stripe starts on a cycle boundary (in indian classical terms, the sam). Usage:
d1 $ slowstripe 3 $ sound "bd sd ~ [mt ht]"
d2 $ sound "cp"
palindrome
Type: palindrome :: Pattern a -> Pattern a
The palindrome
function applies rev
to a pattern every other cycle, so that the pattern alternates between forwards and backwards. For example this:
d1 $ palindrome $ sound "arpy:0 arpy:1 arpy:2 arpy:3"
... is the same as this:
d1 $ slow 2 $ sound "arpy:0 arpy:1 arpy:2 arpy:3 arpy:3 arpy:2 arpy:1 arpy:0"
... and indeed this:
d1 $ every 2 rev $ sound "arpy:0 arpy:1 arpy:2 arpy:3"
Truncation
trunc
Type: trunc :: Pattern Time -> Pattern a -> Pattern a
trunc
truncates a pattern so that only a fraction of the pattern is played. The following example plays only the first three quarters of the pattern:
d1 $ trunc 0.75 $ sound "bd sn*2 cp hh*4 arpy bd*2 cp bd*2"
You can also pattern the first parameter, for example to cycle through three values, one per cycle:
d1 $ trunc "<0.75 0.25 1>" $ sound "bd sn:2 [mt rs] hc"
linger
Type: linger :: Pattern Time -> Pattern a -> Pattern a
linger
is similar to trunc
, in that it truncates a pattern so that only the first fraction of the pattern is played. However unlike trunc, linger
repeats that part to fill the remainder of the cycle.
For example this repeats the first quarter, so you only hear a single repeating note:
d1 $ linger 0.25 $ n "0 2 [3 4] 2" # sound "arpy"
or slightly more interesting, applied only every fourth cycle:
d1 $ every 4 (linger 0.25) $ n "0 2 [3 4] 2" # sound "arpy"
or to a chopped-up sample:
d1 $ every 2 (linger 0.25) $ loopAt 2 $ chop 8 $ sound "breaks125"
You can also pattern the first parameter, for example to cycle through three values, one per cycle:
d1 $ linger "<0.75 0.25 1>" $ sound "bd sn:2 [mt rs] hc"
d1 $ linger "<0.25 0.5 1>" $ loopAt 2 $ chop 8 $ sound "breaks125"
chunk
Type: chunk :: Int -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b
chunk
divides a pattern into a given number of parts, then cycles through those parts in turn, applying the given function to each part in turn (one part per cycle). Example:
d1 $ chunk 4 (# speed 2) $ sound "bd hh sn cp"
The below highlights in uppercase which part of the above pattern has the (# speed 2) function applied to it over four cycles:
BD hh sn cp
bd HH sn cp
bd hh SN cp
bd hh sn CP
Another example:
d1 $ chunk 4 (hurry 2) $ sound "bd sn:2 [~ bd] sn:2"
chunk'
chunk'
does the same as chunk but cycles through the parts in the reverse direction.
loopFirst
loopFirst
is a function that takes a pattern and loops only the first cycle of the pattern. For example, in the following code will only play the bass drum sample.
d1 $ loopFirst $ s "<<bd*4 ht*8> cp*4>"
This function combines with sometimes to insert events from the first cycle randomly into subsequent cycles of the pattern:
d1 $ sometimes loopFirst $ s "<<bd*4 ht*8> cp*4>"
Shuffling and scrambling
bite
Type: bite :: Int -> Pattern Int -> Pattern a -> Pattern a
The bite
function allows you to slice each cycle into a given number of equal sized bits, and then pattern those bits by number. It's similar to slice
, but is for slicing up patterns, rather than samples. The following slices the pattern into four bits, and then plays those bits in turn.
d1 $ bite 4 "0 1 2 3" $ n "0 .. 7" # sound "arpy"
Of course that doesn't actually change anything, but then you can reorder those bits:
d1 $ bite 4 "2 0 1 3" $ n "0 .. 7" # sound "arpy"
The slices bits of pattern will be squeezed or contracted to fit:
d1 $ bite 4 "2 [0 3] 1*4 1" $ n "0 .. 7" # sound "arpy"
shuffle
Type: shuffle :: Int -> Pattern a -> Pattern a
shuffle
takes a number and a pattern as input, divides the pattern into the given number of parts, and returns a new pattern as a random permutation of the parts, picking one of each per cycle. This could also be called "sampling without replacement". For example:
d1 $ sound $ shuffle 3 "bd sn hh"
... will sometimes play "sn bd hh"
or "hh sn bd"
, but will never play "bd sn bd"
or "hh hh hh"
, because that isn't a permutation of the three parts.
scramble
Type: scramble :: Int -> Pattern a -> Pattern a
scramble
takes a number and a pattern as input, divides the pattern into the given number of parts, and returns a new pattern by randomly selecting from the parts. This could also be called "sampling with replacement". For example:
d1 $ sound $ scramble 3 "bd sn hh"
... will sometimes play "sn bd hh"
or "hh sn bd"
, but can also play "bd sn bd"
or "hh hh hh"
, because it can make any random combination of the three parts.
rot
Type: rot :: Ord a => Pattern Int -> Pattern a -> Pattern a
The rot
function 'rotates' the values in a pattern, while preserving its structure. For example in the following, each value will shift to its neighbour's position one step to the left, so that b
takes the place of a
, a
of c
, and c
of b
:
rot 1 "a ~ b c"
The result is equivalent of:
"b ~ c a"
The first parameter is the number of steps, and may be given as a pattern, for example:
d1 $ rot "<0 0 1 3>" $ n "0 ~ 1 2 0 2 ~ 3*2" # sound "drum"
The above will not rotate the pattern for the first two cycles, will rotate it by one the third cycle, and by three the fourth cycle.
Step sequencers
step
Type: step :: String -> String -> Pattern String
step
acts as a kind of simple step-sequencer using strings. For example, step "sn" "x x 12 "
is equivalent to the pattern of strings given by "sn ~ sn ~ sn:1 sn:2 ~"
. step
substitutes the given string for each x, for each number it substitutes the string followed by a colon and the number, and for everything else it puts in a rest.
In other words, step
generates a pattern of strings in exactly the syntax you'd want for selecting samples and that can be fed directly into the s function.
d1 $ s (step "sn" "x x 12 ")
step'
Type: step' :: [String] -> String -> Pattern String
step'
is like step
but more general, using the numbers in the step-sequencing string as indexes into the list of strings you give it.
d1 $ s (step' ["superpiano","supermandolin"] "0 1 000 1") # sustain 4 # n 0
is equivalent to
d1 $ s "superpiano ~ supermandolin ~ superpiano!3 ~ supermandolin" # sustain 4 # n 0
There is also steps
. You can take a look at this function in the Accumulation
section
lindenmayer
Type: Num b => Int -> String -> String -> [b]
lindenmayer
takes an integer b
, a Lindenmayer system rule set and an initiating string as input in order to generate an L-system tree string of b
iterations. It can be used in conjunction with a step function to convert the generated string into a playable pattern. For example:
d1 $ slow 16 $ sound $ step' ["feel:0", "sn:1", "bd:0"]
(take 512 $ lindenmayer 5 "0:1~~~,1:0~~~2~~~~~0~~~2~,2:2~1~,~:~~1~"
"0")
... generates an L-system with initiating string "0" and maps it onto a list of samples.
Complex L-system trees with many rules and iterations can sometimes result in unwieldy strings. Using take n
to only use the first n
elements of the string, along with a slow
function, can make the generated values more manageable.
Higher-order
spread
Type: spread :: (a -> t -> Pattern b) -> [a] -> t -> Pattern b
The spread
function allows you to take a pattern transformation which takes a parameter, such as slow
, and provide several parameters which are switched between. In other words it 'spreads' a function across several values. Taking a simple high hat loop as an example:
d1 $ sound "ho ho:2 ho:3 hc"
We can speed it up by different amounts, such as by 2x:
d1 $ fast 2 $ sound "ho ho:2 ho:3 hc"
Or by 3x:
d1 $ fast 3 $ sound "ho ho:2 ho:3 hc"
But if we use spread
, we can make a pattern which alternates between the two speeds:
d1 $ spread fast[2,3] $ sound "ho ho:2 ho:3 hc"
Note that many functions now allow pattern input. This is equivalent to the above:
d1 $ fast "<2 3>" $ sound "ho ho:2 ho:3 hc"
Note that if you pass ($
) as the function to spread values over, you can put different functions as the list of values. For example:
d1 $ spread ($) [density 2, rev, slow 2, striate 3, (# speed "0.8")] $ sound "[bd*2 [~ bd]] [sn future]*2 cp jvbass*4"
Above, the pattern will have these transforms applied to it, one at a time, per cycle:
cycle 1: density 2 - pattern will increase in speed
cycle 2: rev - pattern will be reversed
cycle 3: slow 2 - pattern will decrease in speed
cycle 4: striate 3 - pattern will be granualized
cycle 5: (# speed "0.8") - pattern samples will be played back more slowly
After (# speed "0.8")
, the transforms will repeat and start at density 2
again.
(This is the same as slowspread
in earlier versions of TidalCycles.)
spreadf
A convenient shorthand for spread ($
).
fastspread
fastspread
works the same as spread
, but the result is squashed into a single cycle. If you gave four values to spread
, then the result would seem to speed up by a factor of four. Compare these two:
d1 $ spread ($) [gap 4, striate 4] $ sound "ho ho:2 ho:3 hc"
d1 $ fastspread ($) [gap 4, striate 4] $ sound "ho ho:2 ho:3 hc"
spreadChoose
spreadChoose
(alias spreadr
) works the same as spread, but the values are selected at random, one cycle at a time. For example:
d1 $ spreadChoose ($) [gap 4, striate 4] $ sound "ho ho:2 ho:3 hc"