-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Pattern language for improvised music -- -- Tidal is a domain specific language for live coding pattern. @package tidal @version 0.9 module Sound.Tidal.Utils -- | enumerate a list of things -- --
-- >>> enumerate ["foo","bar","baz"] -- [(1,"foo"), (2,"bar"), (3,"baz")] --enumerate :: [a] -> [(Int, a)] -- | apply f to the first element of a tuple mapFst :: (a -> b) -> (a, c) -> (b, c) -- | apply function to the first value of each tuple in given list mapFsts :: (a -> b) -> [(a, c)] -> [(b, c)] -- | apply f to the second element of a tuple mapSnd :: (a -> b) -> (c, a) -> (c, b) -- | apply function to the second value of each tuple in given list mapSnds :: (a -> b) -> [(c, a)] -> [(c, b)] -- | split given list of a by given single a, e.g. -- --
-- >>> wordsBy (== ':') "bd:3" -- ["bd", "3"] --wordsBy :: (a -> Bool) -> [a] -> [[a]] maybeRead :: String -> Maybe Double -- | shorthand for first element of triple fst' :: (t2, t1, t) -> t2 -- | shorthand for second element of triple snd' :: (t1, t2, t) -> t2 -- | shorthand for third element of triple thd' :: (t1, t, t2) -> t2 -- | apply f to the first element of a triple mapFst' :: (a -> x) -> (a, b, c) -> (x, b, c) -- | apply f to the second element of a triple mapSnd' :: (b -> x) -> (a, b, c) -> (a, x, c) -- | apply f to the third element of a triple mapThd' :: (c -> x) -> (a, b, c) -> (a, b, x) -- | apply function to the second value of each triple in given list mapFsts' :: (a -> x) -> [(a, b, c)] -> [(x, b, c)] -- | apply function to the second value of each triple in given list mapSnds' :: (b -> x) -> [(a, b, c)] -> [(a, x, c)] -- | apply function to the third value of each triple in given list mapThds' :: (c -> x) -> [(a, b, c)] -> [(a, b, x)] -- | map f over a given list of arcs mapArcs :: (a -> a) -> [(a, a, x)] -> [(a, a, x)] -- | combines two lists by interleaving them -- --
-- >>> mergelists [1,2,3] [9,8,7] -- [1,9,2,8,3,7] --mergelists :: [a] -> [a] -> [a] -- | like !! selects nth element from xs, but wraps over at -- the end of xs -- --
-- >>> map ((!!!) [1,3,5]) [0,1,2,3,4,5] -- [1,3,5,1,3,5] --(!!!) :: [a] -> Int -> a module Sound.Tidal.Time -- | Time is represented by a rational number. Each natural number -- represents both the start of the next rhythmic cycle, and the end of -- the previous one. Rational numbers are used so that subdivisions of -- each cycle can be accurately represented. type Time = Rational -- | (s,e) :: Arc represents a time interval with a start and end -- value. { t : s <= t && t < e } type Arc = (Time, Time) -- | An Event is a value that occurs during the period given by the first -- Arc. The second one indicates the event's "domain of -- influence". These will often be the same, but many temporal -- transformations, such as rotation and scaling time, may result in arcs -- being split or truncated. In such cases, the first arc is preserved, -- but the second arc reflects the portion of the event which is -- relevant. type Event a = (Arc, Arc, a) -- | The starting point of the current cycle. A cycle occurs from each -- natural number to the next, so this is equivalent to floor. sam :: Time -> Time -- | The end point of the current cycle (and starting point of the next -- cycle) nextSam :: Time -> Time -- | The position of a time value relative to the start of its cycle. cyclePos :: Time -> Time -- | isIn a t is True if t is inside the arc -- represented by a. isIn :: Arc -> Time -> Bool -- | Splits the given Arc into a list of Arcs, at cycle -- boundaries. arcCycles :: Arc -> [Arc] -- | Splits the given Arc into a list of Arcs, at cycle -- boundaries, but wrapping the arcs within the same cycle. arcCycles' :: Arc -> [Arc] -- | subArc i j is the arc that is the intersection of i -- and j. subArc :: Arc -> Arc -> Maybe Arc -- | Map the given function over both the start and end Time -- values of the given Arc. mapArc :: (Time -> Time) -> Arc -> Arc -- | Similar to mapArc but time is relative to the cycle (i.e. the -- sam of the start of the arc) mapCycle :: (Time -> Time) -> Arc -> Arc -- | Returns the `mirror image' of an Arc, used by -- Sound.Tidal.Pattern.rev. mirrorArc :: Arc -> Arc -- | The start time of the given Event eventStart :: Event a -> Time -- | The original onset of the given Event eventOnset :: Event a -> Time -- | The original offset of the given Event eventOffset :: Event a -> Time -- | The arc of the given Event eventArc :: Event a -> Arc -- | The midpoint of an Arc midPoint :: Arc -> Time -- | True if an Event's first and second Arc's start -- times match hasOnset :: Event a -> Bool -- | True if an Event's first and second Arc's end -- times match hasOffset :: Event a -> Bool -- | True if an Event's starts is within given Arc onsetIn :: Arc -> Event a -> Bool -- | True if an Event's ends is within given Arc offsetIn :: Arc -> Event a -> Bool module Sound.Tidal.Tempo data Tempo Tempo :: UTCTime -> Double -> Double -> Bool -> Double -> Tempo [at] :: Tempo -> UTCTime [beat] :: Tempo -> Double [cps] :: Tempo -> Double [paused] :: Tempo -> Bool [clockLatency] :: Tempo -> Double type ClientState = [TConnection] data TConnection TConnection :: Unique -> Connection -> TConnection wsConn :: TConnection -> Connection getLatency :: IO Double getClockIp :: IO String getServerPort :: IO Int readTempo :: String -> Tempo logicalTime :: Tempo -> Double -> Double tempoMVar :: IO (MVar (Tempo)) beatNow :: Tempo -> IO (Double) clientApp :: MVar Tempo -> MVar Double -> MVar Double -> ClientApp () sendTempo :: Connection -> Tempo -> IO () sendCps :: Connection -> MVar Tempo -> MVar Double -> IO () sendNudge :: Connection -> MVar Tempo -> MVar Double -> IO () connectClient :: Bool -> String -> MVar Tempo -> MVar Double -> MVar Double -> IO () runClient :: IO ((MVar Tempo, MVar Double, MVar Double)) cpsUtils' :: IO ((Double -> IO (), Double -> IO (), IO Rational)) cpsUtils :: IO (Double -> IO (), IO Rational) bpsUtils :: IO ((Double -> IO (), IO (Rational))) cpsSetter :: IO (Double -> IO ()) clocked :: (Tempo -> Int -> IO ()) -> IO () clockedTick :: Int -> (Tempo -> Int -> IO ()) -> IO () updateTempo :: Tempo -> Double -> IO (Tempo) nudgeTempo :: Tempo -> Double -> Tempo removeClient :: TConnection -> ClientState -> ClientState broadcast :: Text -> ClientState -> IO () startServer :: IO (ThreadId) serverApp :: MVar Tempo -> MVar ClientState -> ServerApp oscBridge :: MVar ClientState -> IO () serverLoop :: TConnection -> MVar Tempo -> MVar ClientState -> IO () instance GHC.Classes.Eq Sound.Tidal.Tempo.TConnection instance GHC.Show.Show Sound.Tidal.Tempo.Tempo module Sound.Tidal.Scales minPent :: [Int] majPent :: [Int] ritusen :: [Int] egyptian :: [Int] kumai :: [Int] hirajoshi :: [Int] iwato :: [Int] chinese :: [Int] indian :: [Int] pelog :: [Int] prometheus :: [Int] scriabin :: [Int] gong :: [Int] shang :: [Int] jiao :: [Int] zhi :: [Int] yu :: [Int] whole :: [Int] augmented :: [Int] augmented2 :: [Int] hexMajor7 :: [Int] hexDorian :: [Int] hexPhrygian :: [Int] hexSus :: [Int] hexMajor6 :: [Int] hexAeolian :: [Int] major :: [Int] ionian :: [Int] dorian :: [Int] phrygian :: [Int] lydian :: [Int] mixolydian :: [Int] aeolian :: [Int] minor :: [Int] locrian :: [Int] harmonicMinor :: [Int] harmonicMajor :: [Int] melodicMinor :: [Int] melodicMinorDesc :: [Int] melodicMajor :: [Int] bartok :: [Int] hindu :: [Int] todi :: [Int] purvi :: [Int] marva :: [Int] bhairav :: [Int] ahirbhairav :: [Int] superLocrian :: [Int] romanianMinor :: [Int] hungarianMinor :: [Int] neapolitanMinor :: [Int] enigmatic :: [Int] spanish :: [Int] leadingWhole :: [Int] lydianMinor :: [Int] neapolitanMajor :: [Int] locrianMajor :: [Int] diminished :: [Int] diminished2 :: [Int] chromatic :: [Int] module Sound.Tidal.Bjorklund bjorklund :: (Int, Int) -> [Bool] module Sound.Tidal.Pattern -- | The pattern datatype, a function from a time Arc to -- Event values. For discrete patterns, this returns the events -- which are active during that time. For continuous patterns, events -- with values for the midpoint of the given Arc is returned. data Pattern a Pattern :: (Arc -> [Event a]) -> Pattern a [arc] :: Pattern a -> Arc -> [Event a] -- | Admit the pattern datatype to the Num, Fractional and Floating -- classes, to allow arithmetic on them, and for bare numbers to be -- automatically converted into patterns of numbers -- | show (p :: Pattern) returns a text string representing the -- event values active during the first cycle of the given pattern. -- | converts a ratio into human readable string, e.g. 1/3 showTime :: (Show a, Integral a) => Ratio a -> String -- | converts a time arc into human readable string, e.g. 13 -- 34 showArc :: Arc -> String -- | converts an event into human readable string, e.g. ("bd" 14 -- 23) showEvent :: (Show a) => Event a -> String -- | pure a returns a pattern with an event with value a, -- which has a duration of one cycle, and repeats every cycle. -- | mempty is a synonym for silence. | mappend -- is a synonym for overlay. unwrap :: Pattern (Pattern a) -> Pattern a -- | atom is a synonym for pure. atom :: a -> Pattern a -- | silence returns a pattern with no events. silence :: Pattern a -- | withQueryArc f p returns a new Pattern with function -- f applied to the Arc values passed to the original -- Pattern p. withQueryArc :: (Arc -> Arc) -> Pattern a -> Pattern a -- | withQueryTime f p returns a new Pattern with -- function f applied to the both the start and end -- Time of the Arc passed to Pattern -- p. withQueryTime :: (Time -> Time) -> Pattern a -> Pattern a -- | withResultArc f p returns a new Pattern with -- function f applied to the Arc values in the events -- returned from the original Pattern p. withResultArc :: (Arc -> Arc) -> Pattern a -> Pattern a -- | withResultTime f p returns a new Pattern with -- function f applied to the both the start and end -- Time of the Arc values in the events returned from -- the original Pattern p. withResultTime :: (Time -> Time) -> Pattern a -> Pattern a -- | withEvent f p returns a new Pattern with events -- mapped over function f. withEvent :: (Event a -> Event b) -> Pattern a -> Pattern b -- | timedValues p returns a new Pattern where values are -- turned into tuples of Arc and value. timedValues :: Pattern a -> Pattern (Arc, a) -- | overlay combines two Patterns into a new pattern, so -- that their events are combined over time. This is the same as the -- infix operator <>. overlay :: Pattern a -> Pattern a -> Pattern a -- | stack combines a list of Patterns into a new -- pattern, so that their events are combined over time. stack :: [Pattern a] -> Pattern a -- | append combines two patterns Patterns into a new -- pattern, so that the events of the second pattern are appended to -- those of the first pattern, within a single cycle append :: Pattern a -> Pattern a -> Pattern a -- | append' does the same as append, but over two -- cycles, so that the cycles alternate between the two patterns. append' :: Pattern a -> Pattern a -> Pattern a -- | cat returns a new pattern which interlaces the cycles of the -- given patterns, within a single cycle. It's the equivalent of -- append, but with a list of patterns. cat :: [Pattern a] -> Pattern a splitAtSam :: Pattern a -> Pattern a -- | slowcat does the same as cat, but maintaining the -- duration of the original patterns. It is the equivalent of -- append', but with a list of patterns. slowcat :: [Pattern a] -> Pattern a -- | listToPat turns the given list of values to a Pattern, which -- cycles through the list. listToPat :: [a] -> Pattern a -- | maybeListToPat is similar to listToPat, but allows -- values to be optional using the Maybe type, so that -- Nothing results in gaps in the pattern. maybeListToPat :: [Maybe a] -> Pattern a -- | run n returns a pattern representing a cycle of -- numbers from 0 to n-1. run :: (Enum a, Num a) => a -> Pattern a scan :: (Num a, Enum a) => a -> Pattern a -- | density returns the given pattern with density increased by -- the given Time factor. Therefore density 2 p will -- return a pattern that is twice as fast, and density (1/3) p -- will return one three times as slow. density :: Time -> Pattern a -> Pattern a density' :: Pattern Time -> Pattern a -> Pattern a -- | densityGap is similar to density but maintains its -- cyclic alignment. For example, densityGap 2 p would squash -- the events in pattern p into the first half of each cycle -- (and the second halves would be empty). densityGap :: Time -> Pattern a -> Pattern a -- | slow does the opposite of density, i.e. slow 2 -- p will return a pattern that is half the speed. slow :: Time -> Pattern a -> Pattern a slow' :: Pattern Time -> Pattern a -> Pattern a -- | The <~ operator shifts (or rotates) a pattern to the left -- (or counter-clockwise) by the given Time value. For example -- (1%16) <~ p will return a pattern with all the events -- moved one 16th of a cycle to the left. (<~) :: Time -> Pattern a -> Pattern a -- | The ~> operator does the same as <~ but shifts -- events to the right (or clockwise) rather than to the left. (~>) :: Time -> Pattern a -> Pattern a -- | (The above means that brak is a function from patterns of any -- type, to a pattern of the same type.) -- -- Make a pattern sound a bit like a breakbeat -- -- Example: -- --
-- d1 $ sound (brak "bd sn kurt") --brak :: Pattern a -> Pattern a -- | 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 :: Int -> Pattern a -> Pattern a -- | iter' is the same as iter, but decrements the -- starting subdivision instead of incrementing it. iter' :: Int -> Pattern a -> Pattern a -- | rev p returns p with the event positions in each -- cycle reversed (or mirrored). rev :: Pattern a -> Pattern a -- | palindrome p applies rev to p every other -- cycle, so that the pattern alternates between forwards and backwards. palindrome :: Pattern a -> Pattern a -- | Only when the given test function returns True the given -- pattern transformation is applied. The test function will be called -- with the current cycle as a number. -- --
-- d1 $ when ((elem '4').show) -- (striate 4) -- $ sound "hh hc" ---- -- The above will only apply `striate 4` to the pattern if the current -- cycle number contains the number 4. So the fourth cycle will be -- striated and the fourteenth and so on. Expect lots of striates after -- cycle number 399. when :: (Int -> Bool) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a whenT :: (Time -> Bool) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a playWhen :: (Time -> Bool) -> Pattern a -> Pattern a playFor :: Time -> Time -> Pattern a -> Pattern a -- | 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))) -- ] --seqP :: [(Time, Time, Pattern a)] -> Pattern a -- | every n f p applies the function f to p, -- but only affects every n cycles. every :: Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | every n o f' is like every n f with an offset of -- o cycles every' :: Int -> Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | foldEvery ns f p applies the function f to -- p, and is applied for each cycle in ns. foldEvery :: [Int] -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | sig f takes a function from time to values, and turns it into -- a Pattern. sig :: (Time -> a) -> Pattern a -- | sinewave returns a Pattern of continuous -- Double values following a sinewave with frequency of one -- cycle, and amplitude from -1 to 1. sinewave :: Pattern Double -- | sine is a synonym for sinewave. sine :: Pattern Double -- | sinerat is equivalent to sinewave for -- Rational values, suitable for use as Time offsets. sinerat :: Pattern Rational -- | ratsine is a synonym for sinerat. ratsine :: Pattern Rational -- | sinewave1 is equivalent to sinewave, but with -- amplitude from 0 to 1. sinewave1 :: Pattern Double -- | sine1 is a synonym for sinewave1. sine1 :: Pattern Double -- | sinerat1 is equivalent to sinerat, but with -- amplitude from 0 to 1. sinerat1 :: Pattern Rational -- | sineAmp1 d returns sinewave1 with its amplitude -- offset by d. sineAmp1 :: Double -> Pattern Double -- | sawwave is the equivalent of sinewave for -- (ascending) sawtooth waves. sawwave :: Pattern Double -- | saw is a synonym for sawwave. saw :: Pattern Double -- | sawrat is the same as sawwave but returns -- Rational values suitable for use as Time offsets. sawrat :: Pattern Rational -- | sawwave1 is the equivalent of sinewave1 for -- (ascending) sawtooth waves. sawwave1 :: Pattern Double -- | saw1 is a synonym for sawwave1. saw1 :: Pattern Double -- | sawrat1 is the same as sawwave1 but returns -- Rational values suitable for use as Time offsets. sawrat1 :: Pattern Rational -- | triwave is the equivalent of sinewave for triangular -- waves. triwave :: Pattern Double -- | tri is a synonym for triwave. tri :: Pattern Double -- | trirat is the same as triwave but returns -- Rational values suitable for use as Time offsets. trirat :: Pattern Rational -- | triwave1 is the equivalent of sinewave1 for -- triangular waves. triwave1 :: Pattern Double -- | tri1 is a synonym for triwave1. tri1 :: Pattern Double -- | trirat1 is the same as triwave1 but returns -- Rational values suitable for use as Time offsets. trirat1 :: Pattern Rational -- | squarewave1 is the equivalent of sinewave1 for -- square waves. squarewave1 :: Pattern Double -- | square1 is a synonym for squarewave1. square1 :: Pattern Double -- | squarewave is the equivalent of sinewave for square -- waves. squarewave :: Pattern Double -- | square is a synonym for squarewave. square :: Pattern Double -- | envL is a Pattern of continuous Double -- values, representing a linear interpolation between 0 and 1 during the -- first cycle, then staying constant at 1 for all following cycles. -- Possibly only useful if you're using something like the retrig -- function defined in tidal.el. envL :: Pattern Double envLR :: Pattern Double envEq :: Pattern Double envEqR :: Pattern Double fadeOut :: Time -> Pattern a -> Pattern a fadeOut' :: Time -> Time -> Pattern a -> Pattern a fadeIn' :: Time -> Time -> Pattern a -> Pattern a fadeIn :: Time -> Pattern a -> Pattern a -- | (The above is difficult to describe, if you don't understand Haskell, -- just read the description and examples..) -- -- 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. 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: -- --
-- 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" --spread' :: Monad m => (a -> b -> m c) -> m a -> b -> m c -- | `spreadChoose f xs p` is similar to slowspread but picks values -- from xs at random, rather than cycling through them in order. -- It has a shorter alias spreadr. spreadChoose :: (t -> t1 -> Pattern b) -> [t] -> t1 -> Pattern b spreadr :: (t -> t1 -> Pattern b) -> [t] -> t1 -> Pattern b filterValues :: (a -> Bool) -> Pattern a -> Pattern a filterOnsets :: Pattern a -> Pattern a filterStartInRange :: Pattern a -> Pattern a filterOnsetsInRange :: Pattern a -> Pattern a seqToRelOnsetDeltas :: Arc -> Pattern a -> [(Double, Double, a)] segment :: Pattern a -> Pattern [a] segment' :: [Event a] -> [Event a] split :: Time -> [Event a] -> [Event a] points :: [Event a] -> [Time] groupByTime :: [Event a] -> [Event [a]] -- | Decide whether to apply one or another function depending on the -- result of a test function that 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 aply `# 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. ifp :: (Int -> Bool) -> (Pattern a -> Pattern a) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | rand generates a continuous pattern of (pseudo-)random, -- floating point numbers between `0` and `1`. -- --
-- d1 $ sound "bd*8" # pan rand ---- -- pans bass drums randomly -- --
-- d1 $ sound "sn sn ~ sn" # gain rand ---- -- makes the snares' randomly loud and quiet. -- -- Numbers coming from this pattern are random, but dependent on time. So -- if you reset time via `cps (-1)` 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: -- --
-- d1 $ jux (|+| gain rand) $ sound "sn sn ~ sn" # gain rand ---- -- and with the juxed version shifted backwards for 1024 cycles: -- --
-- d1 $ jux (|+| ((1024 <~) $ gain rand)) $ sound "sn sn ~ sn" # gain rand --rand :: Pattern Double timeToRand :: RealFrac a => a -> Double -- | Just like rand but for integers, `irand n` generates a pattern -- of (pseudo-)random integers between `0` to `n-1` inclusive. Notably -- used to pick a random samples from a folder: -- --
-- d1 $ sound (samples "drum*4" (irand 5)) --irand :: Int -> Pattern Int -- | Randomly picks an element from the given list -- --
-- d1 $ sound (samples "xx(3,8)" (tom $ choose ["a", "e", "g", "c"])) ---- -- plays a melody randomly choosing one of the four notes "a", "e", "g", -- "c". choose :: [a] -> Pattern a -- | 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" --degradeBy :: Double -> Pattern a -> Pattern a unDegradeBy :: Double -> Pattern a -> Pattern a -- | 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 :: Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | sometimes is an alias for sometimesBy 0.5. sometimes :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | often is an alias for sometimesBy 0.75. often :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | rarely is an alias for sometimesBy 0.25. rarely :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | almostNever is an alias for sometimesBy 0.1 almostNever :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | almostAlways is an alias for sometimesBy 0.9 almostAlways :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a never :: b -> c -> c always :: a -> a -- | someCyclesBy is a cycle-by-cycle version of -- sometimesBy. It has a `someCycles = someCyclesBy 0.5` alias someCyclesBy :: Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a somecyclesBy :: Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a someCycles :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | 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]" --degrade :: Pattern a -> Pattern a -- | 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. wedge :: Time -> Pattern a -> Pattern a -> Pattern a -- | whenmod has a similar form and behavior to every, but -- requires an additional number. 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 :: Int -> Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- |
-- 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. -- --
-- d1 $ superimpose (density 2) $ sound "bd sn [cp ht] hh" -- d1 $ superimpose ((# speed "2") . (0.125 <~)) $ sound "bd sn cp hh" --superimpose :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a -- | splitQueries p wraps p to ensure that it does not -- get queries that span arcs. For example `arc 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. splitQueries :: Pattern a -> Pattern a -- | 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" --trunc :: Time -> Pattern a -> Pattern a -- | Plays a portion of a pattern, specified by a beginning and end arc of -- time. The new resulting pattern is played over the time period of the -- original pattern: -- --
-- d1 $ zoom (0.25, 0.75) $ sound "bd*2 hh*3 [sn bd]*2 drum" ---- -- In the pattern above, zoom is used with an arc from 25% to 75%. -- It is equivalent to this pattern: -- --
-- d1 $ sound "hh*3 [sn bd]*2" --zoom :: Arc -> Pattern a -> Pattern a compress :: Arc -> Pattern a -> Pattern a sliceArc :: Arc -> Pattern a -> Pattern a -- | Use within to apply a function to only a part of a pattern. For -- example, to apply `density 2` to only the first half of a pattern: -- --
-- d1 $ within (0, 0.5) (density 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" --within :: Arc -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a revArc :: Arc -> Pattern a -> Pattern a -- | You can use the e function to apply a Euclidean algorithm -- over a complex pattern, although the structure of that pattern will be -- lost: -- --
-- d1 $ e 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 `e 3 8`. It ends up picking -- two bd sounds, a cp and missing the sn -- entirely. -- -- 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](http:/cgm.cs.mcgill.ca~godfriedpublicationsbanff.pdf) -- by Toussaint. Some examples from this paper are included below, -- including rotation in some cases. -- --
-- - (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. --e :: Int -> Int -> Pattern a -> Pattern a e' :: Int -> Int -> Pattern a -> Pattern a index :: Real b => b -> Pattern b -> Pattern c -> Pattern c -- | prrw f rot (blen, vlen) beatPattern valuePattern: pattern -- rotate/replace. prrw :: (a -> b -> c) -> Int -> (Time, Time) -> Pattern a -> Pattern b -> Pattern c -- | prr rot (blen, vlen) beatPattern valuePattern: pattern -- rotate/replace. prr :: Int -> (Time, Time) -> Pattern String -> Pattern b -> Pattern b -- | preplace (blen, plen) beats values combines the timing of -- beats with the values of values. Other ways of -- saying this are: * sequential convolution * values quantized -- to beats. -- -- Examples: -- --
-- d1 $ sound $ preplace (1,1) "x [~ x] x x" "bd sn" -- d1 $ sound $ preplace (1,1) "x(3,8)" "bd sn" -- d1 $ sound $ "x(3,8)" ~ "bd sn" -- d1 $ sound "[jvbass jvbass:5]*3" |+| (shape $ "1 1 1 1 1" ~ "0.2 0.9") ---- -- It is assumed the pattern fits into a single cycle. This works well -- with pattern literals, but not always with patterns defined elsewhere. -- In those cases use preplace and provide desired pattern -- lengths: @ let p = slow 2 $ "x x x" -- -- d1 $ sound $ preplace (2,1) p "bd sn" @ preplace :: (Time, Time) -> Pattern String -> Pattern b -> Pattern b -- | prep is an alias for preplace. prep :: (Time, Time) -> Pattern String -> Pattern b -> Pattern b preplace1 :: Pattern String -> Pattern b -> Pattern b preplaceWith :: (a -> b -> c) -> (Time, Time) -> Pattern a -> Pattern b -> Pattern c prw :: (a -> b -> c) -> (Time, Time) -> Pattern a -> Pattern b -> Pattern c preplaceWith1 :: (a -> b -> c) -> Pattern a -> Pattern b -> Pattern c prw1 :: (a -> b -> c) -> Pattern a -> Pattern b -> Pattern c (<~>) :: Pattern String -> Pattern b -> Pattern b -- | protate len rot p rotates pattern p by rot -- beats to the left. len: length of the pattern, in cycles. -- Example: d1 $ every 4 (protate 2 (-1)) $ slow 2 $ sound "bd hh hh -- hh" protate :: Time -> Int -> Pattern a -> Pattern a prot :: Time -> Int -> Pattern a -> Pattern a prot1 :: Int -> Pattern a -> Pattern a -- | The <<~ operator rotates a unit pattern to the left, -- similar to <~, but by events rather than linear time. The -- timing of the pattern remains constant: -- --
-- d1 $ (1 <<~) $ sound "bd ~ sn hh" -- -- will become -- d1 $ sound "sn ~ hh bd" --(<<~) :: Int -> Pattern a -> Pattern a -- | ~>> is like <<~ but for shifting to the -- right. (~>>) :: Int -> Pattern a -> Pattern a -- | pequal cycles p1 p2: quickly test if p1 and -- p2 are the same. pequal :: Ord a => Time -> Pattern a -> Pattern a -> Bool -- | discretise n p: samples the pattern p at a -- rate of n events per cycle. Useful for turning a continuous -- pattern into a discrete one. discretise :: Time -> Pattern a -> Pattern a -- | randcat ps: does a slowcat on the list of patterns -- ps but randomises the order in which they are played. randcat :: [Pattern a] -> Pattern a -- | 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 permstep :: RealFrac b => Int -> [a] -> Pattern b -> Pattern a -- | struct a b: structures pattern b in terms of -- a. struct :: Pattern String -> Pattern a -> Pattern a -- | 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. substruct :: Pattern String -> Pattern b -> Pattern b parseLMRule :: String -> [(String, String)] parseLMRule' :: String -> [(Char, String)] -- | returns the nth iteration of a Lindenmayer System with -- given start sequence. -- -- for example: -- --
-- lindenmayer 1 "a:b,b:ab" "ab" -> "bab" --lindenmayer :: Int -> String -> String -> String unwrap' :: Pattern (Pattern a) -> Pattern a -- | Removes events from second pattern that don't start during an event -- from first. -- -- 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" :: Pattern Bool)
-- (slowcat ["can*8", "[cp*4 sn*4, jvbass*16]"] ))
-- # n (run 8)
--
--
-- Detail: It is currently needed to explicitly _tell_ Tidal that the
-- mask itself is a `Pattern Bool` as it cannot infer this by itself,
-- otherwise it will complain as it does not know how to interpret your
-- input.
mask :: Pattern a -> Pattern b -> Pattern b
enclosingArc :: [Arc] -> Arc
stretch :: Pattern a -> Pattern a
-- | 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. fit' :: Time -> Int -> Pattern Int -> Pattern Int -> Pattern a -> Pattern a -- | runWith n f p treats the given pattern p as having -- n sections, and applies the function f to one of -- those sections per cycle, running from left to right. -- --
-- d1 $ runWith 4 (density 4) $ sound "cp sn arpy [mt lt]" --runWith :: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b -- | runWith' works much the same as runWith, but runs from -- right to left. runWith' :: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b inside :: Time -> (Pattern a1 -> Pattern a) -> Pattern a1 -> Pattern a outside :: Time -> (Pattern a1 -> Pattern a) -> Pattern a1 -> Pattern a loopFirst :: Pattern a -> Pattern a timeLoop :: Time -> Pattern a -> Pattern a seqPLoop :: [(Time, Time, Pattern a)] -> Pattern a -- | 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"`. It assumes your -- scale fits within an octave, to change this use toScale size`. -- Example: toscale 24 [0,4,7,10,14,17] (run 8)` turns into `"0 -- 4 7 10 14 17 24 28"` toScale' :: Int -> [Int] -> Pattern Int -> Pattern Int toScale :: [Int] -> Pattern Int -> Pattern Int -- | `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 . swing is an alias for `swingBy (1%3)` swingBy :: Time -> Time -> Pattern a -> Pattern a swing :: Time -> Pattern a -> Pattern a -- | cycleChoose is like choose but only picks a new item -- from the list once each cycle cycleChoose :: [a] -> Pattern a -- | `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. shuffle :: Int -> Pattern a -> Pattern a -- | `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. scramble :: Int -> Pattern a -> Pattern a ur :: Time -> Pattern String -> [Pattern a] -> Pattern a ur' :: Time -> Pattern String -> [(String, Pattern a)] -> [(String, Pattern a -> Pattern a)] -> Pattern a inhabit :: [(String, Pattern a)] -> Pattern String -> Pattern a instance GHC.Num.Num a => GHC.Num.Num (Sound.Tidal.Pattern.Pattern a) instance GHC.Real.Fractional a => GHC.Real.Fractional (Sound.Tidal.Pattern.Pattern a) instance GHC.Float.Floating a => GHC.Float.Floating (Sound.Tidal.Pattern.Pattern a) instance GHC.Show.Show a => GHC.Show.Show (Sound.Tidal.Pattern.Pattern a) instance GHC.Base.Functor Sound.Tidal.Pattern.Pattern instance GHC.Base.Applicative Sound.Tidal.Pattern.Pattern instance GHC.Base.Monoid (Sound.Tidal.Pattern.Pattern a) instance GHC.Base.Monad Sound.Tidal.Pattern.Pattern module Sound.Tidal.Chords major :: [Int] minor :: [Int] major7 :: [Int] dom7 :: [Int] minor7 :: [Int] aug :: [Int] dim :: [Int] dim7 :: [Int] one :: [Int] five :: [Int] plus :: [Int] sharp5 :: [Int] msharp5 :: [Int] sus2 :: [Int] sus4 :: [Int] six :: [Int] m6 :: [Int] sevenSus2 :: [Int] sevenSus4 :: [Int] sevenFlat5 :: [Int] m7flat5 :: [Int] sevenSharp5 :: [Int] m7sharp5 :: [Int] nine :: [Int] m9 :: [Int] m7sharp9 :: [Int] maj9 :: [Int] nineSus4 :: [Int] sixby9 :: [Int] m6by9 :: [Int] sevenFlat9 :: [Int] m7flat9 :: [Int] sevenFlat10 :: [Int] nineSharp5 :: [Int] m9sharp5 :: [Int] sevenSharp5flat9 :: [Int] m7sharp5flat9 :: [Int] eleven :: [Int] m11 :: [Int] maj11 :: [Int] evelenSharp :: [Int] m11sharp :: [Int] thirteen :: [Int] m13 :: [Int] -- | chordate cs m n selects the nth "chord" (a chord is -- a list of Ints) from a list of chords cs and transposes it by -- m chordate :: Num b => [[b]] -> b -> Int -> [b] -- | flatpat takes a Pattern of lists and pulls the list elements -- as separate Events flatpat :: Pattern [a] -> Pattern a -- | enchord chords pn pc turns every note in the note pattern -- pn into a chord, selecting from the chord lists -- chords using the index pattern pc. For example, -- Chords.enchord [Chords.major Chords.minor] "c g" "0 1" will -- create a pattern of a C-major chord followed by a G-minor chord. enchord :: Num a => [[a]] -> Pattern a -> Pattern Int -> Pattern a module Sound.Tidal.Parse -- | AST representation of patterns data TPat a TPat_Atom :: a -> TPat a TPat_Density :: Time -> (TPat a) -> TPat a TPat_Slow :: Time -> (TPat a) -> TPat a TPat_Zoom :: Arc -> (TPat a) -> TPat a TPat_DegradeBy :: Double -> (TPat a) -> TPat a TPat_Silence :: TPat a TPat_Foot :: TPat a TPat_Cat :: [TPat a] -> TPat a TPat_Overlay :: (TPat a) -> (TPat a) -> TPat a TPat_ShiftL :: Time -> (TPat a) -> TPat a -- | TPat_E Int Int (TPat a) TPat_pE :: (TPat Int) -> (TPat Int) -> (TPat Integer) -> (TPat a) -> TPat a toPat :: TPat a -> Pattern a p :: Parseable a => String -> Pattern a class Parseable a parseTPat :: Parseable a => String -> TPat a type ColourD = Colour Double lexer :: GenTokenParser String u Identity braces :: Parser a -> Parser a brackets :: Parser a -> Parser a parens :: Parser a -> Parser a angles :: Parser a -> Parser a symbol :: String -> Parser String natural :: Parser Integer integer :: Parser Integer float :: Parser Double naturalOrFloat :: Parser (Either Integer Double) data Sign Positive :: Sign Negative :: Sign applySign :: Num a => Sign -> a -> a sign :: Parser Sign intOrFloat :: Parser (Either Integer Double) r :: Parseable a => String -> Pattern a -> IO (Pattern a) parseRhythm :: Parser (TPat a) -> String -> TPat a pSequenceN :: Parser (TPat a) -> GenParser Char () (Int, TPat a) splitFeet :: [TPat t] -> [[TPat t]] pSequence :: Parser (TPat a) -> GenParser Char () (TPat a) pSingle :: Parser (TPat a) -> Parser (TPat a) pPart :: Parser (TPat a) -> Parser [TPat a] pPolyIn :: Parser (TPat a) -> Parser (TPat a) pPolyOut :: Parser (TPat a) -> Parser (TPat a) pString :: Parser (String) pVocable :: Parser (TPat String) pDouble :: Parser (TPat Double) pBool :: Parser (TPat Bool) parseIntNote :: Integral i => Parser i parseInt :: Parser Int pIntegral :: Integral i => Parser (TPat i) parseNote :: Integral a => Parser a fromNote :: Integral c => Pattern String -> Pattern c pColour :: Parser (TPat ColourD) pMult :: TPat a -> Parser (TPat a) pRand :: TPat a -> Parser (TPat a) pE :: TPat a -> Parser (TPat a) eoff :: Int -> Int -> Integer -> Pattern a -> Pattern a pReplicate :: TPat a -> Parser [TPat a] pStretch :: TPat a -> Parser [TPat a] pRatio :: Parser (Rational) pRational :: Parser (TPat Rational) instance GHC.Show.Show a => GHC.Show.Show (Sound.Tidal.Parse.TPat a) instance GHC.Base.Monoid (Sound.Tidal.Parse.TPat a) instance Sound.Tidal.Parse.Parseable GHC.Types.Double instance Sound.Tidal.Parse.Parseable GHC.Base.String instance Sound.Tidal.Parse.Parseable GHC.Types.Bool instance Sound.Tidal.Parse.Parseable GHC.Types.Int instance Sound.Tidal.Parse.Parseable GHC.Integer.Type.Integer instance Sound.Tidal.Parse.Parseable GHC.Real.Rational instance Sound.Tidal.Parse.Parseable Sound.Tidal.Parse.ColourD instance Sound.Tidal.Parse.Parseable a => Data.String.IsString (Sound.Tidal.Pattern.Pattern a) module Sound.Tidal.Stream type ToMessageFunc = Shape -> Tempo -> Int -> (Double, Double, ParamMap) -> Maybe (IO ()) data Backend a Backend :: ToMessageFunc -> (Shape -> Tempo -> Int -> IO ()) -> Backend a [toMessage] :: Backend a -> ToMessageFunc [flush] :: Backend a -> Shape -> Tempo -> Int -> IO () data Param S :: String -> Maybe String -> Param [name] :: Param -> String [sDefault] :: Param -> Maybe String F :: String -> Maybe Double -> Param [name] :: Param -> String [fDefault] :: Param -> Maybe Double I :: String -> Maybe Int -> Param [name] :: Param -> String [iDefault] :: Param -> Maybe Int data Shape Shape :: [Param] -> Double -> Bool -> Shape [params] :: Shape -> [Param] [latency] :: Shape -> Double [cpsStamp] :: Shape -> Bool data Value VS :: String -> Value [svalue] :: Value -> String VF :: Double -> Value [fvalue] :: Value -> Double VI :: Int -> Value [ivalue] :: Value -> Int type ParamMap = Map Param Value type ParamPattern = Pattern ParamMap ticksPerCycle :: Num t => t defaultValue :: Param -> Value hasDefault :: Param -> Bool defaulted :: Shape -> [Param] defaultMap :: Shape -> ParamMap required :: Shape -> [Param] hasRequired :: Shape -> ParamMap -> Bool isSubset :: (Eq a) => [a] -> [a] -> Bool doAt :: RealFrac a => a -> IO () -> IO () logicalOnset' :: Integral t => Tempo -> t -> Double -> Double -> Double applyShape' :: Shape -> ParamMap -> Maybe ParamMap start :: Backend a -> Shape -> IO (MVar (ParamPattern)) state :: Backend a -> Shape -> IO (MVar (ParamPattern, [ParamPattern])) stream :: Backend a -> Shape -> IO (ParamPattern -> IO ()) streamcallback :: (ParamPattern -> IO ()) -> Backend a -> Shape -> IO (ParamPattern -> IO ()) onTick :: Backend a -> Shape -> MVar (ParamPattern) -> Tempo -> Int -> IO () onTick' :: Backend a -> Shape -> MVar (ParamPattern, [ParamPattern]) -> Tempo -> Int -> IO () make :: (a -> Value) -> Shape -> String -> Pattern a -> ParamPattern makeS :: Shape -> String -> Pattern String -> ParamPattern makeF :: Shape -> String -> Pattern Double -> ParamPattern makeI :: Shape -> String -> Pattern Int -> ParamPattern param :: Shape -> String -> Param merge :: ParamPattern -> ParamPattern -> ParamPattern (|=|) :: ParamPattern -> ParamPattern -> ParamPattern infixl 1 |=| (#) :: ParamPattern -> ParamPattern -> ParamPattern infixl 1 # mergeWith :: (Ord k, Applicative f) => (k -> a -> a -> a) -> f (Map k a) -> f (Map k a) -> f (Map k a) mergeNumWith :: Applicative f => (Int -> Int -> Int) -> (Double -> Double -> Double) -> f (Map Param Value) -> f (Map Param Value) -> f (Map Param Value) mergePlus :: Applicative f => f (Map Param Value) -> f (Map Param Value) -> f (Map Param Value) (|*|) :: ParamPattern -> ParamPattern -> ParamPattern infixl 1 |*| (|+|) :: ParamPattern -> ParamPattern -> ParamPattern infixl 1 |+| (|-|) :: ParamPattern -> ParamPattern -> ParamPattern infixl 1 |-| (|/|) :: ParamPattern -> ParamPattern -> ParamPattern infixl 1 |/| -- | These are shorthand for merging lists of patterns with #, -- |*|, |+|, or |/|. Sometimes this saves a -- little typing and can improve readability when passing things into -- other functions. As an example, instead of writing d1 $ sometimes -- ((|*| speed "2") . (|*| cutoff "2") . (|*| shape "1.5")) $ sound -- "arpy*4" shape "0.3" you can write d1 $ sometimes (*** -- [speed "2", cutoff "2", shape "1.5"]) $ sound "arpy*4" ### [cutoff -- "350", shape "0.3"] (###) :: Foldable t => ParamPattern -> t ParamPattern -> ParamPattern (***) :: Foldable t => ParamPattern -> t ParamPattern -> ParamPattern (+++) :: Foldable t => ParamPattern -> t ParamPattern -> ParamPattern (///) :: Foldable t => ParamPattern -> t ParamPattern -> ParamPattern setter :: MVar (a, [a]) -> a -> IO () -- | Copies values from one parameter to another. Used by nToOrbit -- in Sound.Tidal.Dirt. copyParam :: Param -> Param -> ParamPattern -> ParamPattern instance GHC.Classes.Ord Sound.Tidal.Stream.Value instance GHC.Classes.Eq Sound.Tidal.Stream.Value instance GHC.Show.Show Sound.Tidal.Stream.Value instance GHC.Classes.Eq Sound.Tidal.Stream.Param instance GHC.Classes.Ord Sound.Tidal.Stream.Param instance GHC.Show.Show Sound.Tidal.Stream.Param module Sound.Tidal.Params make' :: (a -> Value) -> Param -> Pattern a -> ParamPattern -- | group multiple params into one grp :: [Param] -> Pattern String -> ParamPattern -- | A pattern of strings representing sounds or synth notes. -- -- Internally, sound or its shorter alias s is a -- combination of the samplebank name and number when used with samples, -- or synth name and note number when used with a synthesiser. For -- example `bd:2` specifies the third sample (not the second as you might -- expect, because we start counting at zero) in the bd sample -- folder. -- --
-- d1 $ sound "bd:2 sn:0" ---- -- is essentially the same as: -- --
-- d1 $ s' "bd sn" # n "2 0" ---- -- n is therefore useful when you want to pattern the sample or -- note number separately from the samplebank or synth. For example: -- --
-- d1 $ n "0 5 ~ 2" # sound "drum" ---- -- is equivalent to: -- --
-- d1 $ sound "drum:0 drum:5 ~ drum:2" --sound :: Pattern String -> ParamPattern s :: Pattern String -> ParamPattern pF :: String -> Maybe Double -> (Pattern Double -> ParamPattern, Param) pI :: String -> Maybe Int -> (Pattern Int -> ParamPattern, Param) pS :: String -> Maybe String -> (Pattern String -> ParamPattern, Param) -- | a pattern of numbers that speed up (or slow down) samples while they -- play. accelerate :: Pattern Double -> ParamPattern -- | a pattern of numbers to specify the attack time (in seconds) of an -- envelope applied to each sample. Only takes effect if release -- is also specified. attack :: Pattern Double -> ParamPattern -- | a pattern of numbers from 0 to 1. Sets the center frequency of the -- band-pass filter. bandf :: Pattern Double -> ParamPattern -- | a pattern of numbers from 0 to 1. Sets the q-factor of the band-pass -- filter. bandq :: Pattern Double -> ParamPattern -- | a pattern of numbers from 0 to 1. Skips the beginning of each sample, -- e.g. `0.25` to cut off the first quarter from each sample. -- -- Using `begin "-1"` combined with `cut "-1"` means that when the sample -- cuts itself it will begin playback from where the previous one left -- off, so it will sound like one seamless sample. This allows you to -- apply a synth param across a long sample in a way similar to -- chop: -- --
-- cps 0.5 -- -- d1 $ sound "breaks125*8" begin "-1" coarse "1 2 4 8 16 32 64 128" ---- -- This will play the breaks125 sample and apply the changing -- coarse parameter over the sample. Compare to: -- --
-- d1 $ (chop 8 $ sounds "breaks125") coarse "1 2 4 8 16 32 64 128" ---- -- which performs a similar effect, but due to differences in -- implementation sounds different. begin_p :: Param -- | a pattern of numbers from 0 to 1. Skips the beginning of each sample, -- e.g. `0.25` to cut off the first quarter from each sample. -- -- Using `begin "-1"` combined with `cut "-1"` means that when the sample -- cuts itself it will begin playback from where the previous one left -- off, so it will sound like one seamless sample. This allows you to -- apply a synth param across a long sample in a way similar to -- chop: -- --
-- cps 0.5 -- -- d1 $ sound "breaks125*8" begin "-1" coarse "1 2 4 8 16 32 64 128" ---- -- This will play the breaks125 sample and apply the changing -- coarse parameter over the sample. Compare to: -- --
-- d1 $ (chop 8 $ sounds "breaks125") coarse "1 2 4 8 16 32 64 128" ---- -- which performs a similar effect, but due to differences in -- implementation sounds different. channel_p :: Param -- | a pattern of numbers from 0 to 1. Skips the beginning of each sample, -- e.g. `0.25` to cut off the first quarter from each sample. -- -- Using `begin "-1"` combined with `cut "-1"` means that when the sample -- cuts itself it will begin playback from where the previous one left -- off, so it will sound like one seamless sample. This allows you to -- apply a synth param across a long sample in a way similar to -- chop: -- --
-- cps 0.5 -- -- d1 $ sound "breaks125*8" begin "-1" coarse "1 2 4 8 16 32 64 128" ---- -- This will play the breaks125 sample and apply the changing -- coarse parameter over the sample. Compare to: -- --
-- d1 $ (chop 8 $ sounds "breaks125") coarse "1 2 4 8 16 32 64 128" ---- -- which performs a similar effect, but due to differences in -- implementation sounds different. legato_p :: Param -- | a pattern of numbers from 0 to 1. Skips the beginning of each sample, -- e.g. `0.25` to cut off the first quarter from each sample. -- -- Using `begin "-1"` combined with `cut "-1"` means that when the sample -- cuts itself it will begin playback from where the previous one left -- off, so it will sound like one seamless sample. This allows you to -- apply a synth param across a long sample in a way similar to -- chop: -- --
-- cps 0.5 -- -- d1 $ sound "breaks125*8" begin "-1" coarse "1 2 4 8 16 32 64 128" ---- -- This will play the breaks125 sample and apply the changing -- coarse parameter over the sample. Compare to: -- --
-- d1 $ (chop 8 $ sounds "breaks125") coarse "1 2 4 8 16 32 64 128" ---- -- which performs a similar effect, but due to differences in -- implementation sounds different. clhatdecay_p :: Param -- | a pattern of numbers from 0 to 1. Skips the beginning of each sample, -- e.g. `0.25` to cut off the first quarter from each sample. -- -- Using `begin "-1"` combined with `cut "-1"` means that when the sample -- cuts itself it will begin playback from where the previous one left -- off, so it will sound like one seamless sample. This allows you to -- apply a synth param across a long sample in a way similar to -- chop: -- --
-- cps 0.5 -- -- d1 $ sound "breaks125*8" begin "-1" coarse "1 2 4 8 16 32 64 128" ---- -- This will play the breaks125 sample and apply the changing -- coarse parameter over the sample. Compare to: -- --
-- d1 $ (chop 8 $ sounds "breaks125") coarse "1 2 4 8 16 32 64 128" ---- -- which performs a similar effect, but due to differences in -- implementation sounds different. coarse_p :: Param -- | a pattern of numbers from 0 to 1. Skips the beginning of each sample, -- e.g. `0.25` to cut off the first quarter from each sample. -- -- Using `begin "-1"` combined with `cut "-1"` means that when the sample -- cuts itself it will begin playback from where the previous one left -- off, so it will sound like one seamless sample. This allows you to -- apply a synth param across a long sample in a way similar to -- chop: -- --
-- cps 0.5 -- -- d1 $ sound "breaks125*8" begin "-1" coarse "1 2 4 8 16 32 64 128" ---- -- This will play the breaks125 sample and apply the changing -- coarse parameter over the sample. Compare to: -- --
-- d1 $ (chop 8 $ sounds "breaks125") coarse "1 2 4 8 16 32 64 128" ---- -- which performs a similar effect, but due to differences in -- implementation sounds different. crush_p :: Param begin :: Pattern Double -> ParamPattern legato :: Pattern Double -> ParamPattern clhatdecay :: Pattern Double -> ParamPattern -- | bit crushing, a pattern of numbers from 1 (for drastic reduction in -- bit-depth) to 16 (for barely no reduction). crush :: Pattern Double -> ParamPattern -- | choose the physical channel the pattern is sent to, this is super dirt -- specific channel :: Pattern Int -> ParamPattern -- | fake-resampling, a pattern of numbers for lowering the sample rate, -- i.e. 1 for original 2 for half, 3 for a third and so on. coarse :: Pattern Int -> ParamPattern -- | In the style of classic drum-machines, cut will stop a playing -- sample as soon as another samples with in same cutgroup is to be -- played. -- -- An example would be an open hi-hat followed by a closed one, -- essentially muting the open. -- --
-- d1 $ stack [ -- sound "bd", -- sound "~ [~ [ho:2 hc/2]]" # cut "1" -- ] ---- -- This will mute the open hi-hat every second cycle when the closed one -- is played. -- -- Using cut with negative values will only cut the same sample. -- This is useful to cut very long samples -- --
-- d1 $ sound "bev, [ho:3]" # cut "-1" ---- -- Using `cut "0"` is effectively _no_ cutgroup. cut :: Pattern Int -> ParamPattern -- | a pattern of numbers from 0 to 1. Applies the cutoff frequency of the -- low-pass filter. cutoff :: Pattern Double -> ParamPattern cutoffegint :: Pattern Double -> ParamPattern decay :: Pattern Double -> ParamPattern -- | a pattern of numbers from 0 to 1. Sets the level of the delay signal. delay :: Pattern Double -> ParamPattern -- | a pattern of numbers from 0 to 1. Sets the amount of delay feedback. delayfeedback :: Pattern Double -> ParamPattern -- | a pattern of numbers from 0 to 1. Sets the length of the delay. delaytime :: Pattern Double -> ParamPattern detune :: Pattern Double -> ParamPattern -- | when set to `1` will disable all reverb for this pattern. See -- room and size for more information about reverb. dry :: Pattern Double -> ParamPattern end :: Pattern Double -> ParamPattern -- | a pattern of numbers that specify volume. Values less than 1 make the -- sound quieter. Values greater than 1 make the sound louder. gain :: Pattern Double -> ParamPattern gate :: Pattern Double -> ParamPattern hatgrain :: Pattern Double -> ParamPattern -- | a pattern of numbers from 0 to 1. Applies the cutoff frequency of the -- high-pass filter. hcutoff :: Pattern Double -> ParamPattern -- | a pattern of numbers to specify the hold time (in seconds) of an -- envelope applied to each sample. Only takes effect if attack -- and release are also specified. hold :: Pattern Double -> ParamPattern -- | a pattern of numbers from 0 to 1. Applies the resonance of the -- high-pass filter. hresonance :: Pattern Double -> ParamPattern kriole :: Pattern Int -> ParamPattern lagogo :: Pattern Double -> ParamPattern lclap :: Pattern Double -> ParamPattern lclaves :: Pattern Double -> ParamPattern lclhat :: Pattern Double -> ParamPattern lcrash :: Pattern Double -> ParamPattern lfo :: Pattern Double -> ParamPattern lfocutoffint :: Pattern Double -> ParamPattern lfodelay :: Pattern Double -> ParamPattern lfoint :: Pattern Double -> ParamPattern lfopitchint :: Pattern Double -> ParamPattern lfoshape :: Pattern Double -> ParamPattern lfosync :: Pattern Double -> ParamPattern lhitom :: Pattern Double -> ParamPattern lkick :: Pattern Double -> ParamPattern llotom :: Pattern Double -> ParamPattern -- | A pattern of numbers. Specifies whether delaytime is calculated -- relative to cps. When set to 1, delaytime is a direct multiple of a -- cycle. lock :: Pattern Double -> ParamPattern -- | loops the sample (from begin to end) the specified -- number of times. loop :: Pattern Double -> ParamPattern lophat :: Pattern Double -> ParamPattern lsnare :: Pattern Double -> ParamPattern -- | specifies the sample variation to be used n :: Pattern Int -> ParamPattern -- | Pushes things forward (or backwards within built-in latency) in time. -- Allows for nice things like _swing_ feeling: -- --
-- d1 $ stack [ -- sound "bd bd/4", -- sound "hh(5,8)" -- ] # nudge "[0 0.04]*4" ---- --
-- d1 $ stack [ -- sound "bd bd/4", -- sound "hh(5,8)" -- ] # nudge "[0 0.04]*4" ---- --
-- d1 $ stack [ -- sound "bd bd/4", -- sound "hh(5,8)" -- ] # nudge "[0 0.04]*4" ---- --
-- d1 $ stack [ -- sound "bd bd/4", -- sound "hh(5,8)" -- ] # nudge "[0 0.04]*4" ---- --
-- d1 $ stack [ -- sound "bd bd/4", -- sound "hh(5,8)" -- ] # nudge "[0 0.04]*4" ---- --
-- d1 $ stack [ -- sound "bd bd/4", -- sound "hh(5,8)" -- ] # nudge "[0 0.04]*4" ---- --
-- d1 $ sound "feel ! feel:1 feel:2" -- -- t1 (wash (chop 8) 4) $ sound "feel*4 [feel:2 sn:2]" ---- -- Note that `chop 8` is applied to `sound "feel ! feel:1 feel:2"` for 4 -- cycles and then the whole pattern is replaced by `sound "feel*4 -- [feel:2 sn:2]` wash :: (Pattern a -> Pattern a) -> Time -> Time -> [Pattern a] -> Pattern a -- | Just stop for a bit before playing new pattern wait :: Time -> Time -> [ParamPattern] -> ParamPattern -- | Just as wait, wait' stops for a bit and then applies the -- given transition to the playing pattern -- --
-- d1 $ sound "bd" -- -- t1 (wait' (xfadeIn 8) 4) $ sound "hh*8" --wait' :: (Time -> [ParamPattern] -> ParamPattern) -> Time -> Time -> [ParamPattern] -> ParamPattern -- | Jumps directly into the given pattern, this is essentially the _no -- transition_-transition. -- -- Variants of jump provide more useful capabilities, see -- jumpIn and jumpMod jump :: Time -> [ParamPattern] -> ParamPattern -- | Sharp jump transition after the specified number of cycles have -- passed. -- --
-- t1 (jumpIn 2) $ sound "kick(3,8)" --jumpIn :: Int -> Time -> [ParamPattern] -> ParamPattern -- | Unlike jumpIn the variant jumpIn' will only transition -- at cycle boundary (e.g. when the cycle count is an integer). jumpIn' :: Int -> Time -> [ParamPattern] -> ParamPattern -- | Sharp jump transition at next cycle boundary where cycle mod n -- == 0 jumpMod :: Int -> Time -> [ParamPattern] -> ParamPattern -- | Degrade the new pattern over time until it ends in silence mortal :: Time -> Time -> Time -> [ParamPattern] -> ParamPattern combineV :: (Value -> Value -> Value) -> ParamMap -> ParamMap -> ParamMap mixNums :: Double -> Value -> Value -> Value interpolateIn :: Time -> Time -> [ParamPattern] -> ParamPattern module Sound.Tidal.Dirt dirt :: Shape dirtSlang :: OscSlang superDirtSlang :: OscSlang superDirtBackend :: Int -> IO (Backend a) superDirtState :: Int -> IO (MVar (ParamPattern, [ParamPattern])) dirtBackend :: IO (Backend a) dirtStream :: IO (ParamPattern -> IO ()) dirtState :: IO (MVar (ParamPattern, [ParamPattern])) dirtSetters :: IO Time -> IO (ParamPattern -> IO (), (Time -> [ParamPattern] -> ParamPattern) -> ParamPattern -> IO ()) superDirtSetters :: IO Time -> IO (ParamPattern -> IO (), (Time -> [ParamPattern] -> ParamPattern) -> ParamPattern -> IO ()) superDirts :: [Int] -> IO [(ParamPattern -> IO (), (Time -> [ParamPattern] -> ParamPattern) -> ParamPattern -> IO ())] dirtstream :: t -> IO (ParamPattern -> IO ()) dirtToColour :: ParamPattern -> Pattern ColourD showToColour :: Show a => a -> ColourD datumToColour :: Value -> ColourD stringToColour :: String -> ColourD pick :: String -> Int -> String -- | Striate is a kind of granulator, for example: -- --
-- d1 $ striate 3 $ sound "ho ho:2 ho:3 hc" ---- -- This plays the loop the given number of times, but triggering -- progressive portions of each sample. So in this case it plays the loop -- three times, the first time playing the first third of each sample, -- then the second time playing the second third of each sample, etc.. -- With the highhat samples in the above example it sounds a bit like -- reverb, but it isn't really. -- -- You can also use striate with very long samples, to cut it into short -- chunks and pattern those chunks. This is where things get towards -- granular synthesis. The following cuts a sample into 128 parts, plays -- it over 8 cycles and manipulates those parts by reversing and rotating -- the loops. -- --
-- d1 $ slow 8 $ striate 128 $ sound "bev" --striate :: Int -> ParamPattern -> ParamPattern -- | The striate' function is a variant of striate with an -- extra parameter, which specifies the length of each part. The -- striate' function still scans across the sample over a single -- cycle, but if each bit is longer, it creates a sort of stuttering -- effect. For example the following will cut the bev sample into 32 -- parts, but each will be 1/16th of a sample long: -- --
-- d1 $ slow 32 $ striate' 32 (1/16) $ sound "bev" ---- -- Note that striate uses the begin and end -- parameters internally. This means that if you're using striate -- (or striate') you probably shouldn't also specify begin -- or end. striate' :: Int -> Double -> ParamPattern -> ParamPattern -- | like striate, but with an offset to the begin and end values striateO :: Int -> Double -> ParamPattern -> ParamPattern -- | Just like striate, but also loops each sample chunk a number of -- times specified in the second argument. The primed version is just -- like striate', where the loop count is the third argument. For -- example: -- --
-- d1 $ striateL' 3 0.125 4 $ sound "feel sn:2" ---- -- Like striate, these use the begin and end -- parameters internally, as well as the loop parameter for these -- versions. striateL :: Int -> Int -> ParamPattern -> ParamPattern striateL' :: Integral a => Int -> Double -> a -> ParamPattern -> ParamPattern metronome :: Pattern ParamMap -- | Also degrades the current pattern and undegrades the next. To change -- the number of cycles the transition takes, you can use -- clutchIn like so: -- --
-- d1 $ sound "bd(5,8)" -- -- t1 (clutchIn 8) $ sound "[hh*4, odx(3,8)]" ---- -- will take 8 cycles for the transition. clutchIn :: Time -> Time -> [Pattern a] -> Pattern a -- | Degrades the current pattern while undegrading the next. -- -- This is like xfade but not by gain of samples but by randomly -- removing events from the current pattern and slowly adding back in -- missing events from the next one. -- --
-- d1 $ sound "bd(3,8)" -- -- t1 clutch $ sound "[hh*4, odx(3,8)]" ---- -- clutch takes two cycles for the transition, essentially this -- is clutchIn 2. clutch :: Time -> [Pattern a] -> Pattern a -- | crossfades between old and new pattern over given number of cycles, -- e.g.: -- --
-- d1 $ sound "bd sn" -- -- t1 (xfadeIn 16) $ sound "jvbass*3" ---- -- Will fade over 16 cycles from "bd sn" to "jvbass*3" xfadeIn :: Time -> Time -> [ParamPattern] -> ParamPattern -- | Crossfade between old and new pattern over the next two cycles. -- --
-- d1 $ sound "bd sn" -- -- t1 xfade $ sound "can*3" ---- -- xfade is built with xfadeIn in this case taking two -- cycles for the fade. xfade :: Time -> [ParamPattern] -> ParamPattern -- | Stut applies a type of delay to a pattern. It has three parameters, -- which could be called depth, feedback and time. Depth is an integer -- and the others floating point. This adds a bit of echo: -- --
-- d1 $ stut 4 0.5 0.2 $ sound "bd sn" ---- -- The above results in 4 echos, each one 50% quieter than the last, with -- 1/5th of a cycle between them. It is possible to reverse the echo: -- --
-- d1 $ stut 4 0.5 (-0.2) $ sound "bd sn" --stut :: Integer -> Double -> Rational -> ParamPattern -> ParamPattern -- | Instead of just decreasing volume to produce echoes, stut' -- allows to apply a function for each step and overlays the result -- delayed by the given time. -- --
-- d1 $ stut' 2 (1%3) (# vowel "{a e i o u}%2") $ sound "bd sn"
--
--
-- In this case there are two _overlays_ delayed by 1/3 of a cycle, where
-- each has the vowel filter applied.
stut' :: Integer -> Time -> (ParamPattern -> ParamPattern) -> ParamPattern -> ParamPattern
-- | same as anticipate though it allows you to specify the number
-- of cycles until dropping to the new pattern, e.g.:
--
-- -- d1 $ sound "jvbass(3,8)" -- -- t1 (anticipateIn 4) $ sound "jvbass(5,8)" --anticipateIn :: Time -> Time -> [ParamPattern] -> ParamPattern -- | anticipate is an increasing comb filter. -- -- Build up some tension, culminating in a _drop_ to the new pattern -- after 8 cycles. anticipate :: Time -> [ParamPattern] -> ParamPattern -- | Copies the n parameter to the orbit parameter, so -- different sound variants or notes go to different orbits in SuperDirt. nToOrbit :: ParamPattern -> ParamPattern module Sound.Tidal.Strategies stutter :: Integral i => i -> Time -> Pattern a -> Pattern a echo :: Time -> Pattern a -> Pattern a triple :: Time -> Pattern a -> Pattern a quad :: Time -> Pattern a -> Pattern a double :: Time -> Pattern a -> Pattern a -- | 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) $ striate' 32 (1/16) $ sound "bev" ---- -- When passing pattern transforms to functions like jux and -- every, it's possible to chain multiple transforms together with -- ., 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) $ striate' 32 (1/16) $ sound "bev" --jux :: (ParamPattern -> Pattern ParamMap) -> ParamPattern -> Pattern ParamMap juxcut :: (ParamPattern -> Pattern ParamMap) -> ParamPattern -> Pattern ParamMap juxcut' :: [t -> ParamPattern] -> t -> Pattern ParamMap -- | In addition to jux, jux' allows using a list of pattern -- transform. resulting patterns from each transformation will be spread -- via pan from left to right. -- -- For example: -- --
-- d1 $ jux' [iter 4, chop 16, id, rev, palindrome] $ sound "bd sn" ---- -- 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 mid -- left mid right the chopped and the reversed version will appear. -- -- 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", -- ] --jux' :: [t -> ParamPattern] -> t -> Pattern ParamMap -- | Multichannel variant of jux, _not sure what it does_ jux4 :: (ParamPattern -> Pattern ParamMap) -> ParamPattern -> Pattern ParamMap -- | 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 (density 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. juxBy :: Double -> (ParamPattern -> Pattern ParamMap) -> ParamPattern -> Pattern ParamMap -- | Smash is a combination of spread and striate - it cuts -- the samples into the given number of bits, and then cuts between -- playing the loop at different speeds according to the values in the -- list. -- -- So this: -- --
-- d1 $ smash 3 [2,3,4] $ sound "ho ho:2 ho:3 hc" ---- -- Is a bit like this: -- --
-- d1 $ spread (slow) [2,3,4] $ striate 3 $ sound "ho ho:2 ho:3 hc" ---- -- This is quite dancehall: -- --
-- d1 $ (spread' slow "1%4 2 1 3" $ spread (striate) [2,3,4,1] $ sound -- "sn:2 sid:3 cp sid:4") -- # speed "[1 2 1 1]/2" --smash :: Int -> [Time] -> ParamPattern -> Pattern ParamMap -- | an altenative form to smash is smash' which will use -- chop instead of striate. smash' :: Int -> [Time] -> ParamPattern -> Pattern ParamMap samples :: Applicative f => f String -> f Int -> f String samples' :: Applicative f => f String -> f Int -> f String spreadf :: t1 -> t -> [a -> Pattern b] -> a -> Pattern b -- | spin will "spin" a layer up a pattern the given number of -- times, with each successive layer offset in time by an additional -- `1/n` of a cycle, and panned by an additional `1/n`. The result is a -- pattern that seems to spin around. This function works best on -- multichannel systems. -- --
-- d1 $ slow 3 $ spin 4 $ sound "drum*3 tabla:4 [arpy:2 ~ arpy] [can:2 can:3]" --spin :: Int -> ParamPattern -> ParamPattern sawwave4 :: Pattern Double sinewave4 :: Pattern Double rand4 :: Pattern Double stackwith :: Pattern ParamMap -> [ParamPattern] -> Pattern ParamMap -- | scale will take a pattern which goes from 0 to 1 (like -- sine1), and scale it to a different range - between the first -- and second arguments. In the below example, `scale 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 $ scale 1 1.5 sine1) --scale :: (Functor f, Num b) => b -> b -> f b -> f b -- | scalex is an exponential version of scale, good for -- using with frequencies. Do *not* use negative numbers or zero as -- arguments! scalex :: (Functor f, Floating b) => b -> b -> f b -> f b -- | chop granualizes every sample in place as it is played, turning -- a pattern of samples into a pattern of sample parts. Use an integer -- value to specify how many granules each sample is chopped into: -- --
-- d1 $ chop 16 $ sound "arpy arp feel*4 arpy*4" ---- -- Different values of chop can yield very different results, -- depending on the samples used: -- --
-- d1 $ chop 16 $ sound (samples "arpy*8" (run 16)) -- d1 $ chop 32 $ sound (samples "arpy*8" (run 16)) -- d1 $ chop 256 $ sound "bd*4 [sn cp] [hh future]*2 [cp feel]" --chop :: Int -> ParamPattern -> ParamPattern chop' :: Pattern Int -> ParamPattern -> Pattern ParamMap -- | gap is similar to chop in that it granualizes every -- sample in place as it is played, but every other grain is silent. Use -- an integer value to specify how many granules each sample is chopped -- into: -- --
-- d1 $ gap 8 $ sound "jvbass" -- d1 $ gap 16 $ sound "[jvbass drum:4]" --gap :: Int -> ParamPattern -> ParamPattern chopArc :: Arc -> Int -> [Arc] en :: [(Int, Int)] -> Pattern String -> Pattern String -- | weave applies a function smoothly over an array of different -- patterns. It uses an OscPattern to apply the function at -- different levels to each pattern, creating a weaving effect. -- --
-- d1 $ weave 3 (shape $ sine1) [sound "bd [sn drum:2*2] bd*2 [sn drum:1]", sound "arpy*8 ~"] --weave :: Rational -> ParamPattern -> [ParamPattern] -> ParamPattern -- | weave' is similar in that it blends functions at the same time -- at different amounts over a pattern: -- --
-- d1 $ weave' 3 (sound "bd [sn drum:2*2] bd*2 [sn drum:1]") [density 2, (# speed "0.5"), chop 16] --weave' :: Rational -> Pattern a -> [Pattern a -> Pattern a] -> Pattern a -- | (A function that takes two OscPatterns, and blends them together into -- a new OscPattern. An OscPattern is basically a pattern of messages to -- a synthesiser.) -- -- Shifts between the two given patterns, using distortion. -- -- Example: -- --
-- d1 $ interlace (sound "bd sn kurt") (every 3 rev $ sound "bd sn:2") --interlace :: ParamPattern -> ParamPattern -> ParamPattern -- | Step sequencing step :: String -> String -> Pattern String steps :: [(String, String)] -> Pattern String -- | like step, but allows you to specify an array of strings to use -- for 0,1,2... step' :: [String] -> String -> Pattern String off :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a offadd :: Num a => Time -> a -> Pattern a -> Pattern a -- | up does a poor man's pitchshift by semitones via speed. -- -- You can easily produce melodies from a single sample with up: -- --
-- d1 sound "arpy" ---- -- This will play the _arpy_ sample four times a cycle in the original -- pitch, pitched by 5 semitones, by 4 and then by an octave. up :: Pattern Double -> ParamPattern ghost'' :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a ghost' :: t -> Pattern ParamMap -> Pattern ParamMap ghost :: Pattern ParamMap -> Pattern ParamMap slice :: Int -> Int -> ParamPattern -> ParamPattern randslice :: Int -> ParamPattern -> ParamPattern -- | loopAt makes a sample fit the given number of cycles. -- Internally, it works by setting the unit parameter to "c", -- changing the playback speed of the sample with the speed -- parameter, and setting setting the density of the pattern to -- match. -- --
-- d1 $ loopAt 4 $ sound "breaks125" -- d1 $ juxBy 0.6 (|*| speed "2") $ slowspread (loopAt) [4,6,2,3] $ chop 12 $ sound "fm:14" --loopAt :: Time -> ParamPattern -> ParamPattern -- | tabby - A more literal weaving than the weave function, give -- number of threads per cycle and two patterns, and this -- function will weave them together using a plain (aka tabby) -- weave, with a simple over/under structure tabby :: Integer -> Pattern a -> Pattern a -> Pattern a module Sound.Tidal.Context