tidal-1.9.5: Pattern language for improvised music
Safe HaskellSafe-Inferred
LanguageHaskell2010

Sound.Tidal.UI

Description

This module provides the main user interface functions, including sources of randomness and transformations of patterns. All these functions are available in the context of the TidalCycles REPL.

Many functions in this module taking Pattern values as arguments have a corresponding function with an underscore prepended to its name (e.g. degradeBy and _degradeBy). These functions accept plain values, not Patterns, and are generally intended for those developing or extending Tidal.

Synopsis

UI

Randomisation

xorwise :: Int -> Int Source #

An implementation of the well-known xorshift random number generator. Given a seed number, generates a reasonably random number out of it. This is an efficient algorithm suitable for use in tight loops and used to implement the below functions, which are used to implement rand.

See George Marsaglia (2003). "Xorshift RNGs", in Journal of Statistical Software, pages 8–14.

timeToRand :: (RealFrac a, Fractional b) => a -> b Source #

timeToRands :: (RealFrac a, Fractional b) => a -> Int -> [b] Source #

rand :: Fractional a => Pattern a Source #

rand is an oscillator that generates a continuous pattern of (pseudo-)random numbers between 0 and 1.

For example, to randomly pan around the stereo field:

d1 $ sound "bd*8" # pan rand

Or to enjoy a randomised speed from 0.5 to 1.5, add 0.5 to it:

d1 $ sound "arpy*4" # speed (rand + 0.5)

To make the snares randomly loud and quiet:

sound "sn sn ~ sn" # gain rand

Numbers coming from this pattern are 'seeded' by time. So if you reset time (using resetCycles, setCycle, or cps) the random pattern will emit the exact same _random_ numbers again.

In cases where you need two different random patterns, you can shift one of them around to change the time from which the _random_ pattern is read, note the difference:

jux (# gain rand) $ sound "sn sn ~ sn" # gain rand

and with the juxed version shifted backwards for 1024 cycles:

jux (# ((1024 <~) $ gain rand)) $ sound "sn sn ~ sn" # gain rand

brand :: Pattern Bool Source #

Boolean rand - a continuous stream of true/false values, with a 50/50 chance.

brandBy :: Pattern Double -> Pattern Bool Source #

Boolean rand with probability as input, e.g. brandBy 0.25 produces trues 25% of the time.

irand :: Num a => Pattern Int -> Pattern a Source #

Just like rand but for whole numbers, irand n generates a pattern of (pseudo-) random whole numbers between 0 to n-1 inclusive. Notably used to pick a random samples from a folder:

d1 $ segment 4 $ n (irand 5) # sound "drum"

_irand :: Num a => Int -> Pattern a Source #

perlinWith :: Fractional a => Pattern Double -> Pattern a Source #

1D Perlin (smooth) noise, works like rand but smoothly moves between random values each cycle. perlinWith takes a pattern as the random number generator's "input" instead of automatically using the cycle count.

d1 $ s "arpy*32" # cutoff (perlinWith (saw * 4) * 2000)

will generate a smooth random pattern for the cutoff frequency which will repeat every cycle (because the saw does).

The perlin function uses the cycle count as input and can be used much like rand.

perlin :: Fractional a => Pattern a Source #

As perlin with a suitable choice of input pattern (sig fromRational).

The perlin function produces a new random value to move to every cycle. If you want a new random value to be generated more or less frequently, you can use fast or slow, respectively:

d1 $ sound "bd*32" # speed (fast 4 $ perlin + 0.5)
d1 $ sound "bd*32" # speed (slow 4 $ perlin + 0.5)

perlin2With :: Pattern Double -> Pattern Double -> Pattern Double Source #

perlin2With is Perlin noise with a 2-dimensional input. This can be useful for more control over how the randomness repeats (or doesn't).

d1
  $ s "[supersaw:-12*32]"
  # lpf (rangex 60 5000 $ perlin2With (cosine*2) (sine*2))
  # lpq 0.3

The above will generate a smooth random cutoff pattern that repeats every cycle without any reversals or discontinuities (because the 2D path is a circle).

See also: perlin2, which only needs one input because it uses the cycle count as the second input.

perlin2 :: Pattern Double -> Pattern Double Source #

As perlin2 with a suitable choice of input pattern (sig fromRational).

choose :: [a] -> Pattern a Source #

Randomly picks an element from the given list.

sound "superpiano(3,8)" # note (choose ["a", "e", "g", "c"])

plays a melody randomly choosing one of the four notes "a", "e", "g", "c".

As with all continuous patterns, you have to be careful to give them structure; in this case choose gives you an infinitely detailed stream of random choices.

choose = 'chooseBy' 'rand'

chooseBy :: Pattern Double -> [a] -> Pattern a Source #

Given a pattern of doubles, chooseBy normalizes them so that each corresponds to an index in the provided list. The returned pattern contains the corresponding elements in the list.

It is like choose, but instead of selecting elements of the list randomly, it uses the given pattern to select elements.

choose = chooseBy rand

The following results in the pattern "a b c":

chooseBy "0 0.25 0.5" ["a","b","c","d"]

wchoose :: [(a, Double)] -> Pattern a Source #

Like choose, but works on an a list of tuples of values and weights

sound "superpiano(3,8)" # note (wchoose [("a",1), ("e",0.5), ("g",2), ("c",1)])

In the above example, the "a" and "c" notes are twice as likely to play as the "e" note, and half as likely to play as the "g" note.

wchoose = 'wchooseBy' 'rand'

wchooseBy :: Pattern Double -> [(a, Double)] -> Pattern a Source #

Given a pattern of probabilities and a list of (value, weight) pairs, wchooseBy creates a Pattern value by choosing values based on those probabilities and weighted appropriately by the weights in the list of pairs.

randcat :: [Pattern a] -> Pattern a Source #

randcat ps: does a slowcat on the list of patterns ps but randomises the order in which they are played.

d1 $ sound (randcat ["bd*2 sn", "jvbass*3", "drum*2", "ht mt"])

wrandcat :: [(Pattern a, Double)] -> Pattern a Source #

As randcat, but allowing weighted choice.

In the following, the first pattern is the most likely and will play about half the time, and the last pattern is the less likely, with only a 10% probability.

d1 $ sound
   $ wrandcat
       [ ("bd*2 sn", 5), ("jvbass*3", 2), ("drum*2", 2), ("ht mt", 1) ]

degrade :: Pattern a -> Pattern a Source #

degrade randomly removes events from a pattern 50% of the time:

d1 $ slow 2 $ degrade $ sound "[[[feel:5*8,feel*3] feel:3*8], feel*4]"
   # accelerate "-6"
   # speed "2"

The shorthand syntax for degrade is a question mark: ?. Using ? will allow you to randomly remove events from a portion of a pattern:

d1 $ slow 2 $ sound "bd ~ sn bd ~ bd? [sn bd?] ~"

You can also use ? to randomly remove events from entire sub-patterns:

d1 $ slow 2 $ sound "[[[feel:5*8,feel*3] feel:3*8]?, feel*4]"

degradeBy :: Pattern Double -> Pattern a -> Pattern a Source #

Similar 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"

You can also invoke this behavior in the shorthand notation by specifying a percentage, as a number between 0 and 1, after the question mark:

d1 $ s "bd hh?0.8 bd hh?0.4"

unDegradeBy :: Pattern Double -> Pattern a -> Pattern a Source #

As degradeBy, but the pattern of probabilities represents the chances to retain rather than remove the corresponding element.

sometimesBy :: Pattern Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

Use sometimesBy to apply a given function "sometimes". For example, the following code results in density 2 being applied about 25% of the time:

d1 $ sometimesBy 0.25 (density 2) $ sound "bd*8"

There are some aliases as well:

sometimes = sometimesBy 0.5
often = sometimesBy 0.75
rarely = sometimesBy 0.25
almostNever = sometimesBy 0.1
almostAlways = sometimesBy 0.9

sometimesBy' :: Pattern Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

As sometimesBy, but applies the given transformation to the pattern in its entirety before filtering its actual appearances. Less efficient than sometimesBy but may be useful when the passed pattern transformation depends on properties of the pattern before probabilities are taken into account.

sometimes' = sometimesBy' 0.5
often' = sometimesBy' 0.75
rarely' = sometimesBy' 0.25
almostNever' = sometimesBy' 0.1
almostAlways' = sometimesBy' 0.9

sometimes :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

sometimes is an alias for sometimesBy 0.5.

sometimes' :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

sometimes' is an alias for sometimesBy' 0.5.

often :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

often is an alias for sometimesBy 0.75.

often' :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

often' is an alias for sometimesBy' 0.75.

rarely :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

rarely is an alias for sometimesBy 0.25.

rarely' :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

rarely' is an alias for sometimesBy' 0.25.

almostNever :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

almostNever is an alias for sometimesBy 0.1.

almostNever' :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

almostNever' is an alias for sometimesBy' 0.1.

almostAlways :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

almostAlways is an alias for sometimesBy 0.9.

almostAlways' :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

almostAlways' is an alias for sometimesBy' 0.9.

never :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

Never apply a transformation, returning the pattern unmodified.

never = flip const

always :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

Apply the transformation to the pattern unconditionally.

always = id

someCyclesBy :: Pattern Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

someCyclesBy is a cycle-by-cycle version of sometimesBy.

For example the following will either distort all of the events in a cycle, or none of them:

d1 $ someCyclesBy 0.5 (# crush 2) $ n "0 1 [~ 2] 3" # sound "arpy"

someCycles :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

someCycles = someCyclesBy 0.5

somecycles :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

Alias of someCycles.

Pattern transformations

Pattern transformations are functions generally of type Pattern a -> Pattern a. This means they take a pattern of any type and return a pattern of that type.

brak :: Pattern a -> Pattern a Source #

brak makes a pattern sound a bit like a breakbeat. It does this by, every other cycle, squashing the pattern to fit half a cycle, and offsetting it by a quarter of a cycle.

d1 $ sound (brak "bd sn kurt")
d1 $ brak $ sound "[feel feel:3, hc:3 hc:2 hc:4 ho:1]"

iter :: Pattern Int -> Pattern c -> Pattern c Source #

Divides a pattern into a given number of subdivisions, plays the subdivisions in order, but increments the starting subdivision each cycle. The pattern wraps to the first subdivision after the last subdivision is played.

Example:

d1 $ iter 4 $ sound "bd hh sn cp"

This will produce the following over four cycles:

bd hh sn cp
hh sn cp bd
sn cp bd hh
cp bd hh sn

There is also iter', which shifts the pattern in the opposite direction.

iter' :: Pattern Int -> Pattern c -> Pattern c Source #

iter' is the same as iter, but decrements the starting subdivision instead of incrementing it. For example,

d1 $ iter' 4 $ sound "bd hh sn cp"

produces

bd hh sn cp
cp bd hh sn
sn cp bd hh
hh sn cp bd

palindrome :: Pattern a -> Pattern a Source #

palindrome p applies rev to p every other cycle, so that the pattern alternates between forwards and backwards. For example, these are equivalent:

d1 $ palindrome $ sound "arpy:0 arpy:1 arpy:2 arpy:3"
d1 $ slow 2 $ sound "arpy:0 arpy:1 arpy:2 arpy:3 arpy:3 arpy:2 arpy:1 arpy:0"
d1 $ every 2 rev $ sound "arpy:0 arpy:1 arpy:2 arpy:3"

fadeOut :: Time -> Pattern a -> Pattern a Source #

Degrades a pattern over the given time.

fadeOutFrom :: Time -> Time -> Pattern a -> Pattern a Source #

Alternate version to fadeOut where you can provide the time from which the fade starts

fadeIn :: Time -> Pattern a -> Pattern a Source #

’Undegrades’ a pattern over the given time.

fadeInFrom :: Time -> Time -> Pattern a -> Pattern a Source #

Alternate version to fadeIn where you can provide the time from which the fade in starts

spread :: (a -> t -> Pattern b) -> [a] -> t -> Pattern b Source #

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 slow it down by different amounts, such as by a half:

d1 $ slow 2 $ sound "ho ho:2 ho:3 hc"

Or by four thirds (i.e. speeding it up by a third; 4%3 means four over three):

d1 $ slow (4%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 slow [2,4%3] $ sound "ho ho:2 ho:3 hc"

Note that if you pass ($) as the function to spread values over, you can put functions as the list of values. (spreadf is an alias for spread ($).) 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.

slowspread :: (a -> t -> Pattern b) -> [a] -> t -> Pattern b Source #

An alias for spread consistent with fastspread.

fastspread :: (a -> t -> Pattern b) -> [a] -> t -> Pattern b Source #

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 chop [4,64,32,16] $ sound "ho ho:2 ho:3 hc"
d1 $ fastspread chop [4,64,32,16] $ sound "ho ho:2 ho:3 hc"

There is also slowspread, which is an alias of spread.

spread' :: Monad m => (a -> b -> m c) -> m a -> b -> m c Source #

There's a version of this function, spread' (pronounced "spread prime"), which takes a pattern of parameters, instead of a list:

d1 $ spread' slow "2 4%3" $ sound "ho ho:2 ho:3 hc"

This is quite a messy area of Tidal—due to a slight difference of implementation this sounds completely different! One advantage of using spread' though is that you can provide polyphonic parameters, e.g.:

d1 $ spread' slow "[2 4%3, 3]" $ sound "ho ho:2 ho:3 hc"

spreadChoose :: (t -> t1 -> Pattern b) -> [t] -> t1 -> Pattern b Source #

spreadChoose f xs p is similar to slowspread but picks values from xs at random, rather than cycling through them in order.

d1 $ spreadChoose ($) [gap 4, striate 4] $ sound "ho ho:2 ho:3 hc"

spreadr :: (t -> t1 -> Pattern b) -> [t] -> t1 -> Pattern b Source #

A shorter alias for spreadChoose.

ifp :: (Int -> Bool) -> (Pattern a -> Pattern a) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

Decide whether to apply one or another function depending on the result of a test function, which is passed the current cycle as a number.

d1 $ ifp ((== 0) . flip mod 2)
         (striate 4)
         (# coarse "24 48")
   $ sound "hh hc"

This will apply striate 4 for every even cycle and apply # coarse "24 48" for every odd.

Detail: As you can see the test function is arbitrary and does not rely on anything Tidal specific. In fact it uses only plain Haskell functionality, that is: it calculates the modulo of 2 of the current cycle which is either 0 (for even cycles) or 1. It then compares this value against 0 and returns the result, which is either True or False. This is what the ifp signature's first part signifies: (Int -> Bool), a function that takes a whole number and returns either True or False.

wedge :: Pattern Time -> Pattern a -> Pattern a -> Pattern a Source #

wedge t p p' combines patterns p and p' by squashing the p into the portion of each cycle given by t, and p' into the remainer of each cycle. > d1 $ wedge (1/4) (sound "bd*2 arpy*3 cp sn*2") (sound "odx [feel future]*2 hh hh")

whenmod :: Pattern Time -> Pattern Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

whenmod has a similar form and behavior to every, but requires an additional number. It applies the function to the pattern when the remainder of the current loop number divided by the first parameter is greater or equal than the second parameter.

For example, the following makes every other block of four loops twice as dense:

d1 $ whenmod 8 4 (density 2) (sound "bd sn kurt")

_whenmod :: Time -> Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

superimpose :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

superimpose f p = stack [p, f p]

superimpose plays a modified version of a pattern at the same time as the original pattern, resulting in two patterns being played at the same time. The following are equivalent:

d1 $ superimpose (fast 2) $ sound "bd sn [cp ht] hh"
d1 $ stack [sound "bd sn [cp ht] hh",
            fast 2 $ sound "bd sn [cp ht] hh"
           ]

More examples:

d1 $ superimpose (density 2) $ sound "bd sn [cp ht] hh"
d1 $ superimpose ((# speed "2") . (0.125 <~)) $ sound "bd sn cp hh"

trunc :: Pattern Time -> Pattern a -> Pattern a Source #

trunc truncates a pattern so that only a fraction of the pattern is played. The following example plays only the first quarter of the pattern:

d1 $ trunc 0.25 $ 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 :: Pattern Time -> Pattern a -> Pattern a Source #

linger is similar to trunc, in that it truncates a pattern so that only the first fraction of the pattern is played, but the truncated part of the pattern loops to fill the remainder of the cycle.

d1 $ linger 0.25 $ sound "bd sn*2 cp hh*4 arpy bd*2 cp bd*2"

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"

If you give it a negative number, it will linger on the last part of the pattern, instead of the start of it. E.g. to linger on the last quarter:

d1 $ linger (-0.25) $ sound "bd sn*2 cp hh*4 arpy bd*2 cp bd*2"

within :: (Time, Time) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

Use within to apply a function to only a part of a pattern. It takes two arguments: a start time and an end time, specified as floats between 0 and 1, which are applied to the relevant pattern. Note that the second argument must be greater than the first for the function to have any effect.

For example, to apply fast 2 to only the first half of a pattern:

d1 $ within (0, 0.5) (fast 2) $ sound "bd*2 sn lt mt hh hh hh hh"

Or, to apply (# speed "0.5") to only the last quarter of a pattern:

d1 $ within (0.75, 1) (# speed "0.5") $ sound "bd*2 sn lt mt hh hh hh hh"

withinArc :: Arc -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

within' :: (Time, Time) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

For many cases, within' will function exactly as within. The difference between the two occurs when applying functions that change the timing of notes such as fast or <~. within first applies the function to all notes in the cycle, then keeps the results in the specified interval, and then combines it with the old cycle (an "apply split combine" paradigm). within' first keeps notes in the specified interval, then applies the function to these notes, and then combines it with the old cycle (a "split apply combine" paradigm).

For example, whereas using the standard version of within

d1 $ within (0, 0.25) (fast 2) $ sound "bd hh cp sd"

sounds like:

d1 $ sound "[bd hh] hh cp sd"

using this alternative version, within'

d1 $ within' (0, 0.25) (fast 2) $ sound "bd hh cp sd"

sounds like:

d1 $ sound "[bd bd] hh cp sd"

revArc :: (Time, Time) -> Pattern a -> Pattern a Source #

Reverse the part of the pattern sliced out by the (start, end) pair.

revArc a = within a rev

euclid :: Pattern Int -> Pattern Int -> Pattern a -> Pattern a Source #

You can use the euclid function to apply a Euclidean algorithm over a complex pattern, although the structure of that pattern will be lost:

d1 $ euclid 3 8 $ sound "bd*2 [sn cp]"

In the above, three sounds are picked from the pattern on the right according to the structure given by the euclid 3 8. It ends up picking two bd sounds, a cp and missing the sn entirely.

A negative first argument provides the inverse of the euclidean pattern.

These types of sequences use "Bjorklund's algorithm", which wasn't made for music but for an application in nuclear physics, which is exciting. More exciting still is that it is very similar in structure to the one of the first known algorithms written in Euclid's book of elements in 300 BC. You can read more about this in the paper The Euclidean Algorithm Generates Traditional Musical Rhythms by Toussaint. Some examples from this paper are included below, including rotation as a third parameter in some cases (see euclidOff).

PatternExample
(2,5)A thirteenth century Persian rhythm called Khafif-e-ramal.
(3,4) The archetypal pattern of the Cumbia from Colombia, as well as a Calypso rhythm from Trinidad.
(3,5,2) Another thirteenth century Persian rhythm by the name of Khafif-e-ramal, as well as a Rumanian folk-dance rhythm.
(3,7)A Ruchenitza rhythm used in a Bulgarian folk-dance.
(3,8)The Cuban tresillo pattern.
(4,7)Another Ruchenitza Bulgarian folk-dance rhythm.
(4,9)The Aksak rhythm of Turkey.
(4,11) The metric pattern used by Frank Zappa in his piece titled Outside Now.
(5,6)Yields the York-Samai pattern, a popular Arab rhythm.
(5,7)The Nawakhat pattern, another popular Arab rhythm.
(5,8)The Cuban cinquillo pattern.
(5,9)A popular Arab rhythm called Agsag-Samai.
(5,11) The metric pattern used by Moussorgsky in Pictures at an Exhibition.
(5,12)The Venda clapping pattern of a South African children’s song.
(5,16)The Bossa-Nova rhythm necklace of Brazil.
(7,8)A typical rhythm played on the Bendir (frame drum).
(7,12)A common West African bell pattern.
(7,16,14)A Samba rhythm necklace from Brazil.
(9,16)A rhythm necklace used in the Central African Republic.
(11,24,14)A rhythm necklace of the Aka Pygmies of Central Africa.
(13,24,5)Another rhythm necklace of the Aka Pygmies of the upper Sangha.

There was once a shorter alias e for this function. It has been removed, but you may see references to it in older Tidal code.

euclidFull :: Pattern Int -> Pattern Int -> Pattern a -> Pattern a -> Pattern a Source #

euclidFull n k pa pb stacks euclid n k pa with euclidInv n k pb. That is, it plays one pattern on the euclidean rhythm and a different pattern on the off-beat.

For example, to implement the traditional flamenco rhythm, you could use hard claps for the former and soft claps for the latter:

d1 $ euclidFull 3 7 "realclaps" ("realclaps" # gain 0.8)

_euclidBool :: Int -> Int -> Pattern Bool Source #

Less expressive than euclid due to its constrained types, but may be more efficient.

euclidOff :: Pattern Int -> Pattern Int -> Pattern Int -> Pattern a -> Pattern a Source #

As euclid, but taking a third rotational parameter corresponding to the onset at which to start the rhythm.

eoff :: Pattern Int -> Pattern Int -> Pattern Int -> Pattern a -> Pattern a Source #

A shorter alias for euclidOff.

euclidOffBool :: Pattern Int -> Pattern Int -> Pattern Int -> Pattern Bool -> Pattern Bool Source #

As euclidOff, but specialized to Bool. May be more efficient than euclidOff.

euclidInv :: Pattern Int -> Pattern Int -> Pattern a -> Pattern a Source #

euclidInv fills in the blanks left by euclid, i.e., it inverts the pattern.

For example, whereas euclid 3 8 "x" produces

"x ~ ~ x ~ ~ x ~"

euclidInv 3 8 "x" produces

"~ x x ~ x x ~ x"

As another example, in

d1 $ stack [ euclid 5 8 $ s "bd"
           , euclidInv 5 8 $ s "hh27"
           ]

the hi-hat event fires on every one of the eight even beats that the bass drum does not.

index :: Real b => b -> Pattern b -> Pattern c -> Pattern c Source #

rot :: Ord a => Pattern Int -> Pattern a -> Pattern a Source #

rot n p "rotates" the values in a pattern p by n beats to the left, 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, in

d1 $ rot "<0 0 1 3>" $ n "0 ~ 1 2 0 2 ~ 3*2" # sound "drum"

the pattern will not be rotated for the first two cycles, but will rotate it by one the third cycle, and by three the fourth cycle.

Additional example:

d1 $ every 4 (rot 2) $ slow 2 $ sound "bd hh hh hh"

_rot :: Ord a => Int -> Pattern a -> Pattern a Source #

Calculates a whole cycle, rotates it, then constrains events to the original query arc.

segment :: Pattern Time -> Pattern a -> Pattern a Source #

segment n p ’samples’ the pattern p at a rate of n events per cycle. Useful for turning a continuous pattern into a discrete one.

In the following example, the pattern originates from the shape of a sine wave, a continuous pattern. Without segment, the samples will get triggered at an undefined frequency which may be very high.

d1 $ n (slow 2 $ segment 16 $ range 0 32 $ sine) # sound "amencutup"

discretise :: Pattern Time -> Pattern a -> Pattern a Source #

discretise: the old (deprecated) name for segment

fit :: Pattern Int -> [a] -> Pattern Int -> Pattern a Source #

The fit function takes a pattern of integer numbers, which are used to select values from the given list. What makes this a bit strange is that only a given number of values are selected each cycle. For example:

d1 $ sound (fit 3 ["bd", "sn", "arpy", "arpy:1", "casio"] "0 [~ 1] 2 1")

The above fits three samples into the pattern, i.e. for the first cycle this will be "bd", "sn" and "arpy", giving the result "bd [~ sn] arpy sn" (note that we start counting at zero, so that 0 picks the first value). The following cycle the next three values in the list will be picked, i.e. "arpy:1", "casio" and "bd", giving the pattern "arpy:1 [~ casio] bd casio" (note that the list wraps round here).

_fit :: Int -> [a] -> Pattern Int -> Pattern a Source #

permstep :: RealFrac b => Int -> [a] -> Pattern b -> Pattern a Source #

struct :: Pattern Bool -> Pattern a -> Pattern a Source #

struct a b structures pattern b in terms of the pattern of boolean values a. Only True values in the boolean pattern are used.

The following are equivalent:

d1 $ struct ("t ~ t*2 ~") $ sound "cp"
d1 $ sound "cp ~ cp*2 ~"

The structure comes from a boolean pattern, i.e. a binary pattern containing true or false values. Above we only used true values, denoted by t. It’s also possible to include false values with f, which struct will simply treat as silence. For example, this would have the same outcome as the above:

d1 $ struct ("t f t*2 f") $ sound "cp"

These true / false binary patterns become useful when you conditionally manipulate them, for example, ‘inverting’ the values using every and inv:

d1 $ struct (every 3 inv "t f t*2 f") $ sound "cp"

In the above, the boolean values will be ‘inverted’ every third cycle, so that the structure comes from the fs rather than t. Note that euclidean patterns also create true/false values, for example:

d1 $ struct (every 3 inv "t(3,8)") $ sound "cp"

In the above, the euclidean pattern creates "t f t f t f f t" which gets inverted to "f t f t f t t f" every third cycle. Note that if you prefer you can use 1 and 0 instead of t and f.

substruct :: Pattern Bool -> Pattern b -> Pattern b Source #

substruct a b: similar to struct, but each event in pattern a gets replaced with pattern b, compressed to fit the timespan of the event.

stripe :: Pattern Int -> Pattern a -> Pattern a Source #

stripe n p: repeats pattern p n times per cycle, i.e., the first parameter gives the number of cycles to operate over. So, it is similar to fast, but with random durations. For example stripe 2 will repeat a pattern twice, over two cycles

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"

The repetitions will be contiguous (touching, but not overlapping) and the durations will add up to a single cycle. n can be supplied as a pattern of integers.

slowstripe :: Pattern Int -> Pattern a -> Pattern a Source #

slowstripe n p is the same as stripe, but the result is also n times slower, so 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).

lindenmayer :: Int -> String -> String -> String Source #

Returns the nth iteration of a Lindenmayer System with given start sequence.

It 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.

lindenmayerI :: Num b => Int -> String -> String -> [b] Source #

lindenmayerI converts the resulting string into a a list of integers with fromIntegral applied (so they can be used seamlessly where floats or rationals are required)

runMarkov :: Int -> [[Double]] -> Int -> Time -> [Int] Source #

runMarkov n tmat xi seed generates a Markov chain (as a list) of length n using the transition matrix tmat starting from initial state xi, starting with random numbers generated from seed Each entry in the chain is the index of state (starting from zero). Each row of the matrix will be automatically normalized. For example: runMarkov 8 [[2,3], [1,3]] 0 0 will produce a two-state chain 8 steps long, from initial state 0, where the transition probability from state 0->0 is 25, 0->1 is 35, 1->0 is 1/4, and 1->1 is 3/4.

markovPat :: Pattern Int -> Pattern Int -> [[Double]] -> Pattern Int Source #

markovPat n xi tp generates a one-cycle pattern of n steps in a Markov chain starting from state xi with transition matrix tp. Each row of the transition matrix is automatically normalized. For example:

>>> markovPat 8 1 [[3,5,2], [4,4,2], [0,1,0]]
(0>⅛)|1
(⅛>¼)|2
(¼>⅜)|1
(⅜>½)|1
(½>⅝)|2
(⅝>¾)|1
(¾>⅞)|1
(⅞>1)|0

mask :: Pattern Bool -> Pattern a -> Pattern a Source #

mask takes a boolean pattern and ‘masks’ another pattern with it. That is, events are only carried over if they match within a ‘true’ event in the binary pattern, i.e., it removes events from the second pattern that don't start during an event from the first.

For example, consider this kind of messy rhythm without any rests.

d1 $ sound (slowcat ["sn*8", "[cp*4 bd*4, hc*5]"]) # n (run 8)

If we apply a mask to it

d1 $ s ( mask ("1 1 1 ~ 1 1 ~ 1" :: Pattern Bool)
         ( slowcat ["sn*8", "[cp*4 bd*4, bass*5]"] )
       )
  # n (run 8)

Due to the use of slowcat here, the same mask is first applied to "sn*8" and in the next cycle to "[cp*4 bd*4, hc*5]".

You could achieve the same effect by adding rests within the slowcat patterns, but mask allows you to do this more easily. It kind of keeps the rhythmic structure and you can change the used samples independently, e.g.,

d1 $ s ( mask ("1 ~ 1 ~ 1 1 ~ 1")
         ( slowcat ["can*8", "[cp*4 sn*4, jvbass*16]"] )
       )
  # n (run 8)

stretch :: Pattern a -> Pattern a Source #

stretch takes a pattern, and if there’s silences at the start or end of the current cycle, it will zoom in to avoid them. The following are equivalent:

d1 $ note (stretch "~ 0 1 5 8*4 ~") # s "superpiano"
d1 $ note "0 1 5 8*4" # s "superpiano"

You can pattern silences on the extremes of a cycle to make changes to the rhythm:

d1 $ note (stretch "~ <0 ~> 1 5 8*4 ~") # s "superpiano"

fit' :: Pattern Time -> Int -> Pattern Int -> Pattern Int -> Pattern a -> Pattern a Source #

fit' is a generalization of fit, where the list is instead constructed by using another integer pattern to slice up a given pattern. The first argument is the number of cycles of that latter pattern to use when slicing. It's easier to understand this with a few examples:

d1 $ sound (fit' 1 2 "0 1" "1 0" "bd sn")

So what does this do? The first 1 just tells it to slice up a single cycle of "bd sn". The 2 tells it to select two values each cycle, just like the first argument to fit. The next pattern "0 1" is the "from" pattern which tells it how to slice, which in this case means "0" maps to "bd", and "1" maps to "sn". The next pattern "1 0" is the "to" pattern, which tells it how to rearrange those slices. So the final result is the pattern "sn bd".

A more useful example might be something like

d1 $ fit' 1 4 (run 4) "[0 3*2 2 1 0 3*2 2 [1*8 ~]]/2"
   $ chop 4
   $ (sound "breaks152" # unit "c")

which uses chop to break a single sample into individual pieces, which fit' then puts into a list (using the run 4 pattern) and reassembles according to the complicated integer pattern.

chunk :: Pattern Int -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b Source #

Treats the given pattern p as having n chunks, and applies the function f to one of those sections per cycle. Running: - from left to right if chunk number is positive - from right to left if chunk number is negative

d1 $ chunk 4 (fast 4) $ sound "cp sn arpy [mt lt]"

The following:

d1 $ chunk 4 (# speed 2) $ sound "bd hh sn cp"

applies (# speed 2) to the uppercased part of the cycle below:

BD hh sn cp
bd HH sn cp
bd hh SN cp
bd hh sn CP

_chunk :: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b Source #

chunk' :: Integral a1 => Pattern a1 -> (Pattern a2 -> Pattern a2) -> Pattern a2 -> Pattern a2 Source #

DEPRECATED, use chunk with negative numbers instead

_chunk' :: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b Source #

DEPRECATED, use _chunk with negative numbers instead

inside :: Pattern Time -> (Pattern a1 -> Pattern a) -> Pattern a1 -> Pattern a Source #

inside carries out an operation inside a cycle. For example, while rev "0 1 2 3 4 5 6 7" is the same as "7 6 5 4 3 2 1 0", inside 2 rev "0 1 2 3 4 5 6 7" gives "3 2 1 0 7 6 5 4".

What this function is really doing is ‘slowing down’ the pattern by a given factor, applying the given function to it, and then ‘speeding it up’ by the same factor. In other words, this:

inside 2 rev "0 1 2 3 4 5 6 7"

Is doing this:

fast 2 $ rev $ slow 2 "0 1 2 3 4 5 6 7"

so rather than whole cycles, each half of a cycle is reversed.

_inside :: Time -> (Pattern a1 -> Pattern a) -> Pattern a1 -> Pattern a Source #

outside :: Pattern Time -> (Pattern a1 -> Pattern a) -> Pattern a1 -> Pattern a Source #

outside is the inverse of the inside function. outside applies its function outside the cycle. Say you have a pattern that takes 4 cycles to repeat and apply the rev function:

d1 $ rev $ cat [s "bd bd sn",s "sn sn bd", s"lt lt sd", s "sd sd bd"]

The above generates:

d1 $ rev $ cat [s "sn bd bd",s "bd sn sn", s "sd lt lt", s "bd sd sd"]

However if you apply outside:

d1 $ outside 4 (rev) $ cat [s "bd bd sn",s "sn sn bd", s"lt lt sd", s "sd sd bd"]

The result is:

d1 $ rev $ cat [s "bd sd sd", s "sd lt lt", s "sn sn bd", s "bd bd sn"]

Notice that the whole idea has been reversed. What this function is really doing is ‘speeding up’ the pattern by a given factor, applying the given function to it, and then ‘slowing it down’ by the same factor. In other words, this:

d1 $ slow 4 $ rev $ fast 4
   $ cat [s "bd bd sn",s "sn sn bd", s"lt lt sd", s "sd sd bd"]

This compresses the idea into a single cycle before rev operates and then slows it back to the original speed.

_outside :: Time -> (Pattern a1 -> Pattern a) -> Pattern a1 -> Pattern a Source #

loopFirst :: Pattern a -> Pattern a Source #

Takes a pattern and loops only the first cycle of the pattern. For example, 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>"

seqPLoop :: [(Time, Time, Pattern a)] -> Pattern a Source #

seqPLoop will keep looping the sequence when it gets to the end:

d1 $ qtrigger $ seqPLoop
  [ (0, 12, sound "bd bd*2")
  , (4, 12, sound "hh*2 [sn cp] cp future*4")
  , (8, 12, sound (samples "arpy*8" (run 16)))
  ]

toScale :: Num a => [a] -> Pattern Int -> Pattern a Source #

toScale lets you turn a pattern of notes within a scale (expressed as a list) to note numbers.

For example:

toScale [0, 4, 7] "0 1 2 3"

will turn into the pattern "0 4 7 12".

toScale is handy for quickly applying a scale without naming it:

d1 $ n (toScale [0,2,3,5,7,8,10] "0 1 2 3 4 5 6 7") # sound "superpiano"

This function assumes your scale fits within an octave; if that's not true, use toScale'.

toScale = toScale' 12

toScale' :: Num a => Int -> [a] -> Pattern Int -> Pattern a Source #

As toScale, though allowing scales of arbitrary size.

An example: toScale' 24 [0,4,7,10,14,17] (run 8) turns into "0 4 7 10 14 17 24 28".

swingBy :: Pattern Time -> Pattern Time -> Pattern a -> Pattern a Source #

swingBy x n divides a cycle into n slices and delays the notes in the second half of each slice by x fraction of a slice. So if x is 0 it does nothing, 0.5 delays for half the note duration, and 1 will wrap around to doing nothing again. The end result is a shuffle or swing-like rhythm. For example, the following will delay every other "hh" 1/3 of the way to the next "hh":

d1 $ swingBy (1/3) 4 $ sound "hh*8"

swing :: Pattern Time -> Pattern a -> Pattern a Source #

As swingBy, with the cycle division set to ⅓.

cycleChoose :: [a] -> Pattern a Source #

cycleChoose is like choose but only picks a new item from the list once each cycle.

d1 $ sound "drum ~ drum drum" # n (cycleChoose [0,2,3])

_rearrangeWith :: Pattern Int -> Int -> Pattern a -> Pattern a Source #

Internal function used by shuffle and scramble

shuffle :: Pattern Int -> Pattern a -> Pattern a Source #

shuffle n p evenly divides one cycle of the pattern p into n parts, and returns a random permutation of the parts each cycle. For example, shuffle 3 "a b c" could return "a b c", "a c b", "b a c", "b c a", "c a b", or "c b a". But it will never return "a a a", because that is not a permutation of the parts.

This could also be called “sampling without replacement”.

scramble :: Pattern Int -> Pattern a -> Pattern a Source #

scramble n p is like shuffle but randomly selects from the parts of p instead of making permutations. For example, scramble 3 "a b c" will randomly select 3 parts from "a" "b" and "c", possibly repeating a single part.

This could also be called “sampling with replacement”.

randrun :: Int -> Pattern Int Source #

randrun n generates a pattern of random integers less than n.

The following plays random notes in an octave:

d1 $ s "superhammond!12" # n (fromIntegral $ randrun 13)

Composing patterns

seqP :: [(Time, Time, Pattern a)] -> Pattern a Source #

The function seqP allows you to define when a sound within a list starts and ends. The code below contains three separate patterns in a stack, but each has different start times (zero cycles, eight cycles, and sixteen cycles, respectively). All patterns stop after 128 cycles:

d1 $ seqP [
  (0, 128, sound "bd bd*2"),
  (8, 128, sound "hh*2 [sn cp] cp future*4"),
  (16, 128, sound (samples "arpy*8" (run 16)))
]

ur :: Time -> Pattern String -> [(String, Pattern a)] -> [(String, Pattern a -> Pattern a)] -> Pattern a Source #

The ur function is designed for longer form composition, by allowing you to create ‘patterns of patterns’ in a repeating loop. It takes four parameters: how long the loop will take, a pattern giving the structure of the composition, a lookup table for named patterns to feed into that structure, and a second lookup table for named transformations/effects.

The ur- prefix comes from German and means proto- or original. For a mnemonic device, think of this function as assembling a set of original patterns (ur-patterns) into a larger, newer whole.

Lets say you had three patterns (called a, b and c), and that you wanted to play them four cycles each, over twelve cycles in total. Here is one way to do it:

let pats =
  [ ( "a", stack [ n "c4 c5 g4 f4 f5 g4 e5 g4" # s "superpiano" # gain "0.7"
                 , n "[c3,g4,c4]" # s "superpiano"# gain "0.7"
                 ]
    )
  , ( "b", stack [ n "d4 c5 g4 f4 f5 g4 e5 g4" # s "superpiano" # gain "0.7"
                 , n "[d3,a4,d4]" # s "superpiano"# gain "0.7"
                 ]
    )
  , ( "c", stack [ n "f4 c5 g4 f4 f5 g4 e5 g4" # s "superpiano" # gain "0.7"
                 , n "[f4,c5,f4]" # s "superpiano"# gain "0.7"
                 ]
    )
  ]
in
d1 $ ur 12 "a b c" pats []

In the above, the fourth parameter is given as an empty list, but that is where you can put another lookup table, of functions rather than patterns this time. For example:

let
  pats = ...
  fx   = [ ("reverb", ( # (room 0.8 # sz 0.99 # orbit 1)))
         , ("faster", fast 2)
         ]
in
d1 $ ur 12 "a b:reverb c:faster" pats fx

In this example, b has the function applied that’s named as reverb, while c is made to go faster. It’s also possible to schedule multiple patterns at once, like in the following:

let pats = [ ("drums", s "drum cp*2")
           , ("melody", s "arpy:2 arpy:3 arpy:5")
           , ("craziness", s "cp:4*8" # speed ( sine + 0.5 ))
           ]
    fx = [("higher", ( # speed 2))]
in
d1 $ ur 8 "[drums, melody] [drums,craziness,melody] melody:higher" pats fx

inhabit :: [(String, Pattern a)] -> Pattern String -> Pattern a Source #

A simpler version of ur that just provides name-value bindings that are reflected in the provided pattern.

inhabit allows you to link patterns to some String, or in other words, to give patterns a name and then call them from within another pattern of Strings.

For example, we can make our own bassdrum, hi-hat and snaredrum kit:

do
  let drum = inhabit [ ("bd", s "sine" |- accelerate 1.5)
                     , ("hh", s "alphabet:7" # begin 0.7 # hpf 7000)
                     , ("sd", s "invaders:3" # speed 12)
                     ]
  d1 $ drum "[bd*8?, [~hh]*4, sd(6,16)]"

inhabit can be very useful when using MIDI controlled drum machines, since you can give understandable drum names to patterns of notes.

spaceOut :: [Time] -> Pattern a -> Pattern a Source #

spaceOut xs p repeats a Pattern p at different durations given by the list of time values in xs.

flatpat :: Pattern [a] -> Pattern a Source #

flatpat takes a Pattern of lists and pulls the list elements as separate EventFs. For example, the following code uses flatpat in combination with listToPat to create an alternating pattern of chords:

d1 $ n (flatpat $ listToPat [[0,4,7],[(-12),(-8),(-5)]])
   # s "superpiano" # sustain 2

This code is equivalent to:

d1 $ n ("[0,4,7] [-12,-8,-5]") # s "superpiano" # sustain 2

layer :: [a -> Pattern b] -> a -> Pattern b Source #

layer takes a list of Pattern-returning functions and a seed element, stacking the result of applying the seed element to each function in the list.

It allows you to layer up multiple functions on one pattern. For example, the following will play two versions of the pattern at the same time, one reversed and one at twice the speed:

d1 $ layer [rev, fast 2] $ sound "arpy [~ arpy:4]"

The original version of the pattern can be included by using the id function:

d1 $ layer [id, rev, fast 2] $ sound "arpy [~ arpy:4]"

arpeggiate :: Pattern a -> Pattern a Source #

arpeggiate finds events that share the same timespan, and spreads them out during that timespan, so for example arpeggiate "[bd,sn]" gets turned into "bd sn". Useful for creating arpeggios/broken chords.

arpg :: Pattern a -> Pattern a Source #

Shorthand alias for arpeggiate

arpWith :: ([EventF (ArcF Time) a] -> [EventF (ArcF Time) b]) -> Pattern a -> Pattern b Source #

arp :: Pattern String -> Pattern a -> Pattern a Source #

The arp function takes an additional pattern of arpeggiate modes. For example:

d1 $ sound "superpiano" # n (arp "down diverge" "e'7sus4'8")

The different arpeggiate modes are: up down updown downup up&down down&up converge diverge disconverge pinkyup pinkyupdown thumbup thumbupdown

rolled :: Pattern a -> Pattern a Source #

rolled plays each note of a chord quickly in order, as opposed to simultaneously; to give a chord a harp-like or strum effect.

Notes are played low to high, and are evenly distributed within (14) of the chord event length, as opposed to arparpeggiate that spread the notes over the whole event.

rolled $ n "cmaj4" # s "superpiano"
rolled = rolledBy (1/4)

ply :: Pattern Rational -> Pattern a -> Pattern a Source #

ply n repeats each event n times within its arc.

For example, the following are equivalent:

d1 $ ply 3 $ s "bd ~ sn cp"
d1 $ s "[bd bd bd] ~ [sn sn sn] [cp cp cp]"

The first parameter may be given as a pattern, so that the following are equivalent:

d1 $ ply "2 3" $ s "bd ~ sn cp"
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"

plyWith :: (Ord t, Num t) => Pattern t -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

As ply, but applies a function each time. The applications are compounded.

_plyWith :: (Ord t, Num t) => t -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

press :: Pattern a -> Pattern a Source #

Syncopates a rhythm, shifting (delaying) each event halfway into its arc (timespan).

In mini-notation terms, it basically turns every instance of a into [~ a], e.g., "a b [c d] e" becomes the equivalent of "[~ a] [~ b] [[~ c] [~ d]] [~ e]". Every beat then becomes an offbeat, and so the overall effect is to syncopate a pattern.

In the following example, you can hear that the piano chords play between the snare and the bass drum. In 4/4 time, they are playing in the 2 and a half, and 4 and a half beats:

do
  resetCycles
  d1 $ stack [
    press $ n "~ c'maj ~ c'maj" # s "superpiano" # gain 0.9 # pan 0.6,
    s "[bd,clap sd bd sd]" # pan 0.4
    ] # cps (90/60/4)

In the next example, the C major chord plays before the G major. As the slot that occupies the C chord is that of one eighth note, it is displaced by press only a sixteenth note:

do
  resetCycles
  d1 $ stack [
    press $ n "~ [c'maj ~] ~ ~" # s "superpiano" # gain 0.9 # pan 0.6,
    press $ n "~ g'maj ~ ~" # s "superpiano" # gain 0.9 # pan 0.4,
    s "[bd,clap sd bd sd]"
   ] # cps (90/60/4)

pressBy :: Pattern Time -> Pattern a -> Pattern a Source #

Like press, but allows you to specify the amount in which each event is shifted as a float from 0 to 1 (exclusive).

pressBy 0.5 is the same as press, while pressBy (1/3) shifts each event by a third of its arc.

You can pattern the displacement to create interesting rhythmic effects:

d1 $ stack [
  s "bd sd bd sd",
  pressBy "<0 0.5>" $ s "co:2*4"
]
d1 $ stack [
  s "[bd,co sd bd sd]",
  pressBy "<0 0.25 0.5 0.75>" $ s "cp"
]

stitch :: Pattern Bool -> Pattern a -> Pattern a -> Pattern a Source #

Uses the first (binary) pattern to switch between the following two patterns. The resulting structure comes from the binary pattern, not the source patterns. (In sew, by contrast, the resulting structure comes from the source patterns.)

The following uses a euclidean pattern to control CC0:

d1 $ ccv (stitch "t(7,16)" 127 0) # ccn 0  # "midi"

while :: Pattern Bool -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

A binary pattern is used to conditionally apply a function to a source pattern. The function is applied when a True value is active, and the pattern is let through unchanged when a False value is active. No events are let through where no binary values are active.

stutter :: Integral i => i -> Time -> Pattern a -> Pattern a Source #

stutter n t pat repeats each event in pat n times, separated by t time (in fractions of a cycle). It is like echo that doesn't reduce the volume, or ply if you controlled the timing.

d1 $ stutter 4 (1/16) $ s "bd cp"

is functionally equivalent to

d1 $ stut 4 1 (1/16) $ s "bd cp"

jux :: (Pattern ValueMap -> Pattern ValueMap) -> Pattern ValueMap -> Pattern ValueMap Source #

The jux function creates strange stereo effects by applying a function to a pattern, but only in the right-hand channel. For example, the following reverses the pattern on the righthand side:

d1 $ slow 32 $ jux (rev) $ striateBy 32 (1/16) $ sound "bev"

When passing pattern transforms to functions like jux and every, it's possible to chain multiple transforms together with . (function composition). For example this both reverses and halves the playback speed of the pattern in the righthand channel:

d1 $ slow 32 $ jux ((# speed "0.5") . rev) $ striateBy 32 (1/16) $ sound "bev"

jux' :: [t -> Pattern ValueMap] -> t -> Pattern ValueMap Source #

In addition to jux, jux' allows using a list of pattern transformations. Resulting patterns from each transformation will be spread via pan from left to right.

For example, the following will put iter 4 of the pattern to the far left and palindrome to the far right. In the center, the original pattern will play and the chopped and the reversed version will appear mid left and mid right respectively.

d1 $ jux' [iter 4, chop 16, id, rev, palindrome] $ sound "bd sn"

One could also write:

d1 $ stack
      [ iter 4 $ sound "bd sn" # pan "0"
      , chop 16 $ sound "bd sn" # pan "0.25"
      , sound "bd sn" # pan "0.5"
      , rev $ sound "bd sn" # pan "0.75"
      , palindrome $ sound "bd sn" # pan "1"
      ]

jux4 :: (Pattern ValueMap -> Pattern ValueMap) -> Pattern ValueMap -> Pattern ValueMap Source #

Multichannel variant of jux, not sure what it does

juxBy :: Pattern Double -> (Pattern ValueMap -> Pattern ValueMap) -> Pattern ValueMap -> Pattern ValueMap Source #

With jux, the original and effected versions of the pattern are panned hard left and right (i.e., panned at 0 and 1). This can be a bit much, especially when listening on headphones. The variant juxBy has an additional parameter, which brings the channel closer to the centre. For example:

d1 $ juxBy 0.5 (fast 2) $ sound "bd sn:1"

In the above, the two versions of the pattern would be panned at 0.25 and 0.75, rather than 0 and 1.

pick :: String -> Int -> String Source #

Given a sample's directory name and number, this generates a string suitable to pass to fromString to create a 'Pattern String'. samples is a Pattern-compatible interface to this function.

pick name n = name ++ ":" ++ show n

samples :: Applicative f => f String -> f Int -> f String Source #

Given a pattern of sample directory names and a of pattern indices create a pattern of strings corresponding to the sample at each name-index pair.

An example:

samples "jvbass [~ latibro] [jvbass [latibro jvbass]]"
        ((1%2) `rotL` slow 6 "[1 6 8 7 3]")

The type signature is more general here, but you can consider this to be a function of type Pattern String -> Pattern Int -> Pattern String.

samples = liftA2 pick

samples' :: Applicative f => f String -> f Int -> f String Source #

Equivalent to samples, though the sample specifier pattern (the f Int) will be evaluated first. Not a large difference in the majority of cases.

spreadf :: [a -> Pattern b] -> a -> Pattern b Source #

range :: Num a => Pattern a -> Pattern a -> Pattern a -> Pattern a Source #

range will take a pattern which goes from 0 to 1 (like sine), and range it to a different range - between the first and second arguments. In the below example, `range 1 1.5` shifts the range of sine1 from 0 - 1 to 1 - 1.5.

d1 $ jux (iter 4) $ sound "arpy arpy:2*2"
  |+ speed (slow 4 $ range 1 1.5 sine1)

The above is equivalent to:

d1 $ jux (iter 4) $ sound "arpy arpy:2*2"
  |+ speed (slow 4 $ sine1 * 0.5 + 1)

_range :: (Functor f, Num b) => b -> b -> f b -> f b Source #

rangex :: (Functor f, Floating b) => b -> b -> f b -> f b Source #

rangex is an exponential version of range, good for using with 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.

off :: Pattern Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

off is similar to superimpose, in that it applies a function to a pattern and layers up the results on top of the original pattern. The difference is that off takes an extra pattern being a time (in cycles) to shift the transformed version of the pattern by.

The following plays a pattern on top of itself, but offset by an eighth of a cycle, with a distorting bitcrush effect applied:

d1 $ off 0.125 (# crush 2) $ sound "bd [~ sn:2] mt lt*2"

The following makes arpeggios by adding offset patterns that are shifted up the scale:

d1 $ slow 2
   $ n (off 0.25 (+12)
   $ off 0.125 (+7)
   $ slow 2 "c(3,8) a(3,8,2) f(3,8) e(3,8,4)")
   # sound "superpiano"

_off :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

step :: String -> String -> Pattern String Source #

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 ")

steps :: [(String, String)] -> Pattern String Source #

steps is like step but it takes a list of pairs, like step would, and it plays them all simultaneously.

d1 $ s (steps [("cp","x  x x  x x  x"),("bd", "xxxx")])

step' :: [String] -> String -> Pattern String Source #

like step, but allows you to specify an array of strings to use for 0,1,2... For example,

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

ghost'' :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

Deprecated backwards-compatible alias for ghostWith.

ghostWith :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

Like ghost', but a user-supplied function describes how to alter the pattern.

In this example, ghost notes are applied to the snare hit, but these notes will be louder, not quieter, and the sample will have its beginning slightly cut:

d1 $ slow 2
   $ ghostWith (1/16) ((|*| gain 1.1) . (|> begin 0.05))
   $ sound "sn"

ghost :: Pattern ValueMap -> Pattern ValueMap Source #

As ghost', but with the copies set to appear one-eighth of a cycle afterwards.

ghost = ghost' 0.125

The following creates a kick snare pattern with ghost notes applied to the snare hit:

d1 $ stack [ ghost $ sound "~ sn", sound "bd*2 [~ bd]" ]

tabby :: Int -> Pattern a -> Pattern a -> Pattern a Source #

A more literal weaving than the weave function. Given tabby threads p1 p, parameters representing the threads per cycle and the patterns to weave, and this function will weave them together using a plain (aka ’tabby’) weave, with a simple over/under structure

select :: Pattern Double -> [Pattern a] -> Pattern a Source #

Chooses from a list of patterns, using a pattern of floats (from 0 to 1).

selectF :: Pattern Double -> [Pattern a -> Pattern a] -> Pattern a -> Pattern a Source #

Chooses from a list of functions, using a pattern of floats (from 0 to 1).

pickF :: Pattern Int -> [Pattern a -> Pattern a] -> Pattern a -> Pattern a Source #

Chooses from a list of functions, using a pattern of integers.

_pickF :: Int -> [Pattern a -> Pattern a] -> Pattern a -> Pattern a Source #

contrast :: (ControlPattern -> ControlPattern) -> (ControlPattern -> ControlPattern) -> ControlPattern -> ControlPattern -> ControlPattern Source #

contrast f f' p p' splits the control pattern p' in two, applying the function f to one and f' to the other. This depends on whether events in p' contain values matching with those in p. For example, in

contrast (# crush 3) (# vowel "a") (n "1") $ n "0 1" # s "bd sn" # speed 3

the first event will have the vowel effect applied and the second will have the crush applied.

contrast is like an if-else-statement over patterns. For contrast t f p you can think of t as the true branch, f as the false branch, and p as the test.

You can use any control pattern as a test of equality, e.g., n "1", speed "0.5", or things like that. This lets you choose specific properties of the pattern you’re transforming for testing, like in the following example,

d1 $ contrast (|+ n 12) (|- n 12) (n "c") $ n (run 4) # s "superpiano"

where every note that isn’t middle-c will be shifted down an octave but middle-c will be shifted up to c5.

Since the test given to contrast is also a pattern, you can do things like have it alternate between options:

d1 $ contrast (|+ n 12) (|- n 12) (s "<superpiano superchip>")
   $ s "superpiano superchip" # n 0

If you listen to this you’ll hear that which instrument is shifted up and which instrument is shifted down alternates between cycles.

contrastBy :: (a -> Value -> Bool) -> (ControlPattern -> Pattern b) -> (ControlPattern -> Pattern b) -> Pattern (Map String a) -> Pattern (Map String Value) -> Pattern b Source #

contrastBy is contrastBy is the general version of contrast, in which you can specify an abritrary boolean function that will be used to compare the control patterns.

d2 $ contrastBy (>=) (|+ n 12) (|- n 12) (n "2") $ n "0 1 2 [3 4]" # s "superpiano"

fix :: (ControlPattern -> ControlPattern) -> ControlPattern -> ControlPattern -> ControlPattern Source #

The fix function applies another function to matching events in a pattern of controls. fix is contrast where the false-branching function is set to the identity id. It is like contrast, but one function is given and applied to events with matching controls.

For example, the following only adds the crush control when the n control is set to either 1 or 4:

d1 $ slow 2
   $ fix (# crush 3) (n "[1,4]")
   $ n "0 1 2 3 4 5 6"
   # sound "arpy"

You can be quite specific; for example, the following applies the function hurry 2 to sample 1 of the drum sample set, and leaves the rest as they are:

fix (hurry 2) (s "drum" # n "1")

unfix :: (ControlPattern -> ControlPattern) -> ControlPattern -> ControlPattern -> ControlPattern Source #

Like contrast, but one function is given, and applied to events with controls which don't match. unfix is fix but only applies when the testing pattern is not a match.

fixRange :: (ControlPattern -> Pattern ValueMap) -> Pattern (Map String (Value, Value)) -> ControlPattern -> ControlPattern Source #

The fixRange function isn’t very user-friendly at the moment, but you can create a fix variant with a range condition. Any value of a ControlPattern wich matches the values will apply the passed function.

d1 $ ( fixRange ( (# distort 1) . (# gain 0.8) )
                ( pure $ Map.singleton "note" ((VN 0, VN 7)) )
     )
   $ s "superpiano"
  <| note "1 12 7 11"

quantise :: (Functor f, RealFrac b) => b -> f b -> f b Source #

quantise limits values in a Pattern (or other Functor) to n equally spaced divisions of 1.

It 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.

qfloor :: (Functor f, RealFrac b) => b -> f b -> f b Source #

As quantise, but uses floor to calculate divisions.

qceiling :: (Functor f, RealFrac b) => b -> f b -> f b Source #

As quantise, but uses ceiling to calculate divisions.

qround :: (Functor f, RealFrac b) => b -> f b -> f b Source #

An alias for quantise.

inv :: Functor f => f Bool -> f Bool Source #

Inverts all the values in a boolean pattern

mono :: Pattern a -> Pattern a Source #

Serialises a pattern so there's only one event playing at any one time, making it monophonic. Events which start/end earlier are given priority.

smooth :: Fractional a => Pattern a -> Pattern a Source #

smooth receives a pattern of numbers and linearly goes from one to the next, passing through all of them. As time is cycle-based, after reaching the last number in the pattern, it will smoothly go to the first one again.

d1 $ sound "bd*4" # pan (slow 4 $ smooth "0 1 0.5 1")

This sound will pan gradually from left to right, then to the center, then to the right again, and finally comes back to the left.

swap :: Eq a => [(a, b)] -> Pattern a -> Pattern b Source #

Looks up values from a list of tuples, in order to swap values in the given pattern

snowball :: Int -> (Pattern a -> Pattern a -> Pattern a) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

snowball takes a function that can combine patterns (like +), a function that transforms a pattern (like slow), a depth, and a starting pattern, it will then transform the pattern and combine it with the last transformation until the depth is reached. This is like putting an effect (like a filter) in the feedback of a delay line; each echo is more affected.

d1 $ note ( scale "hexDorian"
          $ snowball 8 (+) (slow 2 . rev) "0 ~ . -1 . 5 3 4 . ~ -2"
          )
   # s "gtr"

soak :: Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a Source #

Applies a function to a pattern and cats the resulting pattern, then continues applying the function until the depth is reached this can be used to create a pattern that wanders away from the original pattern by continually adding random numbers.

d1 $ note ( scale "hexDorian" mutateBy (+ (range -1 1 $ irand 2)) 8
          $ "0 1 . 2 3 4"
          )
   # s "gtr"

deconstruct :: Int -> Pattern String -> String Source #

construct n p breaks p into pieces and then reassembles them so that it fits into n steps.

bite :: Pattern Int -> Pattern Int -> Pattern a -> Pattern a Source #

bite n ipat pat slices a pattern pat into n pieces, then uses the ipat pattern of integers to index into those slices. So bite 4 "0 2*2" (run 8) is the same as "[0 1] [4 5]*2".

I.e., it 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"

squeeze :: Pattern Int -> [Pattern a] -> Pattern a Source #

Chooses from a list of patterns, using a pattern of integers.

chew :: Pattern Int -> Pattern Int -> ControlPattern -> ControlPattern Source #

chew works the same as bite, but speeds up/slows down playback of sounds as well as squeezing/contracting the slices of the provided pattern. Compare:

d1 $ 'bite' 4 "0 1*2 2*2 [~ 3]" $ n "0 .. 7" # sound "drum"
d1 $ chew 4 "0 1*2 2*2 [~ 3]" $ n "0 .. 7" # sound "drum"

__binary :: Bits b => Int -> b -> [Bool] Source #

_binary :: Bits b => Int -> b -> Pattern Bool Source #

grain :: Pattern Double -> Pattern Double -> ControlPattern Source #

Given a start point and a duration (both specified in cycles), this generates a control pattern that makes a sound begin at the start point and last the duration.

The following are equivalent:

d1 $ slow 2 $ s "bev" # grain 0.2 0.1 # legato 1
d1 $ slow 2 $ s "bev" # begin 0.2 # end 0.3 # legato 1

grain is defined as:

grain s d = 'Sound.Tidal.Params.begin' s # 'Sound.Tidal.Params.end' (s+d)

necklace :: Rational -> [Int] -> Pattern Bool Source #

For specifying a boolean pattern according to a list of offsets (aka inter-onset intervals). For example necklace 12 [4,2] is the same as "t f f f t f t f f f t f". That is, 12 steps per cycle, with true values alternating between every 4 and every 2 steps.