HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Moduletidal-1.9.5Haskell2010

Sound.Tidal.Pattern

  • 9 types
  • 3 classes
  • 105 values
  • Packagetidal-1.9.5
  • Exports117
  • LanguageHaskell2010
  • LicenceGPL-3.0-only
  • SourcePattern.hs
datadata Pattern a
#

A datatype representing events taking place over time

Constructors

Instances22Monad, Functor, Applicative, Enum, Eq, Floating, …
datadata Context
#

Some context for an event, currently just position within sourcecode

Constructors

Instances6Eq, Ord, Show, Generic, NFData, Rep
valuerev :: Pattern a -> Pattern a
#

rev p returns p with the event positions in each cycle reversed (or mirrored).

For example rev "1 [~ 2] ~ 3" is equivalent to rev "3 ~ [2 ~] 1".

Note that rev reverses on a cycle-by-cycle basis. This means that rev (slow 2 "1 2 3 4") would actually result in (slow 2 "2 1 4 3"). This is because the slow 2 makes the repeating pattern last two cycles, each of which is reversed independently.

In practice rev is generally used with conditionals, for example with every:

d1 $ every 3 rev $ n "0 1 [~ 2] 3" # sound "arpy"

or jux:

d1 $ jux rev $ n (iter 4 "0 1 [~ 2] 3") # sound "arpy"
datadata EventF a b
#

An event is a value that's active during a timespan. If a whole is present, the part should be equal to or fit inside it.

Constructors

Instances7Functor, Show, Eq, Ord, Generic, NFData, …
valuesqueezeJoin :: Pattern (Pattern a) -> Pattern a
#

Like unwrap, but cycles of the inner patterns are compressed to fit the timespan of the outer whole (or the original query if it's a continuous pattern?) TODO - what if a continuous pattern contains a discrete one, or vice-versa?

valueunwrap :: Pattern (Pattern a) -> Pattern a
#

Turns a pattern of patterns into a single pattern. (this is actually join)

1/ For query arc, get the events from the outer pattern pp 2/ Query the inner pattern using the part of the outer 3/ For each inner event, set the whole and part to be the intersection of the outer whole and part, respectively 4 Concatenate all the events together (discarding wholesparts that didn't intersect)

TODO - what if a continuous pattern contains a discrete one, or vice-versa?

valueinnerJoin :: Pattern (Pattern a) -> Pattern a
#

Turns a pattern of patterns into a single pattern. Like unwrap, but structure only comes from the inner pattern.

valueouterJoin :: Pattern (Pattern a) -> Pattern a
#

Turns a pattern of patterns into a single pattern. Like unwrap, but structure only comes from the outer pattern.

valuerotR :: Time -> Pattern a -> Pattern a
#

Shifts a pattern forward in time by the given amount, expressed in cycles. Opposite of rotL.

valuerotL :: Time -> Pattern a -> Pattern a
#

Shifts a pattern back in time by the given amount, expressed in cycles.

This will skip to the fourth cycle:

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

Useful when building and testing out longer sequences.

datadata Value
#
Instances14Eq, Floating, Fractional, Num, Ord, Show, …
newtypenewtype Note
#

Note is Double, but with a different parser

Constructors

Instances17Enum, Eq, Floating, Fractional, Data, Num, …
valuesplitQueries :: Pattern a -> Pattern a
#

Splits queries that span cycles. For example `query p (0.5, 1.5)` would be turned into two queries, `(0.5,1)` and `(1,1.5)`, and the results combined. Being able to assume queries don't span cycles often makes transformations easier to specify.

valuewithValue :: (a -> b) -> Pattern a -> Pattern b
#

withEvent f p returns a new Pattern with each value mapped over function f.

valuewithEvents :: ([Event a] -> [Event b]) -> Pattern a -> Pattern b
#

withEvent f p returns a new Pattern with f applied to the resulting list of events for each query function f.

valuefast :: Pattern Time -> Pattern a -> Pattern a
#

Speed up a pattern by the given time pattern.

For example, the following will play the sound pattern "bd sn kurt" twice as fast (i.e., so it repeats twice per cycle), and the vowel pattern three times as fast:

d1 $ sound (fast 2 "bd sn kurt")
   # fast 3 (vowel "a e o")

The first parameter can be patterned to, for example, play the pattern at twice the speed for the first half of each cycle and then four times the speed for the second half:

d1 $ fast "2 4" $ sound "bd sn kurt cp"
valuefastSqueeze :: Pattern Time -> Pattern a -> Pattern a
#

fastSqueeze speeds up a pattern by a time pattern given as input, squeezing the resulting pattern inside one cycle and playing the original pattern at every repetition.

To better understand how it works, compare it with fast:

Example1 expression
print $ fast "1 2" $ s "bd sn"(0>½)|s: "bd"(½>¾)|s: "bd"(¾>1)|s: "sn"

This will give bd played in the first half cycle, and bd sn in the second half. On the other hand, using fastSqueeze;

Example1 expression
print $ fastSqueeze "1 2" $ s "bd sn"(0>¼)|s: "bd"(¼>½)|s: "sn"(½>⅝)|s: "bd"(⅝>¾)|s: "sn"(¾>⅞)|s: "bd"(⅞>1)|s: "sn"

The original pattern will play in the first half, and two repetitions of the original pattern will play in the second half. That is, every repetition contains the whole pattern.

If the time pattern has a single value, it becomes equivalent to fast:

d1 $ fastSqueeze 2 $ s "bd sn"
d1 $ fast 2 $ s "bd sn"
d1 $ s "[bd sn]*2"
valueslow :: Pattern Time -> Pattern a -> Pattern a
#

Slow down a pattern by the given time pattern.

For example, the following will play the sound pattern "bd sn kurt" twice as slow (i.e., so it repeats once every two cycles), and the vowel pattern three times as slow:

d1 $ sound (slow 2 "bd sn kurt")
   # slow 3 (vowel "a e o")
valuedefragParts :: Eq a => [Event a] -> [Event a]
#

Returns a list of events, with any adjacent parts of the same whole combined

classclass Valuable a where
#

Methods

Instances8Valuable, …