tidal 1.7.1 → 1.7.2
raw patch · 21 files changed
+3831/−2312 lines, 21 files
Files
- BootTidal.hs +2/−10
- CHANGELOG.md +8/−0
- src/Sound/Tidal/Carabiner.hs +5/−5
- src/Sound/Tidal/Chords.hs +144/−90
- src/Sound/Tidal/Control.hs +18/−18
- src/Sound/Tidal/Core.hs +10/−10
- src/Sound/Tidal/Params.hs +2960/−1626
- src/Sound/Tidal/ParseBP.hs +25/−18
- src/Sound/Tidal/Pattern.hs +363/−436
- src/Sound/Tidal/Show.hs +33/−19
- src/Sound/Tidal/Simple.hs +2/−2
- src/Sound/Tidal/Stream.hs +57/−31
- src/Sound/Tidal/Tempo.hs +14/−15
- src/Sound/Tidal/Time.hs +130/−0
- src/Sound/Tidal/UI.hs +17/−17
- src/Sound/Tidal/Utils.hs +11/−7
- src/Sound/Tidal/Version.hs +1/−1
- test/Sound/Tidal/ParseTest.hs +8/−0
- test/Sound/Tidal/PatternTest.hs +1/−1
- test/TestUtils.hs +20/−1
- tidal.cabal +2/−5
BootTidal.hs view
@@ -4,11 +4,6 @@ import Sound.Tidal.Context import System.IO (hSetEncoding, stdout, utf8)--import qualified Control.Concurrent.MVar as MV-import qualified Sound.Tidal.Tempo as Tempo-import qualified Sound.OSC.FD as O- hSetEncoding stdout utf8 -- total latency = oLatency + cFrameTimespan@@ -33,11 +28,8 @@ all = streamAll tidal resetCycles = streamResetCycles tidal setcps = asap . cps- getcps = do tempo <- MV.readMVar $ sTempoMV tidal- return $ Tempo.cps tempo- getnow = do tempo <- MV.readMVar $ sTempoMV tidal- now <- O.time- return $ fromRational $ Tempo.timeToCycles tempo now+ getcps = streamGetcps tidal+ getnow = streamGetnow tidal xfade i = transition tidal True (Sound.Tidal.Transition.xfadeIn 4) i xfadeIn i t = transition tidal True (Sound.Tidal.Transition.xfadeIn t) i histpan i t = transition tidal True (Sound.Tidal.Transition.histpan t) i
CHANGELOG.md view
@@ -1,5 +1,13 @@ # TidalCycles log of changes +## 1.7.2 - IKLECTIK c+ * tidal-parse additions and improved errors, haskellish dependency fix @dktr0+ * spring cleaning and delinting, recreated Time.hs, renamed ControlMap toValueMAp @yaxu+ * start of [major refactoring of chords](https://club.tidalcycles.org/t/rfc-working-on-making-chord-naming-chordlist-more-consistent/2717/56) @cleary+ * fix `.` mininotation operator @zudov+ * stateful event parameters, for counting @yaxu+ * Move some stuff from BootTidal.hs to the tidal library, to reduce dependencies there @yaxu+ ## 1.7.1 - IKLECTIK b * Fix stack build @yaxu * Add tidal_status command @yaxu
src/Sound/Tidal/Carabiner.hs view
@@ -53,7 +53,7 @@ let msg = B8.unpack rMsg (name:_:ws) = words msg pairs = pairs' ws- pairs' (a:b:xs) = (a,b):(pairs' xs)+ pairs' (a:b:xs) = (a,b):pairs' xs pairs' _ = [] act tidal bpc latency name pairs @@ -65,17 +65,17 @@ when (and [isJust start, isJust bpm, isJust beat]) $ do nowM <- getTime Monotonic nowO <- O.time- let m = (fromIntegral $ sec nowM) + ((fromIntegral $ nsec nowM)/1000000000)+ let m = fromIntegral (sec nowM) + (fromIntegral (nsec nowM)/1000000000) d = nowO - m- start' = ((fromIntegral $ fromJust start) / 1000000)+ start' = fromIntegral (fromJust start) / 1000000 startO = start' + d -- cyc = toRational $ (fromJust beat) / (fromIntegral bpc) tempo <- takeMVar (S.sTempoMV tidal) let tempo' = tempo {atTime = startO + latency, atCycle = 0,- cps = ((fromJust bpm) / 60) / (fromIntegral bpc)+ cps = (fromJust bpm / 60) / fromIntegral bpc }- putMVar (S.sTempoMV tidal) $ tempo'+ putMVar (S.sTempoMV tidal) tempo' act _ _ _ name _ = putStr $ "Unhandled thingie " ++ name sendMsg :: Socket -> String -> IO ()
src/Sound/Tidal/Chords.hs view
@@ -22,70 +22,95 @@ import Sound.Tidal.Pattern +-- major chords major :: Num a => [a] major = [0,4,7]-minor :: Num a => [a]-minor = [0,3,7]+aug :: Num a => [a]+aug = [0,4,8]+six :: Num a => [a]+six = [0,4,7,9]+sixNine :: Num a => [a]+sixNine = [0,4,7,9,14] major7 :: Num a => [a] major7 = [0,4,7,11]+major9 :: Num a => [a]+major9 = [0,4,7,11,14]+add9 :: Num a => [a]+add9 = [0,4,7,14]+major11 :: Num a => [a]+major11 = [0,4,7,11,14,17]+add11 :: Num a => [a]+add11 = [0,4,7,17]+major13 :: Num a => [a]+major13 = [0,4,7,11,14,21]+add13 :: Num a => [a]+add13 = [0,4,7,21]+-- dominant chords dom7 :: Num a => [a] dom7 = [0,4,7,10]+dom9 :: Num a => [a]+dom9 = [0,4,7,14]+dom11 :: Num a => [a]+dom11 = [0,4,7,17]+dom13 :: Num a => [a]+dom13 = [0,4,7,21]+sevenFlat5 :: Num a => [a]+sevenFlat5 = [0,4,6,10]+sevenSharp5 :: Num a => [a]+sevenSharp5 = [0,4,8,10]+sevenFlat9 :: Num a => [a]+sevenFlat9 = [0,4,7,10,13]+nine :: Num a => [a]+nine = [0,4,7,10,14]+eleven :: Num a => [a]+eleven = [0,4,7,10,14,17]+thirteen :: Num a => [a]+thirteen = [0,4,7,10,14,17,21]+-- minor chords+minor :: Num a => [a]+minor = [0,3,7]+diminished :: Num a => [a]+diminished = [0,3,6]+minorSharp5 :: Num a => [a]+minorSharp5 = [0,3,8]+minor6 :: Num a => [a]+minor6 = [0,3,7,9]+minorSixNine :: Num a => [a]+minorSixNine = [0,3,9,7,14]+minor7flat5 :: Num a => [a]+minor7flat5 = [0,3,6,10] minor7 :: Num a => [a] minor7 = [0,3,7,10]-aug :: Num a => [a]-aug = [0,4,8]-dim :: Num a => [a]-dim = [0,3,6]-dim7 :: Num a => [a]-dim7 = [0,3,6,9]+minor7sharp5 :: Num a => [a]+minor7sharp5 = [0,3,8,10]+minor7flat9 :: Num a => [a]+minor7flat9 = [0,3,7,10,13]+minor7sharp9 :: Num a => [a]+minor7sharp9 = [0,3,7,10,14]+diminished7 :: Num a => [a]+diminished7 = [0,3,6,9]+minor9 :: Num a => [a]+minor9 = [0,3,7,10,14]+minor11 :: Num a => [a]+minor11 = [0,3,7,10,14,17]+minor13 :: Num a => [a]+minor13 = [0,3,7,10,14,17,21]+-- other chords one :: Num a => [a] one = [0] five :: Num a => [a] five = [0,7]-plus :: Num a => [a]-plus = [0,4,8]-sharp5 :: Num a => [a]-sharp5 = [0,4,8]-msharp5 :: Num a => [a]-msharp5 = [0,3,8] sus2 :: Num a => [a] sus2 = [0,2,7] sus4 :: Num a => [a] sus4 = [0,5,7]-six :: Num a => [a]-six = [0,4,7,9]-m6 :: Num a => [a]-m6 = [0,3,7,9] sevenSus2 :: Num a => [a] sevenSus2 = [0,2,7,10] sevenSus4 :: Num a => [a] sevenSus4 = [0,5,7,10]-sevenFlat5 :: Num a => [a]-sevenFlat5 = [0,4,6,10]-m7flat5 :: Num a => [a]-m7flat5 = [0,3,6,10]-sevenSharp5 :: Num a => [a]-sevenSharp5 = [0,4,8,10]-m7sharp5 :: Num a => [a]-m7sharp5 = [0,3,8,10]-nine :: Num a => [a]-nine = [0,4,7,10,14]-m9 :: Num a => [a]-m9 = [0,3,7,10,14]-m7sharp9 :: Num a => [a]-m7sharp9 = [0,3,7,10,14]-maj9 :: Num a => [a]-maj9 = [0,4,7,11,14] nineSus4 :: Num a => [a] nineSus4 = [0,5,7,10,14]-sixby9 :: Num a => [a]-sixby9 = [0,4,7,9,14]-m6by9 :: Num a => [a]-m6by9 = [0,3,9,7,14]-sevenFlat9 :: Num a => [a]-sevenFlat9 = [0,4,7,10,13]-m7flat9 :: Num a => [a]-m7flat9 = [0,3,7,10,13]+-- questionable chords sevenFlat10 :: Num a => [a] sevenFlat10 = [0,4,7,10,15] nineSharp5 :: Num a => [a]@@ -96,20 +121,10 @@ sevenSharp5flat9 = [0,4,8,10,13] m7sharp5flat9 :: Num a => [a] m7sharp5flat9 = [0,3,8,10,13]-eleven :: Num a => [a]-eleven = [0,4,7,10,14,17]-m11 :: Num a => [a]-m11 = [0,3,7,10,14,17]-maj11 :: Num a => [a]-maj11 = [0,4,7,11,14,17] elevenSharp :: Num a => [a] elevenSharp = [0,4,7,10,14,18] m11sharp :: Num a => [a] m11sharp = [0,3,7,10,14,18]-thirteen :: Num a => [a]-thirteen = [0,4,7,10,14,17,21]-m13 :: Num a => [a]-m13 = [0,3,7,10,14,17,21] -- | @chordate cs m n@ selects the @n@th "chord" (a chord is a list of Ints) -- from a list of chords @cs@ and transposes it by @m@@@ -126,55 +141,101 @@ chordTable :: Num a => [(String, [a])] chordTable = [("major", major), ("maj", major),- ("minor", minor),- ("min", minor), ("aug", aug),- ("dim", dim),+ ("plus", aug),+ ("sharp5", aug),+ ("six", six),+ ("6", six),+ ("sixNine", sixNine),+ ("six9", sixNine),+ ("sixby9", sixNine),+ ("6by9", sixNine), ("major7", major7), ("maj7", major7),+ ("major9", major9),+ ("maj9", major9),+ ("add9", add9),+ ("major11", major11),+ ("maj11", major11),+ ("add11", add11),+ ("major13", major13),+ ("maj13", major13),+ ("add13", add13), ("dom7", dom7),+ ("dom9", dom9),+ ("dom11", dom11),+ ("dom13", dom13),+ ("sevenFlat5", sevenFlat5),+ ("7f5", sevenFlat5),+ ("sevenSharp5", sevenSharp5),+ ("7s5", sevenSharp5),+ ("sevenFlat9", sevenFlat9),+ ("7f9", sevenFlat9),+ ("nine", nine),+ ("eleven", eleven),+ ("11", eleven),+ ("thirteen", thirteen),+ ("13", thirteen),+ ("minor", minor),+ ("min", minor),+ ("diminished", diminished),+ ("dim", diminished),+ ("minorSharp5", minorSharp5),+ ("msharp5", minorSharp5),+ ("mS5", minorSharp5),+ ("minor6", minor6),+ ("min6", minor6),+ ("m6", minor6),+ ("minorSixNine", minorSixNine),+ ("minor69", minorSixNine),+ ("min69", minorSixNine),+ ("minSixNine", minorSixNine),+ ("m69", minorSixNine),+ ("mSixNine", minorSixNine),+ ("m6by9", minorSixNine),+ ("minor7flat5", minor7flat5),+ ("min7flat5", minor7flat5),+ ("m7flat5", minor7flat5),+ ("m7f5", minor7flat5), ("minor7", minor7), ("min7", minor7),- ("dim7", dim7),+ ("m7", minor7),+ ("minor7sharp5", minor7sharp5),+ ("min7sharp5", minor7sharp5),+ ("m7sharp5", minor7sharp5),+ ("m7s5", minor7sharp5),+ ("minor7flat9", minor7flat9),+ ("min7flat9", minor7flat9),+ ("m7flat9", minor7flat9),+ ("m7f9", minor7flat9),+ ("minor7sharp9", minor7sharp9),+ ("min7sharp9", minor7sharp9),+ ("m7sharp9", minor7sharp9),+ ("m7s9", minor7sharp9),+ ("diminished7", diminished7),+ ("dim7", diminished7),+ ("minor9", minor9),+ ("min9", minor9),+ ("m9", minor9),+ ("minor11", minor11),+ ("min11", minor11),+ ("m11", minor11),+ ("minor13", minor13),+ ("min13", minor13),+ ("m13", minor13), ("one", one), ("1", one), ("five", five), ("5", five),- ("plus", plus),- ("sharp5", sharp5),- ("msharp5", msharp5), ("sus2", sus2), ("sus4", sus4),- ("six", six),- ("6", six),- ("m6", m6), ("sevenSus2", sevenSus2), ("7sus2", sevenSus2), ("sevenSus4", sevenSus4), ("7sus4", sevenSus4),- ("sevenFlat5", sevenFlat5),- ("7f5", sevenFlat5),- ("m7flat5", m7flat5),- ("m7f5", m7flat5),- ("sevenSharp5", sevenSharp5),- ("7s5", sevenSharp5),- ("m7sharp5", m7sharp5),- ("m7s5", m7sharp5),- ("nine", nine),- ("m9", m9),- ("m7sharp9", m7sharp9),- ("m7s9", m7sharp9),- ("maj9", maj9), ("nineSus4", nineSus4), ("ninesus4", nineSus4), ("9sus4", nineSus4),- ("sixby9", sixby9),- ("6by9", sixby9),- ("m6by9", m6by9),- ("sevenFlat9", sevenFlat9),- ("7f9", sevenFlat9),- ("m7flat9", m7flat9),- ("m7f9", m7flat9), ("sevenFlat10", sevenFlat10), ("7f10", sevenFlat10), ("nineSharp5", nineSharp5),@@ -184,17 +245,10 @@ ("sevenSharp5flat9", sevenSharp5flat9), ("7s5f9", sevenSharp5flat9), ("m7sharp5flat9", m7sharp5flat9),- ("eleven", eleven),- ("11", eleven),- ("m11", m11),- ("maj11", maj11), ("elevenSharp", elevenSharp), ("11s", elevenSharp), ("m11sharp", m11sharp),- ("m11s", m11sharp),- ("thirteen", thirteen),- ("13", thirteen),- ("m13", m13)+ ("m11s", m11sharp) ] chordL :: Num a => Pattern String -> Pattern [a]
src/Sound/Tidal/Control.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, OverloadedStrings, FlexibleContexts, BangPatterns #-}+{-# LANGUAGE FlexibleInstances, OverloadedStrings, FlexibleContexts, BangPatterns #-} module Sound.Tidal.Control where @@ -83,7 +83,7 @@ _chop :: Int -> ControlPattern -> ControlPattern _chop n = withEvents (concatMap chopEvent) where -- for each part,- chopEvent :: Event ControlMap -> [Event ControlMap]+ chopEvent :: Event ValueMap -> [Event ValueMap] chopEvent (Event c (Just w) p' v) = map (chomp c v (length $ chopArc w n)) $ arcs w p' -- ignoring 'analog' events (those without wholes), chopEvent _ = []@@ -97,7 +97,7 @@ -- if the old event had a begin and end, then multiply the new -- begin and end values by the old difference (end-begin), and -- add the old begin- chomp :: Context -> ControlMap -> Int -> (Int, (Arc, Arc)) -> Event ControlMap+ chomp :: Context -> ValueMap -> Int -> (Int, (Arc, Arc)) -> Event ValueMap chomp c v n' (i, (w,p')) = Event c (Just w) p' (Map.insert "begin" (VF b') $ Map.insert "end" (VF e') v) where b = fromMaybe 0 $ do v' <- Map.lookup "begin" v getF v'@@ -149,7 +149,7 @@ _striate n p = fastcat $ map offset [0 .. n-1] where offset i = mergePlayRange (fromIntegral i / fromIntegral n, fromIntegral (i+1) / fromIntegral n) <$> p -mergePlayRange :: (Double, Double) -> ControlMap -> ControlMap+mergePlayRange :: (Double, Double) -> ValueMap -> ValueMap mergePlayRange (b,e) cm = Map.insert "begin" (VF ((b*d')+b')) $ Map.insert "end" (VF ((e*d')+b')) cm where b' = fromMaybe 0 $ Map.lookup "begin" cm >>= getF e' = fromMaybe 1 $ Map.lookup "end" cm >>= getF@@ -197,7 +197,7 @@ gap :: Pattern Int -> ControlPattern -> ControlPattern gap = tParam _gap -_gap :: Int -> ControlPattern -> ControlPattern +_gap :: Int -> ControlPattern -> ControlPattern _gap n p = _fast (toRational n) (cat [pure 1, silence]) |>| _chop n p {- |@@ -220,7 +220,7 @@ -} weaveWith :: Time -> Pattern a -> [Pattern a -> Pattern a] -> Pattern a weaveWith t p fs | l == 0 = silence- | otherwise = _slow t $ stack $ map (\(i, f) -> (fromIntegral i % l) `rotL` _fast t (f (_slow t p))) (zip [0 :: Int ..] fs)+ | otherwise = _slow t $ stack $ zipWith (\ i f -> (fromIntegral i % l) `rotL` _fast t (f (_slow t p))) [0 :: Int ..] fs where l = fromIntegral $ length fs weave' :: Time -> Pattern a -> [Pattern a -> Pattern a] -> Pattern a@@ -286,8 +286,8 @@ _splice :: Int -> Pattern Int -> ControlPattern -> Pattern (Map.Map String Value) _splice bits ipat pat = withEvent f (slice (pure bits) ipat pat) # P.unit (pure "c") where f ev = ev {value = Map.insert "speed" (VF d) (value ev)}- where d = sz / (fromRational $ (wholeStop ev) - (wholeStart ev))- sz = 1/(fromIntegral bits)+ where d = sz / fromRational (wholeStop ev - wholeStart ev)+ sz = 1/fromIntegral bits splice :: Pattern Int -> Pattern Int -> ControlPattern -> Pattern (Map.Map String Value) splice bitpat ipat pat = innerJoin $ (\bits -> _splice bits ipat pat) <$> bitpat@@ -334,13 +334,13 @@ @ -} -smash :: Pattern Int -> [Pattern Time] -> ControlPattern -> Pattern ControlMap+smash :: Pattern Int -> [Pattern Time] -> ControlPattern -> Pattern ValueMap smash n xs p = slowcat $ map (`slow` p') xs where p' = striate n p {- | an altenative form to `smash` is `smash'` which will use `chop` instead of `striate`. -}-smash' :: Int -> [Pattern Time] -> ControlPattern -> Pattern ControlMap+smash' :: Int -> [Pattern Time] -> ControlPattern -> ControlPattern smash' n xs p = slowcat $ map (`slow` p') xs where p' = _chop n p @@ -395,13 +395,13 @@ -- | Turns a pattern of milliseconds into a pattern of (rational) -- cycle durations, according to the current cps. msec :: Fractional a => Pattern a -> Pattern a-msec p = ((realToFrac . (/1000)) <$> cF 1 "_cps") *| p+msec p = (realToFrac . (/1000) <$> cF 1 "_cps") *| p triggerWith :: Show a => (Time -> Time) -> a -> Pattern b -> Pattern b triggerWith f k pat = pat {query = q}- where q st = query ((offset st) ~> pat) st- offset st = fromMaybe (pure 0) $ do p <- Map.lookup ctrl (controls st)- return $ ((f . fromMaybe 0 . getR) <$> p)+ where q st = query (rotR (offset st) pat) st+ offset st = fromMaybe 0 $ do v <- Map.lookup ctrl (controls st)+ return (f $ fromMaybe 0 $ getR v) ctrl = "_t_" ++ show k trigger :: Show a => a -> Pattern b -> Pattern b@@ -424,11 +424,11 @@ reset :: Show a => a -> Pattern b -> Pattern b reset k pat = pat {query = q}- where q st = query ((offset st) ~> (when (<=0) (const silence) pat)) st+ where q st = query (rotR (offset st) $ when (<=0) (const silence) pat) st f = (fromIntegral :: Int -> Rational) . floor- offset st = fromMaybe (pure 0) $ do p <- Map.lookup ctrl (controls st)- return $ ((f . fromMaybe 0 . getR) <$> p)+ offset st = fromMaybe 0 $ do p <- Map.lookup ctrl (controls st)+ return (f $ fromMaybe 0 $ getR p) ctrl = "_t_" ++ show k splat :: Pattern Int -> ControlPattern -> ControlPattern -> ControlPattern-splat slices epat pat = (chop slices pat) # bite 1 (const 0 <$> pat) epat+splat slices epat pat = chop slices pat # bite 1 (const 0 <$> pat) epat
src/Sound/Tidal/Core.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, BangPatterns #-}+{-# LANGUAGE FlexibleInstances, BangPatterns #-} {- Core.hs - For functions judged to be 'core' to tidal functionality.@@ -74,7 +74,7 @@ -- following a sawtooth with frequency of one cycle, and amplitude from -- -1 to 1. saw2 :: (Fractional a, Real a) => Pattern a-saw2 = sig $ \t -> (mod' (fromRational t) 1) * 2 - 1+saw2 = sig $ \t -> mod' (fromRational t) 1 * 2 - 1 -- | @isaw@ like @saw@, but a descending (inverse) sawtooth. isaw :: (Fractional a, Real a) => Pattern a@@ -109,7 +109,7 @@ -- -1 to 1. square2 :: (Fractional a) => Pattern a square2 = sig $- \t -> fromIntegral ((floor $ mod' (fromRational t :: Double) 1 * 2) * 2 - 1 :: Integer)+ \t -> fromIntegral (floor (mod' (fromRational t :: Double) 1 * 2) * 2 - 1 :: Integer) -- | @envL@ is a 'Pattern' of continuous 'Double' values, representing -- a linear interpolation between 0 and 1 during the first cycle, then@@ -141,7 +141,7 @@ instance Unionable a where union = const -instance {-# OVERLAPPING #-} Unionable ControlMap where+instance {-# OVERLAPPING #-} Unionable ValueMap where union = Map.union (|+|) :: (Applicative a, Num b) => a b -> a b -> a b@@ -259,7 +259,7 @@ -- in turn, then the second cycle from each, and so on. cat :: [Pattern a] -> Pattern a cat [] = silence-cat ps = Pattern $ q+cat ps = Pattern q where n = length ps q st = concatMap (f st) $ arcCyclesZW (arc st) f st a = query (withResultTime (+offset) p) $ st {arc = Arc (subtract offset (start a)) (subtract offset (stop a))}@@ -376,11 +376,11 @@ }) } where makeWholeRelative :: Event a -> Event a- makeWholeRelative (e@(Event {whole = Nothing})) = e+ makeWholeRelative e@Event {whole = Nothing} = e makeWholeRelative (Event c (Just (Arc s e)) p'@(Arc s' e') v) = Event c (Just $ Arc (s'-s) (e-e')) p' v makeWholeAbsolute :: Event a -> Event a- makeWholeAbsolute (e@(Event {whole = Nothing})) = e+ makeWholeAbsolute e@Event {whole = Nothing} = e makeWholeAbsolute (Event c (Just (Arc s e)) p'@(Arc s' e') v) = Event c (Just $ Arc (s'-e) (e'+s)) p' v midCycle :: Arc -> Time@@ -494,13 +494,13 @@ _getP_ f pat = filterJust $ f <$> pat _getP :: a -> (Value -> Maybe a) -> Pattern Value -> Pattern a-_getP d f pat = (fromMaybe d . f) <$> pat+_getP d f pat = fromMaybe d . f <$> pat _cX :: a -> (Value -> Maybe a) -> String -> Pattern a-_cX d f s = Pattern $ \(State a m) -> queryArc (maybe (pure d) (_getP d f) $ Map.lookup s m) a+_cX d f s = Pattern $ \(State a m) -> queryArc (maybe (pure d) (_getP d f . valueToPattern) $ Map.lookup s m) a _cX_ :: (Value -> Maybe a) -> String -> Pattern a-_cX_ f s = Pattern $ \(State a m) -> queryArc (maybe silence (_getP_ f) $ Map.lookup s m) a+_cX_ f s = Pattern $ \(State a m) -> queryArc (maybe silence (_getP_ f . valueToPattern) $ Map.lookup s m) a cF :: Double -> String -> Pattern Double cF d = _cX d getF
src/Sound/Tidal/Params.hs view
@@ -29,1632 +29,2966 @@ import Sound.Tidal.Utils import Data.Maybe (fromMaybe) import Data.Word (Word8)---- | group multiple params into one-grp :: [String -> ControlMap] -> Pattern String -> ControlPattern-grp [] _ = empty-grp fs p = splitby <$> p- where splitby name = Map.unions $ map (\(v, f) -> f v) $ zip (split name) fs- split :: String -> [String]- split = wordsBy (==':')--mF :: String -> String -> ControlMap-mF name v = fromMaybe Map.empty $ do f <- readMaybe v- return $ Map.singleton name (VF f)--mI :: String -> String -> ControlMap-mI name v = fromMaybe Map.empty $ do i <- readMaybe v- return $ Map.singleton name (VI i)--mS :: String -> String -> ControlMap-mS name v = Map.singleton name (VS v)---- | Param makers--pF :: String -> Pattern Double -> ControlPattern-pF name = fmap (Map.singleton name . VF)--pI :: String -> Pattern Int -> ControlPattern-pI name = fmap (Map.singleton name . VI)--pB :: String -> Pattern Bool -> ControlPattern-pB name = fmap (Map.singleton name . VB)- -pR :: String -> Pattern Rational -> ControlPattern-pR name = fmap (Map.singleton name . VR)--pN :: String -> Pattern Note -> ControlPattern-pN name = fmap (Map.singleton name . VN)--pS :: String -> Pattern String -> ControlPattern-pS name = fmap (Map.singleton name . VS)--pX :: String -> Pattern [Word8] -> ControlPattern-pX name = fmap (Map.singleton name . VX)---- | Grouped params--sound :: Pattern String -> ControlPattern-sound = grp [mS "s", mF "n"]--cc :: Pattern String -> ControlPattern-cc = grp [mF "ccn", mF "ccv"]--nrpn :: Pattern String -> ControlPattern-nrpn = grp [mI "nrpn", mI "val"]--grain' :: Pattern String -> ControlPattern-grain' = grp [mF "begin", mF "end"]--midinote :: Pattern Note -> ControlPattern-midinote = note . (subtract 60 <$>)--drum :: Pattern String -> ControlPattern-drum = n . (subtract 60 . drumN <$>)--drumN :: Num a => String -> a-drumN "hq" = 27-drumN "sl" = 28-drumN "ps" = 29-drumN "pl" = 30-drumN "st" = 31-drumN "sq" = 32-drumN "ml" = 33-drumN "mb" = 34-drumN "ab" = 35-drumN "bd" = 36-drumN "rm" = 37-drumN "sn" = 38-drumN "cp" = 39-drumN "es" = 40-drumN "lf" = 41-drumN "ch" = 42-drumN "lt" = 43-drumN "hh" = 44-drumN "ft" = 45-drumN "oh" = 46-drumN "mt" = 47-drumN "hm" = 48-drumN "cr" = 49-drumN "ht" = 50-drumN "ri" = 51-drumN "cy" = 52-drumN "be" = 53-drumN "ta" = 54-drumN "sc" = 55-drumN "cb" = 56-drumN "cs" = 57-drumN "vi" = 58-drumN "rc" = 59-drumN "hb" = 60-drumN "lb" = 61-drumN "mh" = 62-drumN "hc" = 63-drumN "lc" = 64-drumN "he" = 65-drumN "le" = 66-drumN "ag" = 67-drumN "la" = 68-drumN "ca" = 69-drumN "ma" = 70-drumN "sw" = 71-drumN "lw" = 72-drumN "sg" = 73-drumN "lg" = 74-drumN "cl" = 75-drumN "hi" = 76-drumN "li" = 77-drumN "mc" = 78-drumN "oc" = 79-drumN "tr" = 80-drumN "ot" = 81-drumN "sh" = 82-drumN "jb" = 83-drumN "bt" = 84-drumN "ct" = 85-drumN "ms" = 86-drumN "os" = 87-drumN _ = 0---- Generated params---- | a pattern of numbers that speed up (or slow down) samples while they play.-accelerate :: Pattern Double -> ControlPattern-accelerate = pF "accelerate"-acceleratebus :: Pattern Int -> Pattern Double -> ControlPattern-acceleratebus busid pat = (pF "accelerate" pat) # (pI "^accelerate" busid)-acceleraterecv :: Pattern Int -> ControlPattern-acceleraterecv busid = pI "^accelerate" busid---- | like @gain@, but linear.-amp :: Pattern Double -> ControlPattern-amp = pF "amp"-ampbus :: Pattern Int -> Pattern Double -> ControlPattern-ampbus busid pat = (pF "amp" pat) # (pI "^amp" busid)-amprecv :: Pattern Int -> ControlPattern-amprecv busid = pI "^amp" busid---- | -array :: Pattern [Word8] -> ControlPattern-array = pX "array"-arraybus :: Pattern Int -> Pattern [Word8] -> ControlPattern-arraybus busid pat = (pX "array" pat) # (pI "^array" busid)-arrayrecv :: Pattern Int -> ControlPattern-arrayrecv busid = pI "^array" busid---- | a pattern of numbers to specify the attack time (in seconds) of an envelope applied to each sample.-attack :: Pattern Double -> ControlPattern-attack = pF "attack"-attackbus :: Pattern Int -> Pattern Double -> ControlPattern-attackbus busid pat = (pF "attack" pat) # (pI "^attack" busid)-attackrecv :: Pattern Int -> ControlPattern-attackrecv busid = pI "^attack" busid---- | a pattern of numbers from 0 to 1. Sets the center frequency of the band-pass filter.-bandf :: Pattern Double -> ControlPattern-bandf = pF "bandf"-bandfbus :: Pattern Int -> Pattern Double -> ControlPattern-bandfbus busid pat = (pF "bandf" pat) # (pI "^bandf" busid)-bandfrecv :: Pattern Int -> ControlPattern-bandfrecv busid = pI "^bandf" busid---- | a pattern of anumbers from 0 to 1. Sets the q-factor of the band-pass filter.-bandq :: Pattern Double -> ControlPattern-bandq = pF "bandq"-bandqbus :: Pattern Int -> Pattern Double -> ControlPattern-bandqbus busid pat = (pF "bandq" pat) # (pI "^bandq" busid)-bandqrecv :: Pattern Int -> ControlPattern-bandqrecv busid = pI "^bandq" busid---- | 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.-begin :: Pattern Double -> ControlPattern-begin = pF "begin"-beginbus :: Pattern Int -> Pattern Double -> ControlPattern-beginbus busid pat = (pF "begin" pat) # (pI "^begin" busid)-beginrecv :: Pattern Int -> ControlPattern-beginrecv busid = pI "^begin" busid---- | Spectral binshift-binshift :: Pattern Double -> ControlPattern-binshift = pF "binshift"-binshiftbus :: Pattern Int -> Pattern Double -> ControlPattern-binshiftbus busid pat = (pF "binshift" pat) # (pI "^binshift" busid)-binshiftrecv :: Pattern Int -> ControlPattern-binshiftrecv busid = pI "^binshift" busid---- | -button0 :: Pattern Double -> ControlPattern-button0 = pF "button0"-button0bus :: Pattern Int -> Pattern Double -> ControlPattern-button0bus busid pat = (pF "button0" pat) # (pI "^button0" busid)-button0recv :: Pattern Int -> ControlPattern-button0recv busid = pI "^button0" busid---- | -button1 :: Pattern Double -> ControlPattern-button1 = pF "button1"-button1bus :: Pattern Int -> Pattern Double -> ControlPattern-button1bus busid pat = (pF "button1" pat) # (pI "^button1" busid)-button1recv :: Pattern Int -> ControlPattern-button1recv busid = pI "^button1" busid---- | -button10 :: Pattern Double -> ControlPattern-button10 = pF "button10"-button10bus :: Pattern Int -> Pattern Double -> ControlPattern-button10bus busid pat = (pF "button10" pat) # (pI "^button10" busid)-button10recv :: Pattern Int -> ControlPattern-button10recv busid = pI "^button10" busid---- | -button11 :: Pattern Double -> ControlPattern-button11 = pF "button11"-button11bus :: Pattern Int -> Pattern Double -> ControlPattern-button11bus busid pat = (pF "button11" pat) # (pI "^button11" busid)-button11recv :: Pattern Int -> ControlPattern-button11recv busid = pI "^button11" busid---- | -button12 :: Pattern Double -> ControlPattern-button12 = pF "button12"-button12bus :: Pattern Int -> Pattern Double -> ControlPattern-button12bus busid pat = (pF "button12" pat) # (pI "^button12" busid)-button12recv :: Pattern Int -> ControlPattern-button12recv busid = pI "^button12" busid---- | -button13 :: Pattern Double -> ControlPattern-button13 = pF "button13"-button13bus :: Pattern Int -> Pattern Double -> ControlPattern-button13bus busid pat = (pF "button13" pat) # (pI "^button13" busid)-button13recv :: Pattern Int -> ControlPattern-button13recv busid = pI "^button13" busid---- | -button14 :: Pattern Double -> ControlPattern-button14 = pF "button14"-button14bus :: Pattern Int -> Pattern Double -> ControlPattern-button14bus busid pat = (pF "button14" pat) # (pI "^button14" busid)-button14recv :: Pattern Int -> ControlPattern-button14recv busid = pI "^button14" busid---- | -button15 :: Pattern Double -> ControlPattern-button15 = pF "button15"-button15bus :: Pattern Int -> Pattern Double -> ControlPattern-button15bus busid pat = (pF "button15" pat) # (pI "^button15" busid)-button15recv :: Pattern Int -> ControlPattern-button15recv busid = pI "^button15" busid---- | -button2 :: Pattern Double -> ControlPattern-button2 = pF "button2"-button2bus :: Pattern Int -> Pattern Double -> ControlPattern-button2bus busid pat = (pF "button2" pat) # (pI "^button2" busid)-button2recv :: Pattern Int -> ControlPattern-button2recv busid = pI "^button2" busid---- | -button3 :: Pattern Double -> ControlPattern-button3 = pF "button3"-button3bus :: Pattern Int -> Pattern Double -> ControlPattern-button3bus busid pat = (pF "button3" pat) # (pI "^button3" busid)-button3recv :: Pattern Int -> ControlPattern-button3recv busid = pI "^button3" busid---- | -button4 :: Pattern Double -> ControlPattern-button4 = pF "button4"-button4bus :: Pattern Int -> Pattern Double -> ControlPattern-button4bus busid pat = (pF "button4" pat) # (pI "^button4" busid)-button4recv :: Pattern Int -> ControlPattern-button4recv busid = pI "^button4" busid---- | -button5 :: Pattern Double -> ControlPattern-button5 = pF "button5"-button5bus :: Pattern Int -> Pattern Double -> ControlPattern-button5bus busid pat = (pF "button5" pat) # (pI "^button5" busid)-button5recv :: Pattern Int -> ControlPattern-button5recv busid = pI "^button5" busid---- | -button6 :: Pattern Double -> ControlPattern-button6 = pF "button6"-button6bus :: Pattern Int -> Pattern Double -> ControlPattern-button6bus busid pat = (pF "button6" pat) # (pI "^button6" busid)-button6recv :: Pattern Int -> ControlPattern-button6recv busid = pI "^button6" busid---- | -button7 :: Pattern Double -> ControlPattern-button7 = pF "button7"-button7bus :: Pattern Int -> Pattern Double -> ControlPattern-button7bus busid pat = (pF "button7" pat) # (pI "^button7" busid)-button7recv :: Pattern Int -> ControlPattern-button7recv busid = pI "^button7" busid---- | -button8 :: Pattern Double -> ControlPattern-button8 = pF "button8"-button8bus :: Pattern Int -> Pattern Double -> ControlPattern-button8bus busid pat = (pF "button8" pat) # (pI "^button8" busid)-button8recv :: Pattern Int -> ControlPattern-button8recv busid = pI "^button8" busid---- | -button9 :: Pattern Double -> ControlPattern-button9 = pF "button9"-button9bus :: Pattern Int -> Pattern Double -> ControlPattern-button9bus busid pat = (pF "button9" pat) # (pI "^button9" busid)-button9recv :: Pattern Int -> ControlPattern-button9recv busid = pI "^button9" busid---- | -ccn :: Pattern Double -> ControlPattern-ccn = pF "ccn"-ccnbus :: Pattern Int -> Pattern Double -> ControlPattern-ccnbus busid pat = (pF "ccn" pat) # (pI "^ccn" busid)-ccnrecv :: Pattern Int -> ControlPattern-ccnrecv busid = pI "^ccn" busid---- | -ccv :: Pattern Double -> ControlPattern-ccv = pF "ccv"-ccvbus :: Pattern Int -> Pattern Double -> ControlPattern-ccvbus busid pat = (pF "ccv" pat) # (pI "^ccv" busid)-ccvrecv :: Pattern Int -> ControlPattern-ccvrecv busid = pI "^ccv" busid---- | choose the channel the pattern is sent to in superdirt-channel :: Pattern Int -> ControlPattern-channel = pI "channel"-channelbus :: Pattern Int -> Pattern Int -> ControlPattern-channelbus _ _ = error $ "Control parameter 'channel' can't be sent to a bus."---- | -clhatdecay :: Pattern Double -> ControlPattern-clhatdecay = pF "clhatdecay"-clhatdecaybus :: Pattern Int -> Pattern Double -> ControlPattern-clhatdecaybus busid pat = (pF "clhatdecay" pat) # (pI "^clhatdecay" busid)-clhatdecayrecv :: Pattern Int -> ControlPattern-clhatdecayrecv busid = pI "^clhatdecay" busid---- | 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 Double -> ControlPattern-coarse = pF "coarse"-coarsebus :: Pattern Int -> Pattern Double -> ControlPattern-coarsebus busid pat = (pF "coarse" pat) # (pI "^coarse" busid)-coarserecv :: Pattern Int -> ControlPattern-coarserecv busid = pI "^coarse" busid---- | Spectral comb-comb :: Pattern Double -> ControlPattern-comb = pF "comb"-combbus :: Pattern Int -> Pattern Double -> ControlPattern-combbus busid pat = (pF "comb" pat) # (pI "^comb" busid)-combrecv :: Pattern Int -> ControlPattern-combrecv busid = pI "^comb" busid---- | -control :: Pattern Double -> ControlPattern-control = pF "control"-controlbus :: Pattern Int -> Pattern Double -> ControlPattern-controlbus busid pat = (pF "control" pat) # (pI "^control" busid)-controlrecv :: Pattern Int -> ControlPattern-controlrecv busid = pI "^control" busid---- | -cps :: Pattern Double -> ControlPattern-cps = pF "cps"-cpsbus :: Pattern Int -> Pattern Double -> ControlPattern-cpsbus busid pat = (pF "cps" pat) # (pI "^cps" busid)-cpsrecv :: Pattern Int -> ControlPattern-cpsrecv busid = pI "^cps" busid---- | bit crushing, a pattern of numbers from 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction).-crush :: Pattern Double -> ControlPattern-crush = pF "crush"-crushbus :: Pattern Int -> Pattern Double -> ControlPattern-crushbus busid pat = (pF "crush" pat) # (pI "^crush" busid)-crushrecv :: Pattern Int -> ControlPattern-crushrecv busid = pI "^crush" busid---- | -ctlNum :: Pattern Double -> ControlPattern-ctlNum = pF "ctlNum"-ctlNumbus :: Pattern Int -> Pattern Double -> ControlPattern-ctlNumbus busid pat = (pF "ctlNum" pat) # (pI "^ctlNum" busid)-ctlNumrecv :: Pattern Int -> ControlPattern-ctlNumrecv busid = pI "^ctlNum" busid---- | -ctranspose :: Pattern Double -> ControlPattern-ctranspose = pF "ctranspose"-ctransposebus :: Pattern Int -> Pattern Double -> ControlPattern-ctransposebus busid pat = (pF "ctranspose" pat) # (pI "^ctranspose" busid)-ctransposerecv :: Pattern Int -> ControlPattern-ctransposerecv busid = pI "^ctranspose" busid---- | 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.-cut :: Pattern Int -> ControlPattern-cut = pI "cut"-cutbus :: Pattern Int -> Pattern Int -> ControlPattern-cutbus busid pat = (pI "cut" pat) # (pI "^cut" busid)-cutrecv :: Pattern Int -> ControlPattern-cutrecv busid = pI "^cut" busid---- | a pattern of numbers from 0 to 1. Applies the cutoff frequency of the low-pass filter.-cutoff :: Pattern Double -> ControlPattern-cutoff = pF "cutoff"-cutoffbus :: Pattern Int -> Pattern Double -> ControlPattern-cutoffbus busid pat = (pF "cutoff" pat) # (pI "^cutoff" busid)-cutoffrecv :: Pattern Int -> ControlPattern-cutoffrecv busid = pI "^cutoff" busid---- | -cutoffegint :: Pattern Double -> ControlPattern-cutoffegint = pF "cutoffegint"-cutoffegintbus :: Pattern Int -> Pattern Double -> ControlPattern-cutoffegintbus busid pat = (pF "cutoffegint" pat) # (pI "^cutoffegint" busid)-cutoffegintrecv :: Pattern Int -> ControlPattern-cutoffegintrecv busid = pI "^cutoffegint" busid---- | -decay :: Pattern Double -> ControlPattern-decay = pF "decay"-decaybus :: Pattern Int -> Pattern Double -> ControlPattern-decaybus busid pat = (pF "decay" pat) # (pI "^decay" busid)-decayrecv :: Pattern Int -> ControlPattern-decayrecv busid = pI "^decay" busid---- | -degree :: Pattern Double -> ControlPattern-degree = pF "degree"-degreebus :: Pattern Int -> Pattern Double -> ControlPattern-degreebus busid pat = (pF "degree" pat) # (pI "^degree" busid)-degreerecv :: Pattern Int -> ControlPattern-degreerecv busid = pI "^degree" busid---- | a pattern of numbers from 0 to 1. Sets the level of the delay signal.-delay :: Pattern Double -> ControlPattern-delay = pF "delay"-delaybus :: Pattern Int -> Pattern Double -> ControlPattern-delaybus busid pat = (pF "delay" pat) # (pI "^delay" busid)-delayrecv :: Pattern Int -> ControlPattern-delayrecv busid = pI "^delay" busid---- | a pattern of numbers from 0 to 1. Sets the amount of delay feedback.-delayfeedback :: Pattern Double -> ControlPattern-delayfeedback = pF "delayfeedback"-delayfeedbackbus :: Pattern Int -> Pattern Double -> ControlPattern-delayfeedbackbus busid pat = (pF "delayfeedback" pat) # (pI "^delayfeedback" busid)-delayfeedbackrecv :: Pattern Int -> ControlPattern-delayfeedbackrecv busid = pI "^delayfeedback" busid---- | a pattern of numbers from 0 to 1. Sets the length of the delay.-delaytime :: Pattern Double -> ControlPattern-delaytime = pF "delaytime"-delaytimebus :: Pattern Int -> Pattern Double -> ControlPattern-delaytimebus busid pat = (pF "delaytime" pat) # (pI "^delaytime" busid)-delaytimerecv :: Pattern Int -> ControlPattern-delaytimerecv busid = pI "^delaytime" busid---- | -detune :: Pattern Double -> ControlPattern-detune = pF "detune"-detunebus :: Pattern Int -> Pattern Double -> ControlPattern-detunebus busid pat = (pF "detune" pat) # (pI "^detune" busid)-detunerecv :: Pattern Int -> ControlPattern-detunerecv busid = pI "^detune" busid---- | noisy fuzzy distortion-distort :: Pattern Double -> ControlPattern-distort = pF "distort"-distortbus :: Pattern Int -> Pattern Double -> ControlPattern-distortbus busid pat = (pF "distort" pat) # (pI "^distort" busid)-distortrecv :: Pattern Int -> ControlPattern-distortrecv busid = pI "^distort" busid---- | DJ filter, below 0.5 is low pass filter, above is high pass filter.-djf :: Pattern Double -> ControlPattern-djf = pF "djf"-djfbus :: Pattern Int -> Pattern Double -> ControlPattern-djfbus busid pat = (pF "djf" pat) # (pI "^djf" busid)-djfrecv :: Pattern Int -> ControlPattern-djfrecv busid = pI "^djf" busid---- | when set to `1` will disable all reverb for this pattern. See `room` and `size` for more information about reverb.-dry :: Pattern Double -> ControlPattern-dry = pF "dry"-drybus :: Pattern Int -> Pattern Double -> ControlPattern-drybus busid pat = (pF "dry" pat) # (pI "^dry" busid)-dryrecv :: Pattern Int -> ControlPattern-dryrecv busid = pI "^dry" busid---- | -dur :: Pattern Double -> ControlPattern-dur = pF "dur"-durbus :: Pattern Int -> Pattern Double -> ControlPattern-durbus busid pat = (pF "dur" pat) # (pI "^dur" busid)-durrecv :: Pattern Int -> ControlPattern-durrecv busid = pI "^dur" busid---- | the same as `begin`, but cuts the end off samples, shortening them; e.g. `0.75` to cut off the last quarter of each sample.-end :: Pattern Double -> ControlPattern-end = pF "end"-endbus :: Pattern Int -> Pattern Double -> ControlPattern-endbus _ _ = error $ "Control parameter 'end' can't be sent to a bus."---- | Spectral enhance-enhance :: Pattern Double -> ControlPattern-enhance = pF "enhance"-enhancebus :: Pattern Int -> Pattern Double -> ControlPattern-enhancebus busid pat = (pF "enhance" pat) # (pI "^enhance" busid)-enhancerecv :: Pattern Int -> ControlPattern-enhancerecv busid = pI "^enhance" busid---- | -expression :: Pattern Double -> ControlPattern-expression = pF "expression"-expressionbus :: Pattern Int -> Pattern Double -> ControlPattern-expressionbus busid pat = (pF "expression" pat) # (pI "^expression" busid)-expressionrecv :: Pattern Int -> ControlPattern-expressionrecv busid = pI "^expression" busid---- | -frameRate :: Pattern Double -> ControlPattern-frameRate = pF "frameRate"-frameRatebus :: Pattern Int -> Pattern Double -> ControlPattern-frameRatebus busid pat = (pF "frameRate" pat) # (pI "^frameRate" busid)-frameRaterecv :: Pattern Int -> ControlPattern-frameRaterecv busid = pI "^frameRate" busid---- | -frames :: Pattern Double -> ControlPattern-frames = pF "frames"-framesbus :: Pattern Int -> Pattern Double -> ControlPattern-framesbus busid pat = (pF "frames" pat) # (pI "^frames" busid)-framesrecv :: Pattern Int -> ControlPattern-framesrecv busid = pI "^frames" busid---- | Spectral freeze-freeze :: Pattern Double -> ControlPattern-freeze = pF "freeze"-freezebus :: Pattern Int -> Pattern Double -> ControlPattern-freezebus busid pat = (pF "freeze" pat) # (pI "^freeze" busid)-freezerecv :: Pattern Int -> ControlPattern-freezerecv busid = pI "^freeze" busid---- | -freq :: Pattern Double -> ControlPattern-freq = pF "freq"-freqbus :: Pattern Int -> Pattern Double -> ControlPattern-freqbus busid pat = (pF "freq" pat) # (pI "^freq" busid)-freqrecv :: Pattern Int -> ControlPattern-freqrecv busid = pI "^freq" busid---- | for internal sound routing-from :: Pattern Double -> ControlPattern-from = pF "from"-frombus :: Pattern Int -> Pattern Double -> ControlPattern-frombus busid pat = (pF "from" pat) # (pI "^from" busid)-fromrecv :: Pattern Int -> ControlPattern-fromrecv busid = pI "^from" busid---- | frequency shifter-fshift :: Pattern Double -> ControlPattern-fshift = pF "fshift"-fshiftbus :: Pattern Int -> Pattern Double -> ControlPattern-fshiftbus busid pat = (pF "fshift" pat) # (pI "^fshift" busid)-fshiftrecv :: Pattern Int -> ControlPattern-fshiftrecv busid = pI "^fshift" busid---- | frequency shifter-fshiftnote :: Pattern Double -> ControlPattern-fshiftnote = pF "fshiftnote"-fshiftnotebus :: Pattern Int -> Pattern Double -> ControlPattern-fshiftnotebus busid pat = (pF "fshiftnote" pat) # (pI "^fshiftnote" busid)-fshiftnoterecv :: Pattern Int -> ControlPattern-fshiftnoterecv busid = pI "^fshiftnote" busid---- | frequency shifter-fshiftphase :: Pattern Double -> ControlPattern-fshiftphase = pF "fshiftphase"-fshiftphasebus :: Pattern Int -> Pattern Double -> ControlPattern-fshiftphasebus busid pat = (pF "fshiftphase" pat) # (pI "^fshiftphase" busid)-fshiftphaserecv :: Pattern Int -> ControlPattern-fshiftphaserecv busid = pI "^fshiftphase" busid---- | a pattern of numbers that specify volume. Values less than 1 make the sound quieter. Values greater than 1 make the sound louder. For the linear equivalent, see @amp@.-gain :: Pattern Double -> ControlPattern-gain = pF "gain"-gainbus :: Pattern Int -> Pattern Double -> ControlPattern-gainbus _ _ = error $ "Control parameter 'gain' can't be sent to a bus."---- | -gate :: Pattern Double -> ControlPattern-gate = pF "gate"-gatebus :: Pattern Int -> Pattern Double -> ControlPattern-gatebus busid pat = (pF "gate" pat) # (pI "^gate" busid)-gaterecv :: Pattern Int -> ControlPattern-gaterecv busid = pI "^gate" busid---- | -harmonic :: Pattern Double -> ControlPattern-harmonic = pF "harmonic"-harmonicbus :: Pattern Int -> Pattern Double -> ControlPattern-harmonicbus busid pat = (pF "harmonic" pat) # (pI "^harmonic" busid)-harmonicrecv :: Pattern Int -> ControlPattern-harmonicrecv busid = pI "^harmonic" busid---- | -hatgrain :: Pattern Double -> ControlPattern-hatgrain = pF "hatgrain"-hatgrainbus :: Pattern Int -> Pattern Double -> ControlPattern-hatgrainbus busid pat = (pF "hatgrain" pat) # (pI "^hatgrain" busid)-hatgrainrecv :: Pattern Int -> ControlPattern-hatgrainrecv busid = pI "^hatgrain" busid---- | High pass sort of spectral filter-hbrick :: Pattern Double -> ControlPattern-hbrick = pF "hbrick"-hbrickbus :: Pattern Int -> Pattern Double -> ControlPattern-hbrickbus busid pat = (pF "hbrick" pat) # (pI "^hbrick" busid)-hbrickrecv :: Pattern Int -> ControlPattern-hbrickrecv busid = pI "^hbrick" busid---- | a pattern of numbers from 0 to 1. Applies the cutoff frequency of the high-pass filter. Also has alias @hpf@-hcutoff :: Pattern Double -> ControlPattern-hcutoff = pF "hcutoff"-hcutoffbus :: Pattern Int -> Pattern Double -> ControlPattern-hcutoffbus busid pat = (pF "hcutoff" pat) # (pI "^hcutoff" busid)-hcutoffrecv :: Pattern Int -> ControlPattern-hcutoffrecv busid = pI "^hcutoff" busid---- | 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 -> ControlPattern-hold = pF "hold"-holdbus :: Pattern Int -> Pattern Double -> ControlPattern-holdbus busid pat = (pF "hold" pat) # (pI "^hold" busid)-holdrecv :: Pattern Int -> ControlPattern-holdrecv busid = pI "^hold" busid---- | -hours :: Pattern Double -> ControlPattern-hours = pF "hours"-hoursbus :: Pattern Int -> Pattern Double -> ControlPattern-hoursbus busid pat = (pF "hours" pat) # (pI "^hours" busid)-hoursrecv :: Pattern Int -> ControlPattern-hoursrecv busid = pI "^hours" busid---- | a pattern of numbers from 0 to 1. Applies the resonance of the high-pass filter. Has alias @hpq@-hresonance :: Pattern Double -> ControlPattern-hresonance = pF "hresonance"-hresonancebus :: Pattern Int -> Pattern Double -> ControlPattern-hresonancebus busid pat = (pF "hresonance" pat) # (pI "^hresonance" busid)-hresonancerecv :: Pattern Int -> ControlPattern-hresonancerecv busid = pI "^hresonance" busid---- | -imag :: Pattern Double -> ControlPattern-imag = pF "imag"-imagbus :: Pattern Int -> Pattern Double -> ControlPattern-imagbus busid pat = (pF "imag" pat) # (pI "^imag" busid)-imagrecv :: Pattern Int -> ControlPattern-imagrecv busid = pI "^imag" busid---- | -kcutoff :: Pattern Double -> ControlPattern-kcutoff = pF "kcutoff"-kcutoffbus :: Pattern Int -> Pattern Double -> ControlPattern-kcutoffbus busid pat = (pF "kcutoff" pat) # (pI "^kcutoff" busid)-kcutoffrecv :: Pattern Int -> ControlPattern-kcutoffrecv busid = pI "^kcutoff" busid---- | shape/bass enhancer-krush :: Pattern Double -> ControlPattern-krush = pF "krush"-krushbus :: Pattern Int -> Pattern Double -> ControlPattern-krushbus busid pat = (pF "krush" pat) # (pI "^krush" busid)-krushrecv :: Pattern Int -> ControlPattern-krushrecv busid = pI "^krush" busid---- | -lagogo :: Pattern Double -> ControlPattern-lagogo = pF "lagogo"-lagogobus :: Pattern Int -> Pattern Double -> ControlPattern-lagogobus busid pat = (pF "lagogo" pat) # (pI "^lagogo" busid)-lagogorecv :: Pattern Int -> ControlPattern-lagogorecv busid = pI "^lagogo" busid---- | Low pass sort of spectral filter-lbrick :: Pattern Double -> ControlPattern-lbrick = pF "lbrick"-lbrickbus :: Pattern Int -> Pattern Double -> ControlPattern-lbrickbus busid pat = (pF "lbrick" pat) # (pI "^lbrick" busid)-lbrickrecv :: Pattern Int -> ControlPattern-lbrickrecv busid = pI "^lbrick" busid---- | -lclap :: Pattern Double -> ControlPattern-lclap = pF "lclap"-lclapbus :: Pattern Int -> Pattern Double -> ControlPattern-lclapbus busid pat = (pF "lclap" pat) # (pI "^lclap" busid)-lclaprecv :: Pattern Int -> ControlPattern-lclaprecv busid = pI "^lclap" busid---- | -lclaves :: Pattern Double -> ControlPattern-lclaves = pF "lclaves"-lclavesbus :: Pattern Int -> Pattern Double -> ControlPattern-lclavesbus busid pat = (pF "lclaves" pat) # (pI "^lclaves" busid)-lclavesrecv :: Pattern Int -> ControlPattern-lclavesrecv busid = pI "^lclaves" busid---- | -lclhat :: Pattern Double -> ControlPattern-lclhat = pF "lclhat"-lclhatbus :: Pattern Int -> Pattern Double -> ControlPattern-lclhatbus busid pat = (pF "lclhat" pat) # (pI "^lclhat" busid)-lclhatrecv :: Pattern Int -> ControlPattern-lclhatrecv busid = pI "^lclhat" busid---- | -lcrash :: Pattern Double -> ControlPattern-lcrash = pF "lcrash"-lcrashbus :: Pattern Int -> Pattern Double -> ControlPattern-lcrashbus busid pat = (pF "lcrash" pat) # (pI "^lcrash" busid)-lcrashrecv :: Pattern Int -> ControlPattern-lcrashrecv busid = pI "^lcrash" busid---- | controls the amount of overlap between two adjacent sounds-legato :: Pattern Double -> ControlPattern-legato = pF "legato"-legatobus :: Pattern Int -> Pattern Double -> ControlPattern-legatobus _ _ = error $ "Control parameter 'legato' can't be sent to a bus."---- | -leslie :: Pattern Double -> ControlPattern-leslie = pF "leslie"-lesliebus :: Pattern Int -> Pattern Double -> ControlPattern-lesliebus busid pat = (pF "leslie" pat) # (pI "^leslie" busid)-leslierecv :: Pattern Int -> ControlPattern-leslierecv busid = pI "^leslie" busid---- | -lfo :: Pattern Double -> ControlPattern-lfo = pF "lfo"-lfobus :: Pattern Int -> Pattern Double -> ControlPattern-lfobus busid pat = (pF "lfo" pat) # (pI "^lfo" busid)-lforecv :: Pattern Int -> ControlPattern-lforecv busid = pI "^lfo" busid---- | -lfocutoffint :: Pattern Double -> ControlPattern-lfocutoffint = pF "lfocutoffint"-lfocutoffintbus :: Pattern Int -> Pattern Double -> ControlPattern-lfocutoffintbus busid pat = (pF "lfocutoffint" pat) # (pI "^lfocutoffint" busid)-lfocutoffintrecv :: Pattern Int -> ControlPattern-lfocutoffintrecv busid = pI "^lfocutoffint" busid---- | -lfodelay :: Pattern Double -> ControlPattern-lfodelay = pF "lfodelay"-lfodelaybus :: Pattern Int -> Pattern Double -> ControlPattern-lfodelaybus busid pat = (pF "lfodelay" pat) # (pI "^lfodelay" busid)-lfodelayrecv :: Pattern Int -> ControlPattern-lfodelayrecv busid = pI "^lfodelay" busid---- | -lfoint :: Pattern Double -> ControlPattern-lfoint = pF "lfoint"-lfointbus :: Pattern Int -> Pattern Double -> ControlPattern-lfointbus busid pat = (pF "lfoint" pat) # (pI "^lfoint" busid)-lfointrecv :: Pattern Int -> ControlPattern-lfointrecv busid = pI "^lfoint" busid---- | -lfopitchint :: Pattern Double -> ControlPattern-lfopitchint = pF "lfopitchint"-lfopitchintbus :: Pattern Int -> Pattern Double -> ControlPattern-lfopitchintbus busid pat = (pF "lfopitchint" pat) # (pI "^lfopitchint" busid)-lfopitchintrecv :: Pattern Int -> ControlPattern-lfopitchintrecv busid = pI "^lfopitchint" busid---- | -lfoshape :: Pattern Double -> ControlPattern-lfoshape = pF "lfoshape"-lfoshapebus :: Pattern Int -> Pattern Double -> ControlPattern-lfoshapebus busid pat = (pF "lfoshape" pat) # (pI "^lfoshape" busid)-lfoshaperecv :: Pattern Int -> ControlPattern-lfoshaperecv busid = pI "^lfoshape" busid---- | -lfosync :: Pattern Double -> ControlPattern-lfosync = pF "lfosync"-lfosyncbus :: Pattern Int -> Pattern Double -> ControlPattern-lfosyncbus busid pat = (pF "lfosync" pat) # (pI "^lfosync" busid)-lfosyncrecv :: Pattern Int -> ControlPattern-lfosyncrecv busid = pI "^lfosync" busid---- | -lhitom :: Pattern Double -> ControlPattern-lhitom = pF "lhitom"-lhitombus :: Pattern Int -> Pattern Double -> ControlPattern-lhitombus busid pat = (pF "lhitom" pat) # (pI "^lhitom" busid)-lhitomrecv :: Pattern Int -> ControlPattern-lhitomrecv busid = pI "^lhitom" busid---- | -lkick :: Pattern Double -> ControlPattern-lkick = pF "lkick"-lkickbus :: Pattern Int -> Pattern Double -> ControlPattern-lkickbus busid pat = (pF "lkick" pat) # (pI "^lkick" busid)-lkickrecv :: Pattern Int -> ControlPattern-lkickrecv busid = pI "^lkick" busid---- | -llotom :: Pattern Double -> ControlPattern-llotom = pF "llotom"-llotombus :: Pattern Int -> Pattern Double -> ControlPattern-llotombus busid pat = (pF "llotom" pat) # (pI "^llotom" busid)-llotomrecv :: Pattern Int -> ControlPattern-llotomrecv busid = pI "^llotom" busid---- | 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 -> ControlPattern-lock = pF "lock"-lockbus :: Pattern Int -> Pattern Double -> ControlPattern-lockbus busid pat = (pF "lock" pat) # (pI "^lock" busid)-lockrecv :: Pattern Int -> ControlPattern-lockrecv busid = pI "^lock" busid---- | loops the sample (from `begin` to `end`) the specified number of times.-loop :: Pattern Double -> ControlPattern-loop = pF "loop"-loopbus :: Pattern Int -> Pattern Double -> ControlPattern-loopbus _ _ = error $ "Control parameter 'loop' can't be sent to a bus."---- | -lophat :: Pattern Double -> ControlPattern-lophat = pF "lophat"-lophatbus :: Pattern Int -> Pattern Double -> ControlPattern-lophatbus busid pat = (pF "lophat" pat) # (pI "^lophat" busid)-lophatrecv :: Pattern Int -> ControlPattern-lophatrecv busid = pI "^lophat" busid---- | -lrate :: Pattern Double -> ControlPattern-lrate = pF "lrate"-lratebus :: Pattern Int -> Pattern Double -> ControlPattern-lratebus busid pat = (pF "lrate" pat) # (pI "^lrate" busid)-lraterecv :: Pattern Int -> ControlPattern-lraterecv busid = pI "^lrate" busid---- | -lsize :: Pattern Double -> ControlPattern-lsize = pF "lsize"-lsizebus :: Pattern Int -> Pattern Double -> ControlPattern-lsizebus busid pat = (pF "lsize" pat) # (pI "^lsize" busid)-lsizerecv :: Pattern Int -> ControlPattern-lsizerecv busid = pI "^lsize" busid---- | -lsnare :: Pattern Double -> ControlPattern-lsnare = pF "lsnare"-lsnarebus :: Pattern Int -> Pattern Double -> ControlPattern-lsnarebus busid pat = (pF "lsnare" pat) # (pI "^lsnare" busid)-lsnarerecv :: Pattern Int -> ControlPattern-lsnarerecv busid = pI "^lsnare" busid---- | -midibend :: Pattern Double -> ControlPattern-midibend = pF "midibend"-midibendbus :: Pattern Int -> Pattern Double -> ControlPattern-midibendbus busid pat = (pF "midibend" pat) # (pI "^midibend" busid)-midibendrecv :: Pattern Int -> ControlPattern-midibendrecv busid = pI "^midibend" busid---- | -midichan :: Pattern Double -> ControlPattern-midichan = pF "midichan"-midichanbus :: Pattern Int -> Pattern Double -> ControlPattern-midichanbus busid pat = (pF "midichan" pat) # (pI "^midichan" busid)-midichanrecv :: Pattern Int -> ControlPattern-midichanrecv busid = pI "^midichan" busid---- | -midicmd :: Pattern String -> ControlPattern-midicmd = pS "midicmd"-midicmdbus :: Pattern Int -> Pattern String -> ControlPattern-midicmdbus busid pat = (pS "midicmd" pat) # (pI "^midicmd" busid)-midicmdrecv :: Pattern Int -> ControlPattern-midicmdrecv busid = pI "^midicmd" busid---- | -miditouch :: Pattern Double -> ControlPattern-miditouch = pF "miditouch"-miditouchbus :: Pattern Int -> Pattern Double -> ControlPattern-miditouchbus busid pat = (pF "miditouch" pat) # (pI "^miditouch" busid)-miditouchrecv :: Pattern Int -> ControlPattern-miditouchrecv busid = pI "^miditouch" busid---- | -minutes :: Pattern Double -> ControlPattern-minutes = pF "minutes"-minutesbus :: Pattern Int -> Pattern Double -> ControlPattern-minutesbus busid pat = (pF "minutes" pat) # (pI "^minutes" busid)-minutesrecv :: Pattern Int -> ControlPattern-minutesrecv busid = pI "^minutes" busid---- | -modwheel :: Pattern Double -> ControlPattern-modwheel = pF "modwheel"-modwheelbus :: Pattern Int -> Pattern Double -> ControlPattern-modwheelbus busid pat = (pF "modwheel" pat) # (pI "^modwheel" busid)-modwheelrecv :: Pattern Int -> ControlPattern-modwheelrecv busid = pI "^modwheel" busid---- | -mtranspose :: Pattern Double -> ControlPattern-mtranspose = pF "mtranspose"-mtransposebus :: Pattern Int -> Pattern Double -> ControlPattern-mtransposebus busid pat = (pF "mtranspose" pat) # (pI "^mtranspose" busid)-mtransposerecv :: Pattern Int -> ControlPattern-mtransposerecv busid = pI "^mtranspose" busid---- | The note or sample number to choose for a synth or sampleset-n :: Pattern Note -> ControlPattern-n = pN "n"-nbus :: Pattern Int -> Pattern Note -> ControlPattern-nbus _ _ = error $ "Control parameter 'n' can't be sent to a bus."---- | The note or pitch to play a sound or synth with-note :: Pattern Note -> ControlPattern-note = pN "note"-notebus :: Pattern Int -> Pattern Note -> ControlPattern-notebus _ _ = error $ "Control parameter 'note' can't be sent to a bus."---- | -nrpnn :: Pattern Int -> ControlPattern-nrpnn = pI "nrpnn"-nrpnnbus :: Pattern Int -> Pattern Int -> ControlPattern-nrpnnbus busid pat = (pI "nrpnn" pat) # (pI "^nrpnn" busid)-nrpnnrecv :: Pattern Int -> ControlPattern-nrpnnrecv busid = pI "^nrpnn" busid---- | -nrpnv :: Pattern Int -> ControlPattern-nrpnv = pI "nrpnv"-nrpnvbus :: Pattern Int -> Pattern Int -> ControlPattern-nrpnvbus busid pat = (pI "nrpnv" pat) # (pI "^nrpnv" busid)-nrpnvrecv :: Pattern Int -> ControlPattern-nrpnvrecv busid = pI "^nrpnv" busid---- | Nudges events into the future by the specified number of seconds. Negative numbers work up to a point as well (due to internal latency)-nudge :: Pattern Double -> ControlPattern-nudge = pF "nudge"-nudgebus :: Pattern Int -> Pattern Double -> ControlPattern-nudgebus busid pat = (pF "nudge" pat) # (pI "^nudge" busid)-nudgerecv :: Pattern Int -> ControlPattern-nudgerecv busid = pI "^nudge" busid---- | -octave :: Pattern Int -> ControlPattern-octave = pI "octave"-octavebus :: Pattern Int -> Pattern Int -> ControlPattern-octavebus _ _ = error $ "Control parameter 'octave' can't be sent to a bus."---- | -octaveR :: Pattern Double -> ControlPattern-octaveR = pF "octaveR"-octaveRbus :: Pattern Int -> Pattern Double -> ControlPattern-octaveRbus busid pat = (pF "octaveR" pat) # (pI "^octaveR" busid)-octaveRrecv :: Pattern Int -> ControlPattern-octaveRrecv busid = pI "^octaveR" busid---- | octaver effect-octer :: Pattern Double -> ControlPattern-octer = pF "octer"-octerbus :: Pattern Int -> Pattern Double -> ControlPattern-octerbus busid pat = (pF "octer" pat) # (pI "^octer" busid)-octerrecv :: Pattern Int -> ControlPattern-octerrecv busid = pI "^octer" busid---- | octaver effect-octersub :: Pattern Double -> ControlPattern-octersub = pF "octersub"-octersubbus :: Pattern Int -> Pattern Double -> ControlPattern-octersubbus busid pat = (pF "octersub" pat) # (pI "^octersub" busid)-octersubrecv :: Pattern Int -> ControlPattern-octersubrecv busid = pI "^octersub" busid---- | octaver effect-octersubsub :: Pattern Double -> ControlPattern-octersubsub = pF "octersubsub"-octersubsubbus :: Pattern Int -> Pattern Double -> ControlPattern-octersubsubbus busid pat = (pF "octersubsub" pat) # (pI "^octersubsub" busid)-octersubsubrecv :: Pattern Int -> ControlPattern-octersubsubrecv busid = pI "^octersubsub" busid---- | -offset :: Pattern Double -> ControlPattern-offset = pF "offset"-offsetbus :: Pattern Int -> Pattern Double -> ControlPattern-offsetbus _ _ = error $ "Control parameter 'offset' can't be sent to a bus."---- | -ophatdecay :: Pattern Double -> ControlPattern-ophatdecay = pF "ophatdecay"-ophatdecaybus :: Pattern Int -> Pattern Double -> ControlPattern-ophatdecaybus busid pat = (pF "ophatdecay" pat) # (pI "^ophatdecay" busid)-ophatdecayrecv :: Pattern Int -> ControlPattern-ophatdecayrecv busid = pI "^ophatdecay" busid---- | a pattern of numbers. An `orbit` is a global parameter context for patterns. Patterns with the same orbit will share hardware output bus offset and global effects, e.g. reverb and delay. The maximum number of orbits is specified in the superdirt startup, numbers higher than maximum will wrap around.-orbit :: Pattern Int -> ControlPattern-orbit = pI "orbit"-orbitbus :: Pattern Int -> Pattern Int -> ControlPattern-orbitbus busid pat = (pI "orbit" pat) # (pI "^orbit" busid)-orbitrecv :: Pattern Int -> ControlPattern-orbitrecv busid = pI "^orbit" busid---- | -overgain :: Pattern Double -> ControlPattern-overgain = pF "overgain"-overgainbus :: Pattern Int -> Pattern Double -> ControlPattern-overgainbus _ _ = error $ "Control parameter 'overgain' can't be sent to a bus."---- | -overshape :: Pattern Double -> ControlPattern-overshape = pF "overshape"-overshapebus :: Pattern Int -> Pattern Double -> ControlPattern-overshapebus busid pat = (pF "overshape" pat) # (pI "^overshape" busid)-overshaperecv :: Pattern Int -> ControlPattern-overshaperecv busid = pI "^overshape" busid---- | a pattern of numbers between 0 and 1, from left to right (assuming stereo), once round a circle (assuming multichannel)-pan :: Pattern Double -> ControlPattern-pan = pF "pan"-panbus :: Pattern Int -> Pattern Double -> ControlPattern-panbus busid pat = (pF "pan" pat) # (pI "^pan" busid)-panrecv :: Pattern Int -> ControlPattern-panrecv busid = pI "^pan" busid---- | a pattern of numbers between -1.0 and 1.0, which controls the relative position of the centre pan in a pair of adjacent speakers (multichannel only)-panorient :: Pattern Double -> ControlPattern-panorient = pF "panorient"-panorientbus :: Pattern Int -> Pattern Double -> ControlPattern-panorientbus busid pat = (pF "panorient" pat) # (pI "^panorient" busid)-panorientrecv :: Pattern Int -> ControlPattern-panorientrecv busid = pI "^panorient" busid---- | a pattern of numbers between -inf and inf, which controls how much multichannel output is fanned out (negative is backwards ordering)-panspan :: Pattern Double -> ControlPattern-panspan = pF "panspan"-panspanbus :: Pattern Int -> Pattern Double -> ControlPattern-panspanbus busid pat = (pF "panspan" pat) # (pI "^panspan" busid)-panspanrecv :: Pattern Int -> ControlPattern-panspanrecv busid = pI "^panspan" busid---- | a pattern of numbers between 0.0 and 1.0, which controls the multichannel spread range (multichannel only)-pansplay :: Pattern Double -> ControlPattern-pansplay = pF "pansplay"-pansplaybus :: Pattern Int -> Pattern Double -> ControlPattern-pansplaybus busid pat = (pF "pansplay" pat) # (pI "^pansplay" busid)-pansplayrecv :: Pattern Int -> ControlPattern-pansplayrecv busid = pI "^pansplay" busid---- | a pattern of numbers between 0.0 and inf, which controls how much each channel is distributed over neighbours (multichannel only)-panwidth :: Pattern Double -> ControlPattern-panwidth = pF "panwidth"-panwidthbus :: Pattern Int -> Pattern Double -> ControlPattern-panwidthbus busid pat = (pF "panwidth" pat) # (pI "^panwidth" busid)-panwidthrecv :: Pattern Int -> ControlPattern-panwidthrecv busid = pI "^panwidth" busid---- | -partials :: Pattern Double -> ControlPattern-partials = pF "partials"-partialsbus :: Pattern Int -> Pattern Double -> ControlPattern-partialsbus busid pat = (pF "partials" pat) # (pI "^partials" busid)-partialsrecv :: Pattern Int -> ControlPattern-partialsrecv busid = pI "^partials" busid---- | Phaser Audio DSP effect | params are 'phaserrate' and 'phaserdepth'-phaserdepth :: Pattern Double -> ControlPattern-phaserdepth = pF "phaserdepth"-phaserdepthbus :: Pattern Int -> Pattern Double -> ControlPattern-phaserdepthbus busid pat = (pF "phaserdepth" pat) # (pI "^phaserdepth" busid)-phaserdepthrecv :: Pattern Int -> ControlPattern-phaserdepthrecv busid = pI "^phaserdepth" busid---- | Phaser Audio DSP effect | params are 'phaserrate' and 'phaserdepth'-phaserrate :: Pattern Double -> ControlPattern-phaserrate = pF "phaserrate"-phaserratebus :: Pattern Int -> Pattern Double -> ControlPattern-phaserratebus busid pat = (pF "phaserrate" pat) # (pI "^phaserrate" busid)-phaserraterecv :: Pattern Int -> ControlPattern-phaserraterecv busid = pI "^phaserrate" busid---- | -pitch1 :: Pattern Double -> ControlPattern-pitch1 = pF "pitch1"-pitch1bus :: Pattern Int -> Pattern Double -> ControlPattern-pitch1bus busid pat = (pF "pitch1" pat) # (pI "^pitch1" busid)-pitch1recv :: Pattern Int -> ControlPattern-pitch1recv busid = pI "^pitch1" busid---- | -pitch2 :: Pattern Double -> ControlPattern-pitch2 = pF "pitch2"-pitch2bus :: Pattern Int -> Pattern Double -> ControlPattern-pitch2bus busid pat = (pF "pitch2" pat) # (pI "^pitch2" busid)-pitch2recv :: Pattern Int -> ControlPattern-pitch2recv busid = pI "^pitch2" busid---- | -pitch3 :: Pattern Double -> ControlPattern-pitch3 = pF "pitch3"-pitch3bus :: Pattern Int -> Pattern Double -> ControlPattern-pitch3bus busid pat = (pF "pitch3" pat) # (pI "^pitch3" busid)-pitch3recv :: Pattern Int -> ControlPattern-pitch3recv busid = pI "^pitch3" busid---- | -polyTouch :: Pattern Double -> ControlPattern-polyTouch = pF "polyTouch"-polyTouchbus :: Pattern Int -> Pattern Double -> ControlPattern-polyTouchbus busid pat = (pF "polyTouch" pat) # (pI "^polyTouch" busid)-polyTouchrecv :: Pattern Int -> ControlPattern-polyTouchrecv busid = pI "^polyTouch" busid---- | -portamento :: Pattern Double -> ControlPattern-portamento = pF "portamento"-portamentobus :: Pattern Int -> Pattern Double -> ControlPattern-portamentobus busid pat = (pF "portamento" pat) # (pI "^portamento" busid)-portamentorecv :: Pattern Int -> ControlPattern-portamentorecv busid = pI "^portamento" busid---- | -progNum :: Pattern Double -> ControlPattern-progNum = pF "progNum"-progNumbus :: Pattern Int -> Pattern Double -> ControlPattern-progNumbus busid pat = (pF "progNum" pat) # (pI "^progNum" busid)-progNumrecv :: Pattern Int -> ControlPattern-progNumrecv busid = pI "^progNum" busid---- | used in SuperDirt softsynths as a control rate or 'speed'-rate :: Pattern Double -> ControlPattern-rate = pF "rate"-ratebus :: Pattern Int -> Pattern Double -> ControlPattern-ratebus busid pat = (pF "rate" pat) # (pI "^rate" busid)-raterecv :: Pattern Int -> ControlPattern-raterecv busid = pI "^rate" busid---- | Spectral conform-real :: Pattern Double -> ControlPattern-real = pF "real"-realbus :: Pattern Int -> Pattern Double -> ControlPattern-realbus busid pat = (pF "real" pat) # (pI "^real" busid)-realrecv :: Pattern Int -> ControlPattern-realrecv busid = pI "^real" busid---- | a pattern of numbers to specify the release time (in seconds) of an envelope applied to each sample.-release :: Pattern Double -> ControlPattern-release = pF "release"-releasebus :: Pattern Int -> Pattern Double -> ControlPattern-releasebus busid pat = (pF "release" pat) # (pI "^release" busid)-releaserecv :: Pattern Int -> ControlPattern-releaserecv busid = pI "^release" busid---- | a pattern of numbers from 0 to 1. Specifies the resonance of the low-pass filter.-resonance :: Pattern Double -> ControlPattern-resonance = pF "resonance"-resonancebus :: Pattern Int -> Pattern Double -> ControlPattern-resonancebus busid pat = (pF "resonance" pat) # (pI "^resonance" busid)-resonancerecv :: Pattern Int -> ControlPattern-resonancerecv busid = pI "^resonance" busid---- | ring modulation-ring :: Pattern Double -> ControlPattern-ring = pF "ring"-ringbus :: Pattern Int -> Pattern Double -> ControlPattern-ringbus busid pat = (pF "ring" pat) # (pI "^ring" busid)-ringrecv :: Pattern Int -> ControlPattern-ringrecv busid = pI "^ring" busid---- | ring modulation-ringdf :: Pattern Double -> ControlPattern-ringdf = pF "ringdf"-ringdfbus :: Pattern Int -> Pattern Double -> ControlPattern-ringdfbus busid pat = (pF "ringdf" pat) # (pI "^ringdf" busid)-ringdfrecv :: Pattern Int -> ControlPattern-ringdfrecv busid = pI "^ringdf" busid---- | ring modulation-ringf :: Pattern Double -> ControlPattern-ringf = pF "ringf"-ringfbus :: Pattern Int -> Pattern Double -> ControlPattern-ringfbus busid pat = (pF "ringf" pat) # (pI "^ringf" busid)-ringfrecv :: Pattern Int -> ControlPattern-ringfrecv busid = pI "^ringf" busid---- | a pattern of numbers from 0 to 1. Sets the level of reverb.-room :: Pattern Double -> ControlPattern-room = pF "room"-roombus :: Pattern Int -> Pattern Double -> ControlPattern-roombus busid pat = (pF "room" pat) # (pI "^room" busid)-roomrecv :: Pattern Int -> ControlPattern-roomrecv busid = pI "^room" busid---- | -sagogo :: Pattern Double -> ControlPattern-sagogo = pF "sagogo"-sagogobus :: Pattern Int -> Pattern Double -> ControlPattern-sagogobus busid pat = (pF "sagogo" pat) # (pI "^sagogo" busid)-sagogorecv :: Pattern Int -> ControlPattern-sagogorecv busid = pI "^sagogo" busid---- | -sclap :: Pattern Double -> ControlPattern-sclap = pF "sclap"-sclapbus :: Pattern Int -> Pattern Double -> ControlPattern-sclapbus busid pat = (pF "sclap" pat) # (pI "^sclap" busid)-sclaprecv :: Pattern Int -> ControlPattern-sclaprecv busid = pI "^sclap" busid---- | -sclaves :: Pattern Double -> ControlPattern-sclaves = pF "sclaves"-sclavesbus :: Pattern Int -> Pattern Double -> ControlPattern-sclavesbus busid pat = (pF "sclaves" pat) # (pI "^sclaves" busid)-sclavesrecv :: Pattern Int -> ControlPattern-sclavesrecv busid = pI "^sclaves" busid---- | Spectral scramble-scram :: Pattern Double -> ControlPattern-scram = pF "scram"-scrambus :: Pattern Int -> Pattern Double -> ControlPattern-scrambus busid pat = (pF "scram" pat) # (pI "^scram" busid)-scramrecv :: Pattern Int -> ControlPattern-scramrecv busid = pI "^scram" busid---- | -scrash :: Pattern Double -> ControlPattern-scrash = pF "scrash"-scrashbus :: Pattern Int -> Pattern Double -> ControlPattern-scrashbus busid pat = (pF "scrash" pat) # (pI "^scrash" busid)-scrashrecv :: Pattern Int -> ControlPattern-scrashrecv busid = pI "^scrash" busid---- | -seconds :: Pattern Double -> ControlPattern-seconds = pF "seconds"-secondsbus :: Pattern Int -> Pattern Double -> ControlPattern-secondsbus busid pat = (pF "seconds" pat) # (pI "^seconds" busid)-secondsrecv :: Pattern Int -> ControlPattern-secondsrecv busid = pI "^seconds" busid---- | -semitone :: Pattern Double -> ControlPattern-semitone = pF "semitone"-semitonebus :: Pattern Int -> Pattern Double -> ControlPattern-semitonebus busid pat = (pF "semitone" pat) # (pI "^semitone" busid)-semitonerecv :: Pattern Int -> ControlPattern-semitonerecv busid = pI "^semitone" busid---- | wave shaping distortion, a pattern of numbers from 0 for no distortion up to 1 for loads of distortion.-shape :: Pattern Double -> ControlPattern-shape = pF "shape"-shapebus :: Pattern Int -> Pattern Double -> ControlPattern-shapebus busid pat = (pF "shape" pat) # (pI "^shape" busid)-shaperecv :: Pattern Int -> ControlPattern-shaperecv busid = pI "^shape" busid---- | a pattern of numbers from 0 to 1. Sets the perceptual size (reverb time) of the `room` to be used in reverb.-size :: Pattern Double -> ControlPattern-size = pF "size"-sizebus :: Pattern Int -> Pattern Double -> ControlPattern-sizebus busid pat = (pF "size" pat) # (pI "^size" busid)-sizerecv :: Pattern Int -> ControlPattern-sizerecv busid = pI "^size" busid---- | -slide :: Pattern Double -> ControlPattern-slide = pF "slide"-slidebus :: Pattern Int -> Pattern Double -> ControlPattern-slidebus busid pat = (pF "slide" pat) # (pI "^slide" busid)-sliderecv :: Pattern Int -> ControlPattern-sliderecv busid = pI "^slide" busid---- | -slider0 :: Pattern Double -> ControlPattern-slider0 = pF "slider0"-slider0bus :: Pattern Int -> Pattern Double -> ControlPattern-slider0bus busid pat = (pF "slider0" pat) # (pI "^slider0" busid)-slider0recv :: Pattern Int -> ControlPattern-slider0recv busid = pI "^slider0" busid---- | -slider1 :: Pattern Double -> ControlPattern-slider1 = pF "slider1"-slider1bus :: Pattern Int -> Pattern Double -> ControlPattern-slider1bus busid pat = (pF "slider1" pat) # (pI "^slider1" busid)-slider1recv :: Pattern Int -> ControlPattern-slider1recv busid = pI "^slider1" busid---- | -slider10 :: Pattern Double -> ControlPattern-slider10 = pF "slider10"-slider10bus :: Pattern Int -> Pattern Double -> ControlPattern-slider10bus busid pat = (pF "slider10" pat) # (pI "^slider10" busid)-slider10recv :: Pattern Int -> ControlPattern-slider10recv busid = pI "^slider10" busid---- | -slider11 :: Pattern Double -> ControlPattern-slider11 = pF "slider11"-slider11bus :: Pattern Int -> Pattern Double -> ControlPattern-slider11bus busid pat = (pF "slider11" pat) # (pI "^slider11" busid)-slider11recv :: Pattern Int -> ControlPattern-slider11recv busid = pI "^slider11" busid---- | -slider12 :: Pattern Double -> ControlPattern-slider12 = pF "slider12"-slider12bus :: Pattern Int -> Pattern Double -> ControlPattern-slider12bus busid pat = (pF "slider12" pat) # (pI "^slider12" busid)-slider12recv :: Pattern Int -> ControlPattern-slider12recv busid = pI "^slider12" busid---- | -slider13 :: Pattern Double -> ControlPattern-slider13 = pF "slider13"-slider13bus :: Pattern Int -> Pattern Double -> ControlPattern-slider13bus busid pat = (pF "slider13" pat) # (pI "^slider13" busid)-slider13recv :: Pattern Int -> ControlPattern-slider13recv busid = pI "^slider13" busid---- | -slider14 :: Pattern Double -> ControlPattern-slider14 = pF "slider14"-slider14bus :: Pattern Int -> Pattern Double -> ControlPattern-slider14bus busid pat = (pF "slider14" pat) # (pI "^slider14" busid)-slider14recv :: Pattern Int -> ControlPattern-slider14recv busid = pI "^slider14" busid---- | -slider15 :: Pattern Double -> ControlPattern-slider15 = pF "slider15"-slider15bus :: Pattern Int -> Pattern Double -> ControlPattern-slider15bus busid pat = (pF "slider15" pat) # (pI "^slider15" busid)-slider15recv :: Pattern Int -> ControlPattern-slider15recv busid = pI "^slider15" busid---- | -slider2 :: Pattern Double -> ControlPattern-slider2 = pF "slider2"-slider2bus :: Pattern Int -> Pattern Double -> ControlPattern-slider2bus busid pat = (pF "slider2" pat) # (pI "^slider2" busid)-slider2recv :: Pattern Int -> ControlPattern-slider2recv busid = pI "^slider2" busid---- | -slider3 :: Pattern Double -> ControlPattern-slider3 = pF "slider3"-slider3bus :: Pattern Int -> Pattern Double -> ControlPattern-slider3bus busid pat = (pF "slider3" pat) # (pI "^slider3" busid)-slider3recv :: Pattern Int -> ControlPattern-slider3recv busid = pI "^slider3" busid---- | -slider4 :: Pattern Double -> ControlPattern-slider4 = pF "slider4"-slider4bus :: Pattern Int -> Pattern Double -> ControlPattern-slider4bus busid pat = (pF "slider4" pat) # (pI "^slider4" busid)-slider4recv :: Pattern Int -> ControlPattern-slider4recv busid = pI "^slider4" busid---- | -slider5 :: Pattern Double -> ControlPattern-slider5 = pF "slider5"-slider5bus :: Pattern Int -> Pattern Double -> ControlPattern-slider5bus busid pat = (pF "slider5" pat) # (pI "^slider5" busid)-slider5recv :: Pattern Int -> ControlPattern-slider5recv busid = pI "^slider5" busid---- | -slider6 :: Pattern Double -> ControlPattern-slider6 = pF "slider6"-slider6bus :: Pattern Int -> Pattern Double -> ControlPattern-slider6bus busid pat = (pF "slider6" pat) # (pI "^slider6" busid)-slider6recv :: Pattern Int -> ControlPattern-slider6recv busid = pI "^slider6" busid---- | -slider7 :: Pattern Double -> ControlPattern-slider7 = pF "slider7"-slider7bus :: Pattern Int -> Pattern Double -> ControlPattern-slider7bus busid pat = (pF "slider7" pat) # (pI "^slider7" busid)-slider7recv :: Pattern Int -> ControlPattern-slider7recv busid = pI "^slider7" busid---- | -slider8 :: Pattern Double -> ControlPattern-slider8 = pF "slider8"-slider8bus :: Pattern Int -> Pattern Double -> ControlPattern-slider8bus busid pat = (pF "slider8" pat) # (pI "^slider8" busid)-slider8recv :: Pattern Int -> ControlPattern-slider8recv busid = pI "^slider8" busid---- | -slider9 :: Pattern Double -> ControlPattern-slider9 = pF "slider9"-slider9bus :: Pattern Int -> Pattern Double -> ControlPattern-slider9bus busid pat = (pF "slider9" pat) # (pI "^slider9" busid)-slider9recv :: Pattern Int -> ControlPattern-slider9recv busid = pI "^slider9" busid---- | Spectral smear-smear :: Pattern Double -> ControlPattern-smear = pF "smear"-smearbus :: Pattern Int -> Pattern Double -> ControlPattern-smearbus busid pat = (pF "smear" pat) # (pI "^smear" busid)-smearrecv :: Pattern Int -> ControlPattern-smearrecv busid = pI "^smear" busid---- | -songPtr :: Pattern Double -> ControlPattern-songPtr = pF "songPtr"-songPtrbus :: Pattern Int -> Pattern Double -> ControlPattern-songPtrbus busid pat = (pF "songPtr" pat) # (pI "^songPtr" busid)-songPtrrecv :: Pattern Int -> ControlPattern-songPtrrecv busid = pI "^songPtr" busid---- | a pattern of numbers which changes the speed of sample playback, i.e. a cheap way of changing pitch. Negative values will play the sample backwards!-speed :: Pattern Double -> ControlPattern-speed = pF "speed"-speedbus :: Pattern Int -> Pattern Double -> ControlPattern-speedbus _ _ = error $ "Control parameter 'speed' can't be sent to a bus."---- | -squiz :: Pattern Double -> ControlPattern-squiz = pF "squiz"-squizbus :: Pattern Int -> Pattern Double -> ControlPattern-squizbus busid pat = (pF "squiz" pat) # (pI "^squiz" busid)-squizrecv :: Pattern Int -> ControlPattern-squizrecv busid = pI "^squiz" busid---- | -stepsPerOctave :: Pattern Double -> ControlPattern-stepsPerOctave = pF "stepsPerOctave"-stepsPerOctavebus :: Pattern Int -> Pattern Double -> ControlPattern-stepsPerOctavebus busid pat = (pF "stepsPerOctave" pat) # (pI "^stepsPerOctave" busid)-stepsPerOctaverecv :: Pattern Int -> ControlPattern-stepsPerOctaverecv busid = pI "^stepsPerOctave" busid---- | -stutterdepth :: Pattern Double -> ControlPattern-stutterdepth = pF "stutterdepth"-stutterdepthbus :: Pattern Int -> Pattern Double -> ControlPattern-stutterdepthbus busid pat = (pF "stutterdepth" pat) # (pI "^stutterdepth" busid)-stutterdepthrecv :: Pattern Int -> ControlPattern-stutterdepthrecv busid = pI "^stutterdepth" busid---- | -stuttertime :: Pattern Double -> ControlPattern-stuttertime = pF "stuttertime"-stuttertimebus :: Pattern Int -> Pattern Double -> ControlPattern-stuttertimebus busid pat = (pF "stuttertime" pat) # (pI "^stuttertime" busid)-stuttertimerecv :: Pattern Int -> ControlPattern-stuttertimerecv busid = pI "^stuttertime" busid---- | -sustain :: Pattern Double -> ControlPattern-sustain = pF "sustain"-sustainbus :: Pattern Int -> Pattern Double -> ControlPattern-sustainbus _ _ = error $ "Control parameter 'sustain' can't be sent to a bus."---- | -sustainpedal :: Pattern Double -> ControlPattern-sustainpedal = pF "sustainpedal"-sustainpedalbus :: Pattern Int -> Pattern Double -> ControlPattern-sustainpedalbus busid pat = (pF "sustainpedal" pat) # (pI "^sustainpedal" busid)-sustainpedalrecv :: Pattern Int -> ControlPattern-sustainpedalrecv busid = pI "^sustainpedal" busid---- | for internal sound routing-to :: Pattern Double -> ControlPattern-to = pF "to"-tobus :: Pattern Int -> Pattern Double -> ControlPattern-tobus busid pat = (pF "to" pat) # (pI "^to" busid)-torecv :: Pattern Int -> ControlPattern-torecv busid = pI "^to" busid---- | for internal sound routing-toArg :: Pattern String -> ControlPattern-toArg = pS "toArg"-toArgbus :: Pattern Int -> Pattern String -> ControlPattern-toArgbus busid pat = (pS "toArg" pat) # (pI "^toArg" busid)-toArgrecv :: Pattern Int -> ControlPattern-toArgrecv busid = pI "^toArg" busid---- | -tomdecay :: Pattern Double -> ControlPattern-tomdecay = pF "tomdecay"-tomdecaybus :: Pattern Int -> Pattern Double -> ControlPattern-tomdecaybus busid pat = (pF "tomdecay" pat) # (pI "^tomdecay" busid)-tomdecayrecv :: Pattern Int -> ControlPattern-tomdecayrecv busid = pI "^tomdecay" busid---- | Tremolo Audio DSP effect | params are 'tremolorate' and 'tremolodepth'-tremolodepth :: Pattern Double -> ControlPattern-tremolodepth = pF "tremolodepth"-tremolodepthbus :: Pattern Int -> Pattern Double -> ControlPattern-tremolodepthbus busid pat = (pF "tremolodepth" pat) # (pI "^tremolodepth" busid)-tremolodepthrecv :: Pattern Int -> ControlPattern-tremolodepthrecv busid = pI "^tremolodepth" busid---- | Tremolo Audio DSP effect | params are 'tremolorate' and 'tremolodepth'-tremolorate :: Pattern Double -> ControlPattern-tremolorate = pF "tremolorate"-tremoloratebus :: Pattern Int -> Pattern Double -> ControlPattern-tremoloratebus busid pat = (pF "tremolorate" pat) # (pI "^tremolorate" busid)-tremoloraterecv :: Pattern Int -> ControlPattern-tremoloraterecv busid = pI "^tremolorate" busid---- | tube distortion-triode :: Pattern Double -> ControlPattern-triode = pF "triode"-triodebus :: Pattern Int -> Pattern Double -> ControlPattern-triodebus busid pat = (pF "triode" pat) # (pI "^triode" busid)-trioderecv :: Pattern Int -> ControlPattern-trioderecv busid = pI "^triode" busid---- | -tsdelay :: Pattern Double -> ControlPattern-tsdelay = pF "tsdelay"-tsdelaybus :: Pattern Int -> Pattern Double -> ControlPattern-tsdelaybus busid pat = (pF "tsdelay" pat) # (pI "^tsdelay" busid)-tsdelayrecv :: Pattern Int -> ControlPattern-tsdelayrecv busid = pI "^tsdelay" busid---- | -uid :: Pattern Double -> ControlPattern-uid = pF "uid"-uidbus :: Pattern Int -> Pattern Double -> ControlPattern-uidbus busid pat = (pF "uid" pat) # (pI "^uid" busid)-uidrecv :: Pattern Int -> ControlPattern-uidrecv busid = pI "^uid" busid---- | used in conjunction with `speed`, accepts values of "r" (rate, default behavior), "c" (cycles), or "s" (seconds). Using `unit "c"` means `speed` will be interpreted in units of cycles, e.g. `speed "1"` means samples will be stretched to fill a cycle. Using `unit "s"` means the playback speed will be adjusted so that the duration is the number of seconds specified by `speed`.-unit :: Pattern String -> ControlPattern-unit = pS "unit"-unitbus :: Pattern Int -> Pattern String -> ControlPattern-unitbus _ _ = error $ "Control parameter 'unit' can't be sent to a bus."---- | -val :: Pattern Double -> ControlPattern-val = pF "val"-valbus :: Pattern Int -> Pattern Double -> ControlPattern-valbus busid pat = (pF "val" pat) # (pI "^val" busid)-valrecv :: Pattern Int -> ControlPattern-valrecv busid = pI "^val" busid---- | -vcfegint :: Pattern Double -> ControlPattern-vcfegint = pF "vcfegint"-vcfegintbus :: Pattern Int -> Pattern Double -> ControlPattern-vcfegintbus busid pat = (pF "vcfegint" pat) # (pI "^vcfegint" busid)-vcfegintrecv :: Pattern Int -> ControlPattern-vcfegintrecv busid = pI "^vcfegint" busid---- | -vcoegint :: Pattern Double -> ControlPattern-vcoegint = pF "vcoegint"-vcoegintbus :: Pattern Int -> Pattern Double -> ControlPattern-vcoegintbus busid pat = (pF "vcoegint" pat) # (pI "^vcoegint" busid)-vcoegintrecv :: Pattern Int -> ControlPattern-vcoegintrecv busid = pI "^vcoegint" busid---- | -velocity :: Pattern Double -> ControlPattern-velocity = pF "velocity"-velocitybus :: Pattern Int -> Pattern Double -> ControlPattern-velocitybus busid pat = (pF "velocity" pat) # (pI "^velocity" busid)-velocityrecv :: Pattern Int -> ControlPattern-velocityrecv busid = pI "^velocity" busid---- | -voice :: Pattern Double -> ControlPattern-voice = pF "voice"-voicebus :: Pattern Int -> Pattern Double -> ControlPattern-voicebus busid pat = (pF "voice" pat) # (pI "^voice" busid)-voicerecv :: Pattern Int -> ControlPattern-voicerecv busid = pI "^voice" busid---- | formant filter to make things sound like vowels, a pattern of either `a`, `e`, `i`, `o` or `u`. Use a rest (`~`) for no effect.-vowel :: Pattern String -> ControlPattern-vowel = pS "vowel"-vowelbus :: Pattern Int -> Pattern String -> ControlPattern-vowelbus busid pat = (pS "vowel" pat) # (pI "^vowel" busid)-vowelrecv :: Pattern Int -> ControlPattern-vowelrecv busid = pI "^vowel" busid---- | -waveloss :: Pattern Double -> ControlPattern-waveloss = pF "waveloss"-wavelossbus :: Pattern Int -> Pattern Double -> ControlPattern-wavelossbus busid pat = (pF "waveloss" pat) # (pI "^waveloss" busid)-wavelossrecv :: Pattern Int -> ControlPattern-wavelossrecv busid = pI "^waveloss" busid---- | -xsdelay :: Pattern Double -> ControlPattern-xsdelay = pF "xsdelay"+import Data.Fixed (mod')++-- | group multiple params into one+grp :: [String -> ValueMap] -> Pattern String -> ControlPattern+grp [] _ = empty+grp fs p = splitby <$> p+ where splitby name = Map.unions $ map (\(v, f) -> f v) $ zip (split name) fs+ split :: String -> [String]+ split = wordsBy (==':')++mF :: String -> String -> ValueMap+mF name v = fromMaybe Map.empty $ do f <- readMaybe v+ return $ Map.singleton name (VF f)++mI :: String -> String -> ValueMap+mI name v = fromMaybe Map.empty $ do i <- readMaybe v+ return $ Map.singleton name (VI i)++mS :: String -> String -> ValueMap+mS name v = Map.singleton name (VS v)++-- | Param makers++pF :: String -> Pattern Double -> ControlPattern+pF name = fmap (Map.singleton name . VF)++pI :: String -> Pattern Int -> ControlPattern+pI name = fmap (Map.singleton name . VI)++pB :: String -> Pattern Bool -> ControlPattern+pB name = fmap (Map.singleton name . VB)+ +pR :: String -> Pattern Rational -> ControlPattern+pR name = fmap (Map.singleton name . VR)++pN :: String -> Pattern Note -> ControlPattern+pN name = fmap (Map.singleton name . VN)++pS :: String -> Pattern String -> ControlPattern+pS name = fmap (Map.singleton name . VS)++pX :: String -> Pattern [Word8] -> ControlPattern+pX name = fmap (Map.singleton name . VX)++pStateF :: String -> String -> (Maybe Double -> Double) -> ControlPattern+pStateF name sName update = pure $ Map.singleton name $ VState statef+ where statef :: ValueMap -> (ValueMap, Value)+ statef sMap = (Map.insert sName v sMap, v) + where v = VF $ update $ (Map.lookup sName sMap) >>= getF++pStateList :: String -> String -> [Value] -> ControlPattern+pStateList name sName xs = pure $ Map.singleton name $ VState statef+ where statef :: ValueMap -> (ValueMap, Value)+ statef sMap = (Map.insert sName (VList $ tail looped) sMap, head looped) + where xs' = fromMaybe xs ((Map.lookup sName sMap) >>= getList)+ -- do this instead of a cycle, so it can get updated with the a list+ looped | null xs' = xs+ | otherwise = xs'++pStateListF :: String -> String -> [Double] -> ControlPattern+pStateListF name sName = pStateList name sName . map VF++-- | Grouped params++sound :: Pattern String -> ControlPattern+sound = grp [mS "s", mF "n"]++sTake :: String -> [Double] -> ControlPattern+sTake name xs = pStateListF "s" name xs++cc :: Pattern String -> ControlPattern+cc = grp [mF "ccn", mF "ccv"]++nrpn :: Pattern String -> ControlPattern+nrpn = grp [mI "nrpn", mI "val"]++grain' :: Pattern String -> ControlPattern+grain' = grp [mF "begin", mF "end"]++midinote :: Pattern Note -> ControlPattern+midinote = note . (subtract 60 <$>)++drum :: Pattern String -> ControlPattern+drum = n . (subtract 60 . drumN <$>)++drumN :: Num a => String -> a+drumN "hq" = 27+drumN "sl" = 28+drumN "ps" = 29+drumN "pl" = 30+drumN "st" = 31+drumN "sq" = 32+drumN "ml" = 33+drumN "mb" = 34+drumN "ab" = 35+drumN "bd" = 36+drumN "rm" = 37+drumN "sn" = 38+drumN "cp" = 39+drumN "es" = 40+drumN "lf" = 41+drumN "ch" = 42+drumN "lt" = 43+drumN "hh" = 44+drumN "ft" = 45+drumN "oh" = 46+drumN "mt" = 47+drumN "hm" = 48+drumN "cr" = 49+drumN "ht" = 50+drumN "ri" = 51+drumN "cy" = 52+drumN "be" = 53+drumN "ta" = 54+drumN "sc" = 55+drumN "cb" = 56+drumN "cs" = 57+drumN "vi" = 58+drumN "rc" = 59+drumN "hb" = 60+drumN "lb" = 61+drumN "mh" = 62+drumN "hc" = 63+drumN "lc" = 64+drumN "he" = 65+drumN "le" = 66+drumN "ag" = 67+drumN "la" = 68+drumN "ca" = 69+drumN "ma" = 70+drumN "sw" = 71+drumN "lw" = 72+drumN "sg" = 73+drumN "lg" = 74+drumN "cl" = 75+drumN "hi" = 76+drumN "li" = 77+drumN "mc" = 78+drumN "oc" = 79+drumN "tr" = 80+drumN "ot" = 81+drumN "sh" = 82+drumN "jb" = 83+drumN "bt" = 84+drumN "ct" = 85+drumN "ms" = 86+drumN "os" = 87+drumN _ = 0++-- Generated params++-- | a pattern of numbers that speed up (or slow down) samples while they play.+accelerate :: Pattern Double -> ControlPattern+accelerate = pF "accelerate"+accelerateTake :: String -> [Double] -> ControlPattern+accelerateTake name xs = pStateListF "accelerate" name xs+accelerateCount :: String -> ControlPattern+accelerateCount name = pStateF "accelerate" name (maybe 0 (+1))+accelerateCountTo :: String -> Pattern Double -> Pattern ValueMap+accelerateCountTo name ipat = innerJoin $ (\i -> pStateF "accelerate" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++acceleratebus :: Pattern Int -> Pattern Double -> ControlPattern+acceleratebus busid pat = (pF "accelerate" pat) # (pI "^accelerate" busid)+acceleraterecv :: Pattern Int -> ControlPattern+acceleraterecv busid = pI "^accelerate" busid++-- | like @gain@, but linear.+amp :: Pattern Double -> ControlPattern+amp = pF "amp"+ampTake :: String -> [Double] -> ControlPattern+ampTake name xs = pStateListF "amp" name xs+ampCount :: String -> ControlPattern+ampCount name = pStateF "amp" name (maybe 0 (+1))+ampCountTo :: String -> Pattern Double -> Pattern ValueMap+ampCountTo name ipat = innerJoin $ (\i -> pStateF "amp" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++ampbus :: Pattern Int -> Pattern Double -> ControlPattern+ampbus busid pat = (pF "amp" pat) # (pI "^amp" busid)+amprecv :: Pattern Int -> ControlPattern+amprecv busid = pI "^amp" busid++-- | +array :: Pattern [Word8] -> ControlPattern+array = pX "array"+arrayTake :: String -> [Double] -> ControlPattern+arrayTake name xs = pStateListF "array" name xs+arraybus :: Pattern Int -> Pattern [Word8] -> ControlPattern+arraybus busid pat = (pX "array" pat) # (pI "^array" busid)+arrayrecv :: Pattern Int -> ControlPattern+arrayrecv busid = pI "^array" busid++-- | a pattern of numbers to specify the attack time (in seconds) of an envelope applied to each sample.+attack :: Pattern Double -> ControlPattern+attack = pF "attack"+attackTake :: String -> [Double] -> ControlPattern+attackTake name xs = pStateListF "attack" name xs+attackCount :: String -> ControlPattern+attackCount name = pStateF "attack" name (maybe 0 (+1))+attackCountTo :: String -> Pattern Double -> Pattern ValueMap+attackCountTo name ipat = innerJoin $ (\i -> pStateF "attack" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++attackbus :: Pattern Int -> Pattern Double -> ControlPattern+attackbus busid pat = (pF "attack" pat) # (pI "^attack" busid)+attackrecv :: Pattern Int -> ControlPattern+attackrecv busid = pI "^attack" busid++-- | a pattern of numbers from 0 to 1. Sets the center frequency of the band-pass filter.+bandf :: Pattern Double -> ControlPattern+bandf = pF "bandf"+bandfTake :: String -> [Double] -> ControlPattern+bandfTake name xs = pStateListF "bandf" name xs+bandfCount :: String -> ControlPattern+bandfCount name = pStateF "bandf" name (maybe 0 (+1))+bandfCountTo :: String -> Pattern Double -> Pattern ValueMap+bandfCountTo name ipat = innerJoin $ (\i -> pStateF "bandf" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++bandfbus :: Pattern Int -> Pattern Double -> ControlPattern+bandfbus busid pat = (pF "bandf" pat) # (pI "^bandf" busid)+bandfrecv :: Pattern Int -> ControlPattern+bandfrecv busid = pI "^bandf" busid++-- | a pattern of anumbers from 0 to 1. Sets the q-factor of the band-pass filter.+bandq :: Pattern Double -> ControlPattern+bandq = pF "bandq"+bandqTake :: String -> [Double] -> ControlPattern+bandqTake name xs = pStateListF "bandq" name xs+bandqCount :: String -> ControlPattern+bandqCount name = pStateF "bandq" name (maybe 0 (+1))+bandqCountTo :: String -> Pattern Double -> Pattern ValueMap+bandqCountTo name ipat = innerJoin $ (\i -> pStateF "bandq" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++bandqbus :: Pattern Int -> Pattern Double -> ControlPattern+bandqbus busid pat = (pF "bandq" pat) # (pI "^bandq" busid)+bandqrecv :: Pattern Int -> ControlPattern+bandqrecv busid = pI "^bandq" busid++-- | 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.+begin :: Pattern Double -> ControlPattern+begin = pF "begin"+beginTake :: String -> [Double] -> ControlPattern+beginTake name xs = pStateListF "begin" name xs+beginCount :: String -> ControlPattern+beginCount name = pStateF "begin" name (maybe 0 (+1))+beginCountTo :: String -> Pattern Double -> Pattern ValueMap+beginCountTo name ipat = innerJoin $ (\i -> pStateF "begin" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++beginbus :: Pattern Int -> Pattern Double -> ControlPattern+beginbus busid pat = (pF "begin" pat) # (pI "^begin" busid)+beginrecv :: Pattern Int -> ControlPattern+beginrecv busid = pI "^begin" busid++-- | Spectral binshift+binshift :: Pattern Double -> ControlPattern+binshift = pF "binshift"+binshiftTake :: String -> [Double] -> ControlPattern+binshiftTake name xs = pStateListF "binshift" name xs+binshiftCount :: String -> ControlPattern+binshiftCount name = pStateF "binshift" name (maybe 0 (+1))+binshiftCountTo :: String -> Pattern Double -> Pattern ValueMap+binshiftCountTo name ipat = innerJoin $ (\i -> pStateF "binshift" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++binshiftbus :: Pattern Int -> Pattern Double -> ControlPattern+binshiftbus busid pat = (pF "binshift" pat) # (pI "^binshift" busid)+binshiftrecv :: Pattern Int -> ControlPattern+binshiftrecv busid = pI "^binshift" busid++-- | +button0 :: Pattern Double -> ControlPattern+button0 = pF "button0"+button0Take :: String -> [Double] -> ControlPattern+button0Take name xs = pStateListF "button0" name xs+button0Count :: String -> ControlPattern+button0Count name = pStateF "button0" name (maybe 0 (+1))+button0CountTo :: String -> Pattern Double -> Pattern ValueMap+button0CountTo name ipat = innerJoin $ (\i -> pStateF "button0" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button0bus :: Pattern Int -> Pattern Double -> ControlPattern+button0bus busid pat = (pF "button0" pat) # (pI "^button0" busid)+button0recv :: Pattern Int -> ControlPattern+button0recv busid = pI "^button0" busid++-- | +button1 :: Pattern Double -> ControlPattern+button1 = pF "button1"+button1Take :: String -> [Double] -> ControlPattern+button1Take name xs = pStateListF "button1" name xs+button1Count :: String -> ControlPattern+button1Count name = pStateF "button1" name (maybe 0 (+1))+button1CountTo :: String -> Pattern Double -> Pattern ValueMap+button1CountTo name ipat = innerJoin $ (\i -> pStateF "button1" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button1bus :: Pattern Int -> Pattern Double -> ControlPattern+button1bus busid pat = (pF "button1" pat) # (pI "^button1" busid)+button1recv :: Pattern Int -> ControlPattern+button1recv busid = pI "^button1" busid++-- | +button10 :: Pattern Double -> ControlPattern+button10 = pF "button10"+button10Take :: String -> [Double] -> ControlPattern+button10Take name xs = pStateListF "button10" name xs+button10Count :: String -> ControlPattern+button10Count name = pStateF "button10" name (maybe 0 (+1))+button10CountTo :: String -> Pattern Double -> Pattern ValueMap+button10CountTo name ipat = innerJoin $ (\i -> pStateF "button10" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button10bus :: Pattern Int -> Pattern Double -> ControlPattern+button10bus busid pat = (pF "button10" pat) # (pI "^button10" busid)+button10recv :: Pattern Int -> ControlPattern+button10recv busid = pI "^button10" busid++-- | +button11 :: Pattern Double -> ControlPattern+button11 = pF "button11"+button11Take :: String -> [Double] -> ControlPattern+button11Take name xs = pStateListF "button11" name xs+button11Count :: String -> ControlPattern+button11Count name = pStateF "button11" name (maybe 0 (+1))+button11CountTo :: String -> Pattern Double -> Pattern ValueMap+button11CountTo name ipat = innerJoin $ (\i -> pStateF "button11" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button11bus :: Pattern Int -> Pattern Double -> ControlPattern+button11bus busid pat = (pF "button11" pat) # (pI "^button11" busid)+button11recv :: Pattern Int -> ControlPattern+button11recv busid = pI "^button11" busid++-- | +button12 :: Pattern Double -> ControlPattern+button12 = pF "button12"+button12Take :: String -> [Double] -> ControlPattern+button12Take name xs = pStateListF "button12" name xs+button12Count :: String -> ControlPattern+button12Count name = pStateF "button12" name (maybe 0 (+1))+button12CountTo :: String -> Pattern Double -> Pattern ValueMap+button12CountTo name ipat = innerJoin $ (\i -> pStateF "button12" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button12bus :: Pattern Int -> Pattern Double -> ControlPattern+button12bus busid pat = (pF "button12" pat) # (pI "^button12" busid)+button12recv :: Pattern Int -> ControlPattern+button12recv busid = pI "^button12" busid++-- | +button13 :: Pattern Double -> ControlPattern+button13 = pF "button13"+button13Take :: String -> [Double] -> ControlPattern+button13Take name xs = pStateListF "button13" name xs+button13Count :: String -> ControlPattern+button13Count name = pStateF "button13" name (maybe 0 (+1))+button13CountTo :: String -> Pattern Double -> Pattern ValueMap+button13CountTo name ipat = innerJoin $ (\i -> pStateF "button13" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button13bus :: Pattern Int -> Pattern Double -> ControlPattern+button13bus busid pat = (pF "button13" pat) # (pI "^button13" busid)+button13recv :: Pattern Int -> ControlPattern+button13recv busid = pI "^button13" busid++-- | +button14 :: Pattern Double -> ControlPattern+button14 = pF "button14"+button14Take :: String -> [Double] -> ControlPattern+button14Take name xs = pStateListF "button14" name xs+button14Count :: String -> ControlPattern+button14Count name = pStateF "button14" name (maybe 0 (+1))+button14CountTo :: String -> Pattern Double -> Pattern ValueMap+button14CountTo name ipat = innerJoin $ (\i -> pStateF "button14" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button14bus :: Pattern Int -> Pattern Double -> ControlPattern+button14bus busid pat = (pF "button14" pat) # (pI "^button14" busid)+button14recv :: Pattern Int -> ControlPattern+button14recv busid = pI "^button14" busid++-- | +button15 :: Pattern Double -> ControlPattern+button15 = pF "button15"+button15Take :: String -> [Double] -> ControlPattern+button15Take name xs = pStateListF "button15" name xs+button15Count :: String -> ControlPattern+button15Count name = pStateF "button15" name (maybe 0 (+1))+button15CountTo :: String -> Pattern Double -> Pattern ValueMap+button15CountTo name ipat = innerJoin $ (\i -> pStateF "button15" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button15bus :: Pattern Int -> Pattern Double -> ControlPattern+button15bus busid pat = (pF "button15" pat) # (pI "^button15" busid)+button15recv :: Pattern Int -> ControlPattern+button15recv busid = pI "^button15" busid++-- | +button2 :: Pattern Double -> ControlPattern+button2 = pF "button2"+button2Take :: String -> [Double] -> ControlPattern+button2Take name xs = pStateListF "button2" name xs+button2Count :: String -> ControlPattern+button2Count name = pStateF "button2" name (maybe 0 (+1))+button2CountTo :: String -> Pattern Double -> Pattern ValueMap+button2CountTo name ipat = innerJoin $ (\i -> pStateF "button2" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button2bus :: Pattern Int -> Pattern Double -> ControlPattern+button2bus busid pat = (pF "button2" pat) # (pI "^button2" busid)+button2recv :: Pattern Int -> ControlPattern+button2recv busid = pI "^button2" busid++-- | +button3 :: Pattern Double -> ControlPattern+button3 = pF "button3"+button3Take :: String -> [Double] -> ControlPattern+button3Take name xs = pStateListF "button3" name xs+button3Count :: String -> ControlPattern+button3Count name = pStateF "button3" name (maybe 0 (+1))+button3CountTo :: String -> Pattern Double -> Pattern ValueMap+button3CountTo name ipat = innerJoin $ (\i -> pStateF "button3" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button3bus :: Pattern Int -> Pattern Double -> ControlPattern+button3bus busid pat = (pF "button3" pat) # (pI "^button3" busid)+button3recv :: Pattern Int -> ControlPattern+button3recv busid = pI "^button3" busid++-- | +button4 :: Pattern Double -> ControlPattern+button4 = pF "button4"+button4Take :: String -> [Double] -> ControlPattern+button4Take name xs = pStateListF "button4" name xs+button4Count :: String -> ControlPattern+button4Count name = pStateF "button4" name (maybe 0 (+1))+button4CountTo :: String -> Pattern Double -> Pattern ValueMap+button4CountTo name ipat = innerJoin $ (\i -> pStateF "button4" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button4bus :: Pattern Int -> Pattern Double -> ControlPattern+button4bus busid pat = (pF "button4" pat) # (pI "^button4" busid)+button4recv :: Pattern Int -> ControlPattern+button4recv busid = pI "^button4" busid++-- | +button5 :: Pattern Double -> ControlPattern+button5 = pF "button5"+button5Take :: String -> [Double] -> ControlPattern+button5Take name xs = pStateListF "button5" name xs+button5Count :: String -> ControlPattern+button5Count name = pStateF "button5" name (maybe 0 (+1))+button5CountTo :: String -> Pattern Double -> Pattern ValueMap+button5CountTo name ipat = innerJoin $ (\i -> pStateF "button5" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button5bus :: Pattern Int -> Pattern Double -> ControlPattern+button5bus busid pat = (pF "button5" pat) # (pI "^button5" busid)+button5recv :: Pattern Int -> ControlPattern+button5recv busid = pI "^button5" busid++-- | +button6 :: Pattern Double -> ControlPattern+button6 = pF "button6"+button6Take :: String -> [Double] -> ControlPattern+button6Take name xs = pStateListF "button6" name xs+button6Count :: String -> ControlPattern+button6Count name = pStateF "button6" name (maybe 0 (+1))+button6CountTo :: String -> Pattern Double -> Pattern ValueMap+button6CountTo name ipat = innerJoin $ (\i -> pStateF "button6" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button6bus :: Pattern Int -> Pattern Double -> ControlPattern+button6bus busid pat = (pF "button6" pat) # (pI "^button6" busid)+button6recv :: Pattern Int -> ControlPattern+button6recv busid = pI "^button6" busid++-- | +button7 :: Pattern Double -> ControlPattern+button7 = pF "button7"+button7Take :: String -> [Double] -> ControlPattern+button7Take name xs = pStateListF "button7" name xs+button7Count :: String -> ControlPattern+button7Count name = pStateF "button7" name (maybe 0 (+1))+button7CountTo :: String -> Pattern Double -> Pattern ValueMap+button7CountTo name ipat = innerJoin $ (\i -> pStateF "button7" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button7bus :: Pattern Int -> Pattern Double -> ControlPattern+button7bus busid pat = (pF "button7" pat) # (pI "^button7" busid)+button7recv :: Pattern Int -> ControlPattern+button7recv busid = pI "^button7" busid++-- | +button8 :: Pattern Double -> ControlPattern+button8 = pF "button8"+button8Take :: String -> [Double] -> ControlPattern+button8Take name xs = pStateListF "button8" name xs+button8Count :: String -> ControlPattern+button8Count name = pStateF "button8" name (maybe 0 (+1))+button8CountTo :: String -> Pattern Double -> Pattern ValueMap+button8CountTo name ipat = innerJoin $ (\i -> pStateF "button8" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button8bus :: Pattern Int -> Pattern Double -> ControlPattern+button8bus busid pat = (pF "button8" pat) # (pI "^button8" busid)+button8recv :: Pattern Int -> ControlPattern+button8recv busid = pI "^button8" busid++-- | +button9 :: Pattern Double -> ControlPattern+button9 = pF "button9"+button9Take :: String -> [Double] -> ControlPattern+button9Take name xs = pStateListF "button9" name xs+button9Count :: String -> ControlPattern+button9Count name = pStateF "button9" name (maybe 0 (+1))+button9CountTo :: String -> Pattern Double -> Pattern ValueMap+button9CountTo name ipat = innerJoin $ (\i -> pStateF "button9" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++button9bus :: Pattern Int -> Pattern Double -> ControlPattern+button9bus busid pat = (pF "button9" pat) # (pI "^button9" busid)+button9recv :: Pattern Int -> ControlPattern+button9recv busid = pI "^button9" busid++-- | +ccn :: Pattern Double -> ControlPattern+ccn = pF "ccn"+ccnTake :: String -> [Double] -> ControlPattern+ccnTake name xs = pStateListF "ccn" name xs+ccnCount :: String -> ControlPattern+ccnCount name = pStateF "ccn" name (maybe 0 (+1))+ccnCountTo :: String -> Pattern Double -> Pattern ValueMap+ccnCountTo name ipat = innerJoin $ (\i -> pStateF "ccn" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++ccnbus :: Pattern Int -> Pattern Double -> ControlPattern+ccnbus busid pat = (pF "ccn" pat) # (pI "^ccn" busid)+ccnrecv :: Pattern Int -> ControlPattern+ccnrecv busid = pI "^ccn" busid++-- | +ccv :: Pattern Double -> ControlPattern+ccv = pF "ccv"+ccvTake :: String -> [Double] -> ControlPattern+ccvTake name xs = pStateListF "ccv" name xs+ccvCount :: String -> ControlPattern+ccvCount name = pStateF "ccv" name (maybe 0 (+1))+ccvCountTo :: String -> Pattern Double -> Pattern ValueMap+ccvCountTo name ipat = innerJoin $ (\i -> pStateF "ccv" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++ccvbus :: Pattern Int -> Pattern Double -> ControlPattern+ccvbus busid pat = (pF "ccv" pat) # (pI "^ccv" busid)+ccvrecv :: Pattern Int -> ControlPattern+ccvrecv busid = pI "^ccv" busid++-- | choose the channel the pattern is sent to in superdirt+channel :: Pattern Int -> ControlPattern+channel = pI "channel"+channelTake :: String -> [Double] -> ControlPattern+channelTake name xs = pStateListF "channel" name xs+channelCount :: String -> ControlPattern+channelCount name = pStateF "channel" name (maybe 0 (+1))+channelCountTo :: String -> Pattern Double -> Pattern ValueMap+channelCountTo name ipat = innerJoin $ (\i -> pStateF "channel" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++channelbus :: Pattern Int -> Pattern Int -> ControlPattern+channelbus _ _ = error $ "Control parameter 'channel' can't be sent to a bus."++-- | +clhatdecay :: Pattern Double -> ControlPattern+clhatdecay = pF "clhatdecay"+clhatdecayTake :: String -> [Double] -> ControlPattern+clhatdecayTake name xs = pStateListF "clhatdecay" name xs+clhatdecayCount :: String -> ControlPattern+clhatdecayCount name = pStateF "clhatdecay" name (maybe 0 (+1))+clhatdecayCountTo :: String -> Pattern Double -> Pattern ValueMap+clhatdecayCountTo name ipat = innerJoin $ (\i -> pStateF "clhatdecay" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++clhatdecaybus :: Pattern Int -> Pattern Double -> ControlPattern+clhatdecaybus busid pat = (pF "clhatdecay" pat) # (pI "^clhatdecay" busid)+clhatdecayrecv :: Pattern Int -> ControlPattern+clhatdecayrecv busid = pI "^clhatdecay" busid++-- | 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 Double -> ControlPattern+coarse = pF "coarse"+coarseTake :: String -> [Double] -> ControlPattern+coarseTake name xs = pStateListF "coarse" name xs+coarseCount :: String -> ControlPattern+coarseCount name = pStateF "coarse" name (maybe 0 (+1))+coarseCountTo :: String -> Pattern Double -> Pattern ValueMap+coarseCountTo name ipat = innerJoin $ (\i -> pStateF "coarse" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++coarsebus :: Pattern Int -> Pattern Double -> ControlPattern+coarsebus busid pat = (pF "coarse" pat) # (pI "^coarse" busid)+coarserecv :: Pattern Int -> ControlPattern+coarserecv busid = pI "^coarse" busid++-- | Spectral comb+comb :: Pattern Double -> ControlPattern+comb = pF "comb"+combTake :: String -> [Double] -> ControlPattern+combTake name xs = pStateListF "comb" name xs+combCount :: String -> ControlPattern+combCount name = pStateF "comb" name (maybe 0 (+1))+combCountTo :: String -> Pattern Double -> Pattern ValueMap+combCountTo name ipat = innerJoin $ (\i -> pStateF "comb" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++combbus :: Pattern Int -> Pattern Double -> ControlPattern+combbus busid pat = (pF "comb" pat) # (pI "^comb" busid)+combrecv :: Pattern Int -> ControlPattern+combrecv busid = pI "^comb" busid++-- | +control :: Pattern Double -> ControlPattern+control = pF "control"+controlTake :: String -> [Double] -> ControlPattern+controlTake name xs = pStateListF "control" name xs+controlCount :: String -> ControlPattern+controlCount name = pStateF "control" name (maybe 0 (+1))+controlCountTo :: String -> Pattern Double -> Pattern ValueMap+controlCountTo name ipat = innerJoin $ (\i -> pStateF "control" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++controlbus :: Pattern Int -> Pattern Double -> ControlPattern+controlbus busid pat = (pF "control" pat) # (pI "^control" busid)+controlrecv :: Pattern Int -> ControlPattern+controlrecv busid = pI "^control" busid++-- | +cps :: Pattern Double -> ControlPattern+cps = pF "cps"+cpsTake :: String -> [Double] -> ControlPattern+cpsTake name xs = pStateListF "cps" name xs+cpsCount :: String -> ControlPattern+cpsCount name = pStateF "cps" name (maybe 0 (+1))+cpsCountTo :: String -> Pattern Double -> Pattern ValueMap+cpsCountTo name ipat = innerJoin $ (\i -> pStateF "cps" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++cpsbus :: Pattern Int -> Pattern Double -> ControlPattern+cpsbus busid pat = (pF "cps" pat) # (pI "^cps" busid)+cpsrecv :: Pattern Int -> ControlPattern+cpsrecv busid = pI "^cps" busid++-- | bit crushing, a pattern of numbers from 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction).+crush :: Pattern Double -> ControlPattern+crush = pF "crush"+crushTake :: String -> [Double] -> ControlPattern+crushTake name xs = pStateListF "crush" name xs+crushCount :: String -> ControlPattern+crushCount name = pStateF "crush" name (maybe 0 (+1))+crushCountTo :: String -> Pattern Double -> Pattern ValueMap+crushCountTo name ipat = innerJoin $ (\i -> pStateF "crush" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++crushbus :: Pattern Int -> Pattern Double -> ControlPattern+crushbus busid pat = (pF "crush" pat) # (pI "^crush" busid)+crushrecv :: Pattern Int -> ControlPattern+crushrecv busid = pI "^crush" busid++-- | +ctlNum :: Pattern Double -> ControlPattern+ctlNum = pF "ctlNum"+ctlNumTake :: String -> [Double] -> ControlPattern+ctlNumTake name xs = pStateListF "ctlNum" name xs+ctlNumCount :: String -> ControlPattern+ctlNumCount name = pStateF "ctlNum" name (maybe 0 (+1))+ctlNumCountTo :: String -> Pattern Double -> Pattern ValueMap+ctlNumCountTo name ipat = innerJoin $ (\i -> pStateF "ctlNum" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++ctlNumbus :: Pattern Int -> Pattern Double -> ControlPattern+ctlNumbus busid pat = (pF "ctlNum" pat) # (pI "^ctlNum" busid)+ctlNumrecv :: Pattern Int -> ControlPattern+ctlNumrecv busid = pI "^ctlNum" busid++-- | +ctranspose :: Pattern Double -> ControlPattern+ctranspose = pF "ctranspose"+ctransposeTake :: String -> [Double] -> ControlPattern+ctransposeTake name xs = pStateListF "ctranspose" name xs+ctransposeCount :: String -> ControlPattern+ctransposeCount name = pStateF "ctranspose" name (maybe 0 (+1))+ctransposeCountTo :: String -> Pattern Double -> Pattern ValueMap+ctransposeCountTo name ipat = innerJoin $ (\i -> pStateF "ctranspose" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++ctransposebus :: Pattern Int -> Pattern Double -> ControlPattern+ctransposebus busid pat = (pF "ctranspose" pat) # (pI "^ctranspose" busid)+ctransposerecv :: Pattern Int -> ControlPattern+ctransposerecv busid = pI "^ctranspose" busid++-- | 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.+cut :: Pattern Int -> ControlPattern+cut = pI "cut"+cutTake :: String -> [Double] -> ControlPattern+cutTake name xs = pStateListF "cut" name xs+cutCount :: String -> ControlPattern+cutCount name = pStateF "cut" name (maybe 0 (+1))+cutCountTo :: String -> Pattern Double -> Pattern ValueMap+cutCountTo name ipat = innerJoin $ (\i -> pStateF "cut" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++cutbus :: Pattern Int -> Pattern Int -> ControlPattern+cutbus busid pat = (pI "cut" pat) # (pI "^cut" busid)+cutrecv :: Pattern Int -> ControlPattern+cutrecv busid = pI "^cut" busid++-- | a pattern of numbers from 0 to 1. Applies the cutoff frequency of the low-pass filter.+cutoff :: Pattern Double -> ControlPattern+cutoff = pF "cutoff"+cutoffTake :: String -> [Double] -> ControlPattern+cutoffTake name xs = pStateListF "cutoff" name xs+cutoffCount :: String -> ControlPattern+cutoffCount name = pStateF "cutoff" name (maybe 0 (+1))+cutoffCountTo :: String -> Pattern Double -> Pattern ValueMap+cutoffCountTo name ipat = innerJoin $ (\i -> pStateF "cutoff" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++cutoffbus :: Pattern Int -> Pattern Double -> ControlPattern+cutoffbus busid pat = (pF "cutoff" pat) # (pI "^cutoff" busid)+cutoffrecv :: Pattern Int -> ControlPattern+cutoffrecv busid = pI "^cutoff" busid++-- | +cutoffegint :: Pattern Double -> ControlPattern+cutoffegint = pF "cutoffegint"+cutoffegintTake :: String -> [Double] -> ControlPattern+cutoffegintTake name xs = pStateListF "cutoffegint" name xs+cutoffegintCount :: String -> ControlPattern+cutoffegintCount name = pStateF "cutoffegint" name (maybe 0 (+1))+cutoffegintCountTo :: String -> Pattern Double -> Pattern ValueMap+cutoffegintCountTo name ipat = innerJoin $ (\i -> pStateF "cutoffegint" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++cutoffegintbus :: Pattern Int -> Pattern Double -> ControlPattern+cutoffegintbus busid pat = (pF "cutoffegint" pat) # (pI "^cutoffegint" busid)+cutoffegintrecv :: Pattern Int -> ControlPattern+cutoffegintrecv busid = pI "^cutoffegint" busid++-- | +decay :: Pattern Double -> ControlPattern+decay = pF "decay"+decayTake :: String -> [Double] -> ControlPattern+decayTake name xs = pStateListF "decay" name xs+decayCount :: String -> ControlPattern+decayCount name = pStateF "decay" name (maybe 0 (+1))+decayCountTo :: String -> Pattern Double -> Pattern ValueMap+decayCountTo name ipat = innerJoin $ (\i -> pStateF "decay" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++decaybus :: Pattern Int -> Pattern Double -> ControlPattern+decaybus busid pat = (pF "decay" pat) # (pI "^decay" busid)+decayrecv :: Pattern Int -> ControlPattern+decayrecv busid = pI "^decay" busid++-- | +degree :: Pattern Double -> ControlPattern+degree = pF "degree"+degreeTake :: String -> [Double] -> ControlPattern+degreeTake name xs = pStateListF "degree" name xs+degreeCount :: String -> ControlPattern+degreeCount name = pStateF "degree" name (maybe 0 (+1))+degreeCountTo :: String -> Pattern Double -> Pattern ValueMap+degreeCountTo name ipat = innerJoin $ (\i -> pStateF "degree" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++degreebus :: Pattern Int -> Pattern Double -> ControlPattern+degreebus busid pat = (pF "degree" pat) # (pI "^degree" busid)+degreerecv :: Pattern Int -> ControlPattern+degreerecv busid = pI "^degree" busid++-- | a pattern of numbers from 0 to 1. Sets the level of the delay signal.+delay :: Pattern Double -> ControlPattern+delay = pF "delay"+delayTake :: String -> [Double] -> ControlPattern+delayTake name xs = pStateListF "delay" name xs+delayCount :: String -> ControlPattern+delayCount name = pStateF "delay" name (maybe 0 (+1))+delayCountTo :: String -> Pattern Double -> Pattern ValueMap+delayCountTo name ipat = innerJoin $ (\i -> pStateF "delay" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++delaybus :: Pattern Int -> Pattern Double -> ControlPattern+delaybus busid pat = (pF "delay" pat) # (pI "^delay" busid)+delayrecv :: Pattern Int -> ControlPattern+delayrecv busid = pI "^delay" busid++-- | a pattern of numbers from 0 to 1. Sets the amount of delay feedback.+delayfeedback :: Pattern Double -> ControlPattern+delayfeedback = pF "delayfeedback"+delayfeedbackTake :: String -> [Double] -> ControlPattern+delayfeedbackTake name xs = pStateListF "delayfeedback" name xs+delayfeedbackCount :: String -> ControlPattern+delayfeedbackCount name = pStateF "delayfeedback" name (maybe 0 (+1))+delayfeedbackCountTo :: String -> Pattern Double -> Pattern ValueMap+delayfeedbackCountTo name ipat = innerJoin $ (\i -> pStateF "delayfeedback" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++delayfeedbackbus :: Pattern Int -> Pattern Double -> ControlPattern+delayfeedbackbus busid pat = (pF "delayfeedback" pat) # (pI "^delayfeedback" busid)+delayfeedbackrecv :: Pattern Int -> ControlPattern+delayfeedbackrecv busid = pI "^delayfeedback" busid++-- | a pattern of numbers from 0 to 1. Sets the length of the delay.+delaytime :: Pattern Double -> ControlPattern+delaytime = pF "delaytime"+delaytimeTake :: String -> [Double] -> ControlPattern+delaytimeTake name xs = pStateListF "delaytime" name xs+delaytimeCount :: String -> ControlPattern+delaytimeCount name = pStateF "delaytime" name (maybe 0 (+1))+delaytimeCountTo :: String -> Pattern Double -> Pattern ValueMap+delaytimeCountTo name ipat = innerJoin $ (\i -> pStateF "delaytime" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++delaytimebus :: Pattern Int -> Pattern Double -> ControlPattern+delaytimebus busid pat = (pF "delaytime" pat) # (pI "^delaytime" busid)+delaytimerecv :: Pattern Int -> ControlPattern+delaytimerecv busid = pI "^delaytime" busid++-- | +detune :: Pattern Double -> ControlPattern+detune = pF "detune"+detuneTake :: String -> [Double] -> ControlPattern+detuneTake name xs = pStateListF "detune" name xs+detuneCount :: String -> ControlPattern+detuneCount name = pStateF "detune" name (maybe 0 (+1))+detuneCountTo :: String -> Pattern Double -> Pattern ValueMap+detuneCountTo name ipat = innerJoin $ (\i -> pStateF "detune" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++detunebus :: Pattern Int -> Pattern Double -> ControlPattern+detunebus busid pat = (pF "detune" pat) # (pI "^detune" busid)+detunerecv :: Pattern Int -> ControlPattern+detunerecv busid = pI "^detune" busid++-- | noisy fuzzy distortion+distort :: Pattern Double -> ControlPattern+distort = pF "distort"+distortTake :: String -> [Double] -> ControlPattern+distortTake name xs = pStateListF "distort" name xs+distortCount :: String -> ControlPattern+distortCount name = pStateF "distort" name (maybe 0 (+1))+distortCountTo :: String -> Pattern Double -> Pattern ValueMap+distortCountTo name ipat = innerJoin $ (\i -> pStateF "distort" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++distortbus :: Pattern Int -> Pattern Double -> ControlPattern+distortbus busid pat = (pF "distort" pat) # (pI "^distort" busid)+distortrecv :: Pattern Int -> ControlPattern+distortrecv busid = pI "^distort" busid++-- | DJ filter, below 0.5 is low pass filter, above is high pass filter.+djf :: Pattern Double -> ControlPattern+djf = pF "djf"+djfTake :: String -> [Double] -> ControlPattern+djfTake name xs = pStateListF "djf" name xs+djfCount :: String -> ControlPattern+djfCount name = pStateF "djf" name (maybe 0 (+1))+djfCountTo :: String -> Pattern Double -> Pattern ValueMap+djfCountTo name ipat = innerJoin $ (\i -> pStateF "djf" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++djfbus :: Pattern Int -> Pattern Double -> ControlPattern+djfbus busid pat = (pF "djf" pat) # (pI "^djf" busid)+djfrecv :: Pattern Int -> ControlPattern+djfrecv busid = pI "^djf" busid++-- | when set to `1` will disable all reverb for this pattern. See `room` and `size` for more information about reverb.+dry :: Pattern Double -> ControlPattern+dry = pF "dry"+dryTake :: String -> [Double] -> ControlPattern+dryTake name xs = pStateListF "dry" name xs+dryCount :: String -> ControlPattern+dryCount name = pStateF "dry" name (maybe 0 (+1))+dryCountTo :: String -> Pattern Double -> Pattern ValueMap+dryCountTo name ipat = innerJoin $ (\i -> pStateF "dry" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++drybus :: Pattern Int -> Pattern Double -> ControlPattern+drybus busid pat = (pF "dry" pat) # (pI "^dry" busid)+dryrecv :: Pattern Int -> ControlPattern+dryrecv busid = pI "^dry" busid++-- | +dur :: Pattern Double -> ControlPattern+dur = pF "dur"+durTake :: String -> [Double] -> ControlPattern+durTake name xs = pStateListF "dur" name xs+durCount :: String -> ControlPattern+durCount name = pStateF "dur" name (maybe 0 (+1))+durCountTo :: String -> Pattern Double -> Pattern ValueMap+durCountTo name ipat = innerJoin $ (\i -> pStateF "dur" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++durbus :: Pattern Int -> Pattern Double -> ControlPattern+durbus busid pat = (pF "dur" pat) # (pI "^dur" busid)+durrecv :: Pattern Int -> ControlPattern+durrecv busid = pI "^dur" busid++-- | the same as `begin`, but cuts the end off samples, shortening them; e.g. `0.75` to cut off the last quarter of each sample.+end :: Pattern Double -> ControlPattern+end = pF "end"+endTake :: String -> [Double] -> ControlPattern+endTake name xs = pStateListF "end" name xs+endCount :: String -> ControlPattern+endCount name = pStateF "end" name (maybe 0 (+1))+endCountTo :: String -> Pattern Double -> Pattern ValueMap+endCountTo name ipat = innerJoin $ (\i -> pStateF "end" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++endbus :: Pattern Int -> Pattern Double -> ControlPattern+endbus _ _ = error $ "Control parameter 'end' can't be sent to a bus."++-- | Spectral enhance+enhance :: Pattern Double -> ControlPattern+enhance = pF "enhance"+enhanceTake :: String -> [Double] -> ControlPattern+enhanceTake name xs = pStateListF "enhance" name xs+enhanceCount :: String -> ControlPattern+enhanceCount name = pStateF "enhance" name (maybe 0 (+1))+enhanceCountTo :: String -> Pattern Double -> Pattern ValueMap+enhanceCountTo name ipat = innerJoin $ (\i -> pStateF "enhance" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++enhancebus :: Pattern Int -> Pattern Double -> ControlPattern+enhancebus busid pat = (pF "enhance" pat) # (pI "^enhance" busid)+enhancerecv :: Pattern Int -> ControlPattern+enhancerecv busid = pI "^enhance" busid++-- | +expression :: Pattern Double -> ControlPattern+expression = pF "expression"+expressionTake :: String -> [Double] -> ControlPattern+expressionTake name xs = pStateListF "expression" name xs+expressionCount :: String -> ControlPattern+expressionCount name = pStateF "expression" name (maybe 0 (+1))+expressionCountTo :: String -> Pattern Double -> Pattern ValueMap+expressionCountTo name ipat = innerJoin $ (\i -> pStateF "expression" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++expressionbus :: Pattern Int -> Pattern Double -> ControlPattern+expressionbus busid pat = (pF "expression" pat) # (pI "^expression" busid)+expressionrecv :: Pattern Int -> ControlPattern+expressionrecv busid = pI "^expression" busid++-- | +frameRate :: Pattern Double -> ControlPattern+frameRate = pF "frameRate"+frameRateTake :: String -> [Double] -> ControlPattern+frameRateTake name xs = pStateListF "frameRate" name xs+frameRateCount :: String -> ControlPattern+frameRateCount name = pStateF "frameRate" name (maybe 0 (+1))+frameRateCountTo :: String -> Pattern Double -> Pattern ValueMap+frameRateCountTo name ipat = innerJoin $ (\i -> pStateF "frameRate" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++frameRatebus :: Pattern Int -> Pattern Double -> ControlPattern+frameRatebus busid pat = (pF "frameRate" pat) # (pI "^frameRate" busid)+frameRaterecv :: Pattern Int -> ControlPattern+frameRaterecv busid = pI "^frameRate" busid++-- | +frames :: Pattern Double -> ControlPattern+frames = pF "frames"+framesTake :: String -> [Double] -> ControlPattern+framesTake name xs = pStateListF "frames" name xs+framesCount :: String -> ControlPattern+framesCount name = pStateF "frames" name (maybe 0 (+1))+framesCountTo :: String -> Pattern Double -> Pattern ValueMap+framesCountTo name ipat = innerJoin $ (\i -> pStateF "frames" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++framesbus :: Pattern Int -> Pattern Double -> ControlPattern+framesbus busid pat = (pF "frames" pat) # (pI "^frames" busid)+framesrecv :: Pattern Int -> ControlPattern+framesrecv busid = pI "^frames" busid++-- | Spectral freeze+freeze :: Pattern Double -> ControlPattern+freeze = pF "freeze"+freezeTake :: String -> [Double] -> ControlPattern+freezeTake name xs = pStateListF "freeze" name xs+freezeCount :: String -> ControlPattern+freezeCount name = pStateF "freeze" name (maybe 0 (+1))+freezeCountTo :: String -> Pattern Double -> Pattern ValueMap+freezeCountTo name ipat = innerJoin $ (\i -> pStateF "freeze" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++freezebus :: Pattern Int -> Pattern Double -> ControlPattern+freezebus busid pat = (pF "freeze" pat) # (pI "^freeze" busid)+freezerecv :: Pattern Int -> ControlPattern+freezerecv busid = pI "^freeze" busid++-- | +freq :: Pattern Double -> ControlPattern+freq = pF "freq"+freqTake :: String -> [Double] -> ControlPattern+freqTake name xs = pStateListF "freq" name xs+freqCount :: String -> ControlPattern+freqCount name = pStateF "freq" name (maybe 0 (+1))+freqCountTo :: String -> Pattern Double -> Pattern ValueMap+freqCountTo name ipat = innerJoin $ (\i -> pStateF "freq" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++freqbus :: Pattern Int -> Pattern Double -> ControlPattern+freqbus busid pat = (pF "freq" pat) # (pI "^freq" busid)+freqrecv :: Pattern Int -> ControlPattern+freqrecv busid = pI "^freq" busid++-- | for internal sound routing+from :: Pattern Double -> ControlPattern+from = pF "from"+fromTake :: String -> [Double] -> ControlPattern+fromTake name xs = pStateListF "from" name xs+fromCount :: String -> ControlPattern+fromCount name = pStateF "from" name (maybe 0 (+1))+fromCountTo :: String -> Pattern Double -> Pattern ValueMap+fromCountTo name ipat = innerJoin $ (\i -> pStateF "from" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++frombus :: Pattern Int -> Pattern Double -> ControlPattern+frombus busid pat = (pF "from" pat) # (pI "^from" busid)+fromrecv :: Pattern Int -> ControlPattern+fromrecv busid = pI "^from" busid++-- | frequency shifter+fshift :: Pattern Double -> ControlPattern+fshift = pF "fshift"+fshiftTake :: String -> [Double] -> ControlPattern+fshiftTake name xs = pStateListF "fshift" name xs+fshiftCount :: String -> ControlPattern+fshiftCount name = pStateF "fshift" name (maybe 0 (+1))+fshiftCountTo :: String -> Pattern Double -> Pattern ValueMap+fshiftCountTo name ipat = innerJoin $ (\i -> pStateF "fshift" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++fshiftbus :: Pattern Int -> Pattern Double -> ControlPattern+fshiftbus busid pat = (pF "fshift" pat) # (pI "^fshift" busid)+fshiftrecv :: Pattern Int -> ControlPattern+fshiftrecv busid = pI "^fshift" busid++-- | frequency shifter+fshiftnote :: Pattern Double -> ControlPattern+fshiftnote = pF "fshiftnote"+fshiftnoteTake :: String -> [Double] -> ControlPattern+fshiftnoteTake name xs = pStateListF "fshiftnote" name xs+fshiftnoteCount :: String -> ControlPattern+fshiftnoteCount name = pStateF "fshiftnote" name (maybe 0 (+1))+fshiftnoteCountTo :: String -> Pattern Double -> Pattern ValueMap+fshiftnoteCountTo name ipat = innerJoin $ (\i -> pStateF "fshiftnote" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++fshiftnotebus :: Pattern Int -> Pattern Double -> ControlPattern+fshiftnotebus busid pat = (pF "fshiftnote" pat) # (pI "^fshiftnote" busid)+fshiftnoterecv :: Pattern Int -> ControlPattern+fshiftnoterecv busid = pI "^fshiftnote" busid++-- | frequency shifter+fshiftphase :: Pattern Double -> ControlPattern+fshiftphase = pF "fshiftphase"+fshiftphaseTake :: String -> [Double] -> ControlPattern+fshiftphaseTake name xs = pStateListF "fshiftphase" name xs+fshiftphaseCount :: String -> ControlPattern+fshiftphaseCount name = pStateF "fshiftphase" name (maybe 0 (+1))+fshiftphaseCountTo :: String -> Pattern Double -> Pattern ValueMap+fshiftphaseCountTo name ipat = innerJoin $ (\i -> pStateF "fshiftphase" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++fshiftphasebus :: Pattern Int -> Pattern Double -> ControlPattern+fshiftphasebus busid pat = (pF "fshiftphase" pat) # (pI "^fshiftphase" busid)+fshiftphaserecv :: Pattern Int -> ControlPattern+fshiftphaserecv busid = pI "^fshiftphase" busid++-- | a pattern of numbers that specify volume. Values less than 1 make the sound quieter. Values greater than 1 make the sound louder. For the linear equivalent, see @amp@.+gain :: Pattern Double -> ControlPattern+gain = pF "gain"+gainTake :: String -> [Double] -> ControlPattern+gainTake name xs = pStateListF "gain" name xs+gainCount :: String -> ControlPattern+gainCount name = pStateF "gain" name (maybe 0 (+1))+gainCountTo :: String -> Pattern Double -> Pattern ValueMap+gainCountTo name ipat = innerJoin $ (\i -> pStateF "gain" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++gainbus :: Pattern Int -> Pattern Double -> ControlPattern+gainbus _ _ = error $ "Control parameter 'gain' can't be sent to a bus."++-- | +gate :: Pattern Double -> ControlPattern+gate = pF "gate"+gateTake :: String -> [Double] -> ControlPattern+gateTake name xs = pStateListF "gate" name xs+gateCount :: String -> ControlPattern+gateCount name = pStateF "gate" name (maybe 0 (+1))+gateCountTo :: String -> Pattern Double -> Pattern ValueMap+gateCountTo name ipat = innerJoin $ (\i -> pStateF "gate" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++gatebus :: Pattern Int -> Pattern Double -> ControlPattern+gatebus busid pat = (pF "gate" pat) # (pI "^gate" busid)+gaterecv :: Pattern Int -> ControlPattern+gaterecv busid = pI "^gate" busid++-- | +harmonic :: Pattern Double -> ControlPattern+harmonic = pF "harmonic"+harmonicTake :: String -> [Double] -> ControlPattern+harmonicTake name xs = pStateListF "harmonic" name xs+harmonicCount :: String -> ControlPattern+harmonicCount name = pStateF "harmonic" name (maybe 0 (+1))+harmonicCountTo :: String -> Pattern Double -> Pattern ValueMap+harmonicCountTo name ipat = innerJoin $ (\i -> pStateF "harmonic" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++harmonicbus :: Pattern Int -> Pattern Double -> ControlPattern+harmonicbus busid pat = (pF "harmonic" pat) # (pI "^harmonic" busid)+harmonicrecv :: Pattern Int -> ControlPattern+harmonicrecv busid = pI "^harmonic" busid++-- | +hatgrain :: Pattern Double -> ControlPattern+hatgrain = pF "hatgrain"+hatgrainTake :: String -> [Double] -> ControlPattern+hatgrainTake name xs = pStateListF "hatgrain" name xs+hatgrainCount :: String -> ControlPattern+hatgrainCount name = pStateF "hatgrain" name (maybe 0 (+1))+hatgrainCountTo :: String -> Pattern Double -> Pattern ValueMap+hatgrainCountTo name ipat = innerJoin $ (\i -> pStateF "hatgrain" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++hatgrainbus :: Pattern Int -> Pattern Double -> ControlPattern+hatgrainbus busid pat = (pF "hatgrain" pat) # (pI "^hatgrain" busid)+hatgrainrecv :: Pattern Int -> ControlPattern+hatgrainrecv busid = pI "^hatgrain" busid++-- | High pass sort of spectral filter+hbrick :: Pattern Double -> ControlPattern+hbrick = pF "hbrick"+hbrickTake :: String -> [Double] -> ControlPattern+hbrickTake name xs = pStateListF "hbrick" name xs+hbrickCount :: String -> ControlPattern+hbrickCount name = pStateF "hbrick" name (maybe 0 (+1))+hbrickCountTo :: String -> Pattern Double -> Pattern ValueMap+hbrickCountTo name ipat = innerJoin $ (\i -> pStateF "hbrick" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++hbrickbus :: Pattern Int -> Pattern Double -> ControlPattern+hbrickbus busid pat = (pF "hbrick" pat) # (pI "^hbrick" busid)+hbrickrecv :: Pattern Int -> ControlPattern+hbrickrecv busid = pI "^hbrick" busid++-- | a pattern of numbers from 0 to 1. Applies the cutoff frequency of the high-pass filter. Also has alias @hpf@+hcutoff :: Pattern Double -> ControlPattern+hcutoff = pF "hcutoff"+hcutoffTake :: String -> [Double] -> ControlPattern+hcutoffTake name xs = pStateListF "hcutoff" name xs+hcutoffCount :: String -> ControlPattern+hcutoffCount name = pStateF "hcutoff" name (maybe 0 (+1))+hcutoffCountTo :: String -> Pattern Double -> Pattern ValueMap+hcutoffCountTo name ipat = innerJoin $ (\i -> pStateF "hcutoff" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++hcutoffbus :: Pattern Int -> Pattern Double -> ControlPattern+hcutoffbus busid pat = (pF "hcutoff" pat) # (pI "^hcutoff" busid)+hcutoffrecv :: Pattern Int -> ControlPattern+hcutoffrecv busid = pI "^hcutoff" busid++-- | 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 -> ControlPattern+hold = pF "hold"+holdTake :: String -> [Double] -> ControlPattern+holdTake name xs = pStateListF "hold" name xs+holdCount :: String -> ControlPattern+holdCount name = pStateF "hold" name (maybe 0 (+1))+holdCountTo :: String -> Pattern Double -> Pattern ValueMap+holdCountTo name ipat = innerJoin $ (\i -> pStateF "hold" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++holdbus :: Pattern Int -> Pattern Double -> ControlPattern+holdbus busid pat = (pF "hold" pat) # (pI "^hold" busid)+holdrecv :: Pattern Int -> ControlPattern+holdrecv busid = pI "^hold" busid++-- | +hours :: Pattern Double -> ControlPattern+hours = pF "hours"+hoursTake :: String -> [Double] -> ControlPattern+hoursTake name xs = pStateListF "hours" name xs+hoursCount :: String -> ControlPattern+hoursCount name = pStateF "hours" name (maybe 0 (+1))+hoursCountTo :: String -> Pattern Double -> Pattern ValueMap+hoursCountTo name ipat = innerJoin $ (\i -> pStateF "hours" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++hoursbus :: Pattern Int -> Pattern Double -> ControlPattern+hoursbus busid pat = (pF "hours" pat) # (pI "^hours" busid)+hoursrecv :: Pattern Int -> ControlPattern+hoursrecv busid = pI "^hours" busid++-- | a pattern of numbers from 0 to 1. Applies the resonance of the high-pass filter. Has alias @hpq@+hresonance :: Pattern Double -> ControlPattern+hresonance = pF "hresonance"+hresonanceTake :: String -> [Double] -> ControlPattern+hresonanceTake name xs = pStateListF "hresonance" name xs+hresonanceCount :: String -> ControlPattern+hresonanceCount name = pStateF "hresonance" name (maybe 0 (+1))+hresonanceCountTo :: String -> Pattern Double -> Pattern ValueMap+hresonanceCountTo name ipat = innerJoin $ (\i -> pStateF "hresonance" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++hresonancebus :: Pattern Int -> Pattern Double -> ControlPattern+hresonancebus busid pat = (pF "hresonance" pat) # (pI "^hresonance" busid)+hresonancerecv :: Pattern Int -> ControlPattern+hresonancerecv busid = pI "^hresonance" busid++-- | +imag :: Pattern Double -> ControlPattern+imag = pF "imag"+imagTake :: String -> [Double] -> ControlPattern+imagTake name xs = pStateListF "imag" name xs+imagCount :: String -> ControlPattern+imagCount name = pStateF "imag" name (maybe 0 (+1))+imagCountTo :: String -> Pattern Double -> Pattern ValueMap+imagCountTo name ipat = innerJoin $ (\i -> pStateF "imag" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++imagbus :: Pattern Int -> Pattern Double -> ControlPattern+imagbus busid pat = (pF "imag" pat) # (pI "^imag" busid)+imagrecv :: Pattern Int -> ControlPattern+imagrecv busid = pI "^imag" busid++-- | +kcutoff :: Pattern Double -> ControlPattern+kcutoff = pF "kcutoff"+kcutoffTake :: String -> [Double] -> ControlPattern+kcutoffTake name xs = pStateListF "kcutoff" name xs+kcutoffCount :: String -> ControlPattern+kcutoffCount name = pStateF "kcutoff" name (maybe 0 (+1))+kcutoffCountTo :: String -> Pattern Double -> Pattern ValueMap+kcutoffCountTo name ipat = innerJoin $ (\i -> pStateF "kcutoff" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++kcutoffbus :: Pattern Int -> Pattern Double -> ControlPattern+kcutoffbus busid pat = (pF "kcutoff" pat) # (pI "^kcutoff" busid)+kcutoffrecv :: Pattern Int -> ControlPattern+kcutoffrecv busid = pI "^kcutoff" busid++-- | shape/bass enhancer+krush :: Pattern Double -> ControlPattern+krush = pF "krush"+krushTake :: String -> [Double] -> ControlPattern+krushTake name xs = pStateListF "krush" name xs+krushCount :: String -> ControlPattern+krushCount name = pStateF "krush" name (maybe 0 (+1))+krushCountTo :: String -> Pattern Double -> Pattern ValueMap+krushCountTo name ipat = innerJoin $ (\i -> pStateF "krush" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++krushbus :: Pattern Int -> Pattern Double -> ControlPattern+krushbus busid pat = (pF "krush" pat) # (pI "^krush" busid)+krushrecv :: Pattern Int -> ControlPattern+krushrecv busid = pI "^krush" busid++-- | +lagogo :: Pattern Double -> ControlPattern+lagogo = pF "lagogo"+lagogoTake :: String -> [Double] -> ControlPattern+lagogoTake name xs = pStateListF "lagogo" name xs+lagogoCount :: String -> ControlPattern+lagogoCount name = pStateF "lagogo" name (maybe 0 (+1))+lagogoCountTo :: String -> Pattern Double -> Pattern ValueMap+lagogoCountTo name ipat = innerJoin $ (\i -> pStateF "lagogo" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lagogobus :: Pattern Int -> Pattern Double -> ControlPattern+lagogobus busid pat = (pF "lagogo" pat) # (pI "^lagogo" busid)+lagogorecv :: Pattern Int -> ControlPattern+lagogorecv busid = pI "^lagogo" busid++-- | Low pass sort of spectral filter+lbrick :: Pattern Double -> ControlPattern+lbrick = pF "lbrick"+lbrickTake :: String -> [Double] -> ControlPattern+lbrickTake name xs = pStateListF "lbrick" name xs+lbrickCount :: String -> ControlPattern+lbrickCount name = pStateF "lbrick" name (maybe 0 (+1))+lbrickCountTo :: String -> Pattern Double -> Pattern ValueMap+lbrickCountTo name ipat = innerJoin $ (\i -> pStateF "lbrick" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lbrickbus :: Pattern Int -> Pattern Double -> ControlPattern+lbrickbus busid pat = (pF "lbrick" pat) # (pI "^lbrick" busid)+lbrickrecv :: Pattern Int -> ControlPattern+lbrickrecv busid = pI "^lbrick" busid++-- | +lclap :: Pattern Double -> ControlPattern+lclap = pF "lclap"+lclapTake :: String -> [Double] -> ControlPattern+lclapTake name xs = pStateListF "lclap" name xs+lclapCount :: String -> ControlPattern+lclapCount name = pStateF "lclap" name (maybe 0 (+1))+lclapCountTo :: String -> Pattern Double -> Pattern ValueMap+lclapCountTo name ipat = innerJoin $ (\i -> pStateF "lclap" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lclapbus :: Pattern Int -> Pattern Double -> ControlPattern+lclapbus busid pat = (pF "lclap" pat) # (pI "^lclap" busid)+lclaprecv :: Pattern Int -> ControlPattern+lclaprecv busid = pI "^lclap" busid++-- | +lclaves :: Pattern Double -> ControlPattern+lclaves = pF "lclaves"+lclavesTake :: String -> [Double] -> ControlPattern+lclavesTake name xs = pStateListF "lclaves" name xs+lclavesCount :: String -> ControlPattern+lclavesCount name = pStateF "lclaves" name (maybe 0 (+1))+lclavesCountTo :: String -> Pattern Double -> Pattern ValueMap+lclavesCountTo name ipat = innerJoin $ (\i -> pStateF "lclaves" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lclavesbus :: Pattern Int -> Pattern Double -> ControlPattern+lclavesbus busid pat = (pF "lclaves" pat) # (pI "^lclaves" busid)+lclavesrecv :: Pattern Int -> ControlPattern+lclavesrecv busid = pI "^lclaves" busid++-- | +lclhat :: Pattern Double -> ControlPattern+lclhat = pF "lclhat"+lclhatTake :: String -> [Double] -> ControlPattern+lclhatTake name xs = pStateListF "lclhat" name xs+lclhatCount :: String -> ControlPattern+lclhatCount name = pStateF "lclhat" name (maybe 0 (+1))+lclhatCountTo :: String -> Pattern Double -> Pattern ValueMap+lclhatCountTo name ipat = innerJoin $ (\i -> pStateF "lclhat" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lclhatbus :: Pattern Int -> Pattern Double -> ControlPattern+lclhatbus busid pat = (pF "lclhat" pat) # (pI "^lclhat" busid)+lclhatrecv :: Pattern Int -> ControlPattern+lclhatrecv busid = pI "^lclhat" busid++-- | +lcrash :: Pattern Double -> ControlPattern+lcrash = pF "lcrash"+lcrashTake :: String -> [Double] -> ControlPattern+lcrashTake name xs = pStateListF "lcrash" name xs+lcrashCount :: String -> ControlPattern+lcrashCount name = pStateF "lcrash" name (maybe 0 (+1))+lcrashCountTo :: String -> Pattern Double -> Pattern ValueMap+lcrashCountTo name ipat = innerJoin $ (\i -> pStateF "lcrash" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lcrashbus :: Pattern Int -> Pattern Double -> ControlPattern+lcrashbus busid pat = (pF "lcrash" pat) # (pI "^lcrash" busid)+lcrashrecv :: Pattern Int -> ControlPattern+lcrashrecv busid = pI "^lcrash" busid++-- | controls the amount of overlap between two adjacent sounds+legato :: Pattern Double -> ControlPattern+legato = pF "legato"+legatoTake :: String -> [Double] -> ControlPattern+legatoTake name xs = pStateListF "legato" name xs+legatoCount :: String -> ControlPattern+legatoCount name = pStateF "legato" name (maybe 0 (+1))+legatoCountTo :: String -> Pattern Double -> Pattern ValueMap+legatoCountTo name ipat = innerJoin $ (\i -> pStateF "legato" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++legatobus :: Pattern Int -> Pattern Double -> ControlPattern+legatobus _ _ = error $ "Control parameter 'legato' can't be sent to a bus."++-- | +leslie :: Pattern Double -> ControlPattern+leslie = pF "leslie"+leslieTake :: String -> [Double] -> ControlPattern+leslieTake name xs = pStateListF "leslie" name xs+leslieCount :: String -> ControlPattern+leslieCount name = pStateF "leslie" name (maybe 0 (+1))+leslieCountTo :: String -> Pattern Double -> Pattern ValueMap+leslieCountTo name ipat = innerJoin $ (\i -> pStateF "leslie" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lesliebus :: Pattern Int -> Pattern Double -> ControlPattern+lesliebus busid pat = (pF "leslie" pat) # (pI "^leslie" busid)+leslierecv :: Pattern Int -> ControlPattern+leslierecv busid = pI "^leslie" busid++-- | +lfo :: Pattern Double -> ControlPattern+lfo = pF "lfo"+lfoTake :: String -> [Double] -> ControlPattern+lfoTake name xs = pStateListF "lfo" name xs+lfoCount :: String -> ControlPattern+lfoCount name = pStateF "lfo" name (maybe 0 (+1))+lfoCountTo :: String -> Pattern Double -> Pattern ValueMap+lfoCountTo name ipat = innerJoin $ (\i -> pStateF "lfo" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lfobus :: Pattern Int -> Pattern Double -> ControlPattern+lfobus busid pat = (pF "lfo" pat) # (pI "^lfo" busid)+lforecv :: Pattern Int -> ControlPattern+lforecv busid = pI "^lfo" busid++-- | +lfocutoffint :: Pattern Double -> ControlPattern+lfocutoffint = pF "lfocutoffint"+lfocutoffintTake :: String -> [Double] -> ControlPattern+lfocutoffintTake name xs = pStateListF "lfocutoffint" name xs+lfocutoffintCount :: String -> ControlPattern+lfocutoffintCount name = pStateF "lfocutoffint" name (maybe 0 (+1))+lfocutoffintCountTo :: String -> Pattern Double -> Pattern ValueMap+lfocutoffintCountTo name ipat = innerJoin $ (\i -> pStateF "lfocutoffint" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lfocutoffintbus :: Pattern Int -> Pattern Double -> ControlPattern+lfocutoffintbus busid pat = (pF "lfocutoffint" pat) # (pI "^lfocutoffint" busid)+lfocutoffintrecv :: Pattern Int -> ControlPattern+lfocutoffintrecv busid = pI "^lfocutoffint" busid++-- | +lfodelay :: Pattern Double -> ControlPattern+lfodelay = pF "lfodelay"+lfodelayTake :: String -> [Double] -> ControlPattern+lfodelayTake name xs = pStateListF "lfodelay" name xs+lfodelayCount :: String -> ControlPattern+lfodelayCount name = pStateF "lfodelay" name (maybe 0 (+1))+lfodelayCountTo :: String -> Pattern Double -> Pattern ValueMap+lfodelayCountTo name ipat = innerJoin $ (\i -> pStateF "lfodelay" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lfodelaybus :: Pattern Int -> Pattern Double -> ControlPattern+lfodelaybus busid pat = (pF "lfodelay" pat) # (pI "^lfodelay" busid)+lfodelayrecv :: Pattern Int -> ControlPattern+lfodelayrecv busid = pI "^lfodelay" busid++-- | +lfoint :: Pattern Double -> ControlPattern+lfoint = pF "lfoint"+lfointTake :: String -> [Double] -> ControlPattern+lfointTake name xs = pStateListF "lfoint" name xs+lfointCount :: String -> ControlPattern+lfointCount name = pStateF "lfoint" name (maybe 0 (+1))+lfointCountTo :: String -> Pattern Double -> Pattern ValueMap+lfointCountTo name ipat = innerJoin $ (\i -> pStateF "lfoint" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lfointbus :: Pattern Int -> Pattern Double -> ControlPattern+lfointbus busid pat = (pF "lfoint" pat) # (pI "^lfoint" busid)+lfointrecv :: Pattern Int -> ControlPattern+lfointrecv busid = pI "^lfoint" busid++-- | +lfopitchint :: Pattern Double -> ControlPattern+lfopitchint = pF "lfopitchint"+lfopitchintTake :: String -> [Double] -> ControlPattern+lfopitchintTake name xs = pStateListF "lfopitchint" name xs+lfopitchintCount :: String -> ControlPattern+lfopitchintCount name = pStateF "lfopitchint" name (maybe 0 (+1))+lfopitchintCountTo :: String -> Pattern Double -> Pattern ValueMap+lfopitchintCountTo name ipat = innerJoin $ (\i -> pStateF "lfopitchint" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lfopitchintbus :: Pattern Int -> Pattern Double -> ControlPattern+lfopitchintbus busid pat = (pF "lfopitchint" pat) # (pI "^lfopitchint" busid)+lfopitchintrecv :: Pattern Int -> ControlPattern+lfopitchintrecv busid = pI "^lfopitchint" busid++-- | +lfoshape :: Pattern Double -> ControlPattern+lfoshape = pF "lfoshape"+lfoshapeTake :: String -> [Double] -> ControlPattern+lfoshapeTake name xs = pStateListF "lfoshape" name xs+lfoshapeCount :: String -> ControlPattern+lfoshapeCount name = pStateF "lfoshape" name (maybe 0 (+1))+lfoshapeCountTo :: String -> Pattern Double -> Pattern ValueMap+lfoshapeCountTo name ipat = innerJoin $ (\i -> pStateF "lfoshape" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lfoshapebus :: Pattern Int -> Pattern Double -> ControlPattern+lfoshapebus busid pat = (pF "lfoshape" pat) # (pI "^lfoshape" busid)+lfoshaperecv :: Pattern Int -> ControlPattern+lfoshaperecv busid = pI "^lfoshape" busid++-- | +lfosync :: Pattern Double -> ControlPattern+lfosync = pF "lfosync"+lfosyncTake :: String -> [Double] -> ControlPattern+lfosyncTake name xs = pStateListF "lfosync" name xs+lfosyncCount :: String -> ControlPattern+lfosyncCount name = pStateF "lfosync" name (maybe 0 (+1))+lfosyncCountTo :: String -> Pattern Double -> Pattern ValueMap+lfosyncCountTo name ipat = innerJoin $ (\i -> pStateF "lfosync" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lfosyncbus :: Pattern Int -> Pattern Double -> ControlPattern+lfosyncbus busid pat = (pF "lfosync" pat) # (pI "^lfosync" busid)+lfosyncrecv :: Pattern Int -> ControlPattern+lfosyncrecv busid = pI "^lfosync" busid++-- | +lhitom :: Pattern Double -> ControlPattern+lhitom = pF "lhitom"+lhitomTake :: String -> [Double] -> ControlPattern+lhitomTake name xs = pStateListF "lhitom" name xs+lhitomCount :: String -> ControlPattern+lhitomCount name = pStateF "lhitom" name (maybe 0 (+1))+lhitomCountTo :: String -> Pattern Double -> Pattern ValueMap+lhitomCountTo name ipat = innerJoin $ (\i -> pStateF "lhitom" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lhitombus :: Pattern Int -> Pattern Double -> ControlPattern+lhitombus busid pat = (pF "lhitom" pat) # (pI "^lhitom" busid)+lhitomrecv :: Pattern Int -> ControlPattern+lhitomrecv busid = pI "^lhitom" busid++-- | +lkick :: Pattern Double -> ControlPattern+lkick = pF "lkick"+lkickTake :: String -> [Double] -> ControlPattern+lkickTake name xs = pStateListF "lkick" name xs+lkickCount :: String -> ControlPattern+lkickCount name = pStateF "lkick" name (maybe 0 (+1))+lkickCountTo :: String -> Pattern Double -> Pattern ValueMap+lkickCountTo name ipat = innerJoin $ (\i -> pStateF "lkick" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lkickbus :: Pattern Int -> Pattern Double -> ControlPattern+lkickbus busid pat = (pF "lkick" pat) # (pI "^lkick" busid)+lkickrecv :: Pattern Int -> ControlPattern+lkickrecv busid = pI "^lkick" busid++-- | +llotom :: Pattern Double -> ControlPattern+llotom = pF "llotom"+llotomTake :: String -> [Double] -> ControlPattern+llotomTake name xs = pStateListF "llotom" name xs+llotomCount :: String -> ControlPattern+llotomCount name = pStateF "llotom" name (maybe 0 (+1))+llotomCountTo :: String -> Pattern Double -> Pattern ValueMap+llotomCountTo name ipat = innerJoin $ (\i -> pStateF "llotom" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++llotombus :: Pattern Int -> Pattern Double -> ControlPattern+llotombus busid pat = (pF "llotom" pat) # (pI "^llotom" busid)+llotomrecv :: Pattern Int -> ControlPattern+llotomrecv busid = pI "^llotom" busid++-- | 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 -> ControlPattern+lock = pF "lock"+lockTake :: String -> [Double] -> ControlPattern+lockTake name xs = pStateListF "lock" name xs+lockCount :: String -> ControlPattern+lockCount name = pStateF "lock" name (maybe 0 (+1))+lockCountTo :: String -> Pattern Double -> Pattern ValueMap+lockCountTo name ipat = innerJoin $ (\i -> pStateF "lock" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lockbus :: Pattern Int -> Pattern Double -> ControlPattern+lockbus busid pat = (pF "lock" pat) # (pI "^lock" busid)+lockrecv :: Pattern Int -> ControlPattern+lockrecv busid = pI "^lock" busid++-- | loops the sample (from `begin` to `end`) the specified number of times.+loop :: Pattern Double -> ControlPattern+loop = pF "loop"+loopTake :: String -> [Double] -> ControlPattern+loopTake name xs = pStateListF "loop" name xs+loopCount :: String -> ControlPattern+loopCount name = pStateF "loop" name (maybe 0 (+1))+loopCountTo :: String -> Pattern Double -> Pattern ValueMap+loopCountTo name ipat = innerJoin $ (\i -> pStateF "loop" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++loopbus :: Pattern Int -> Pattern Double -> ControlPattern+loopbus _ _ = error $ "Control parameter 'loop' can't be sent to a bus."++-- | +lophat :: Pattern Double -> ControlPattern+lophat = pF "lophat"+lophatTake :: String -> [Double] -> ControlPattern+lophatTake name xs = pStateListF "lophat" name xs+lophatCount :: String -> ControlPattern+lophatCount name = pStateF "lophat" name (maybe 0 (+1))+lophatCountTo :: String -> Pattern Double -> Pattern ValueMap+lophatCountTo name ipat = innerJoin $ (\i -> pStateF "lophat" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lophatbus :: Pattern Int -> Pattern Double -> ControlPattern+lophatbus busid pat = (pF "lophat" pat) # (pI "^lophat" busid)+lophatrecv :: Pattern Int -> ControlPattern+lophatrecv busid = pI "^lophat" busid++-- | +lrate :: Pattern Double -> ControlPattern+lrate = pF "lrate"+lrateTake :: String -> [Double] -> ControlPattern+lrateTake name xs = pStateListF "lrate" name xs+lrateCount :: String -> ControlPattern+lrateCount name = pStateF "lrate" name (maybe 0 (+1))+lrateCountTo :: String -> Pattern Double -> Pattern ValueMap+lrateCountTo name ipat = innerJoin $ (\i -> pStateF "lrate" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lratebus :: Pattern Int -> Pattern Double -> ControlPattern+lratebus busid pat = (pF "lrate" pat) # (pI "^lrate" busid)+lraterecv :: Pattern Int -> ControlPattern+lraterecv busid = pI "^lrate" busid++-- | +lsize :: Pattern Double -> ControlPattern+lsize = pF "lsize"+lsizeTake :: String -> [Double] -> ControlPattern+lsizeTake name xs = pStateListF "lsize" name xs+lsizeCount :: String -> ControlPattern+lsizeCount name = pStateF "lsize" name (maybe 0 (+1))+lsizeCountTo :: String -> Pattern Double -> Pattern ValueMap+lsizeCountTo name ipat = innerJoin $ (\i -> pStateF "lsize" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lsizebus :: Pattern Int -> Pattern Double -> ControlPattern+lsizebus busid pat = (pF "lsize" pat) # (pI "^lsize" busid)+lsizerecv :: Pattern Int -> ControlPattern+lsizerecv busid = pI "^lsize" busid++-- | +lsnare :: Pattern Double -> ControlPattern+lsnare = pF "lsnare"+lsnareTake :: String -> [Double] -> ControlPattern+lsnareTake name xs = pStateListF "lsnare" name xs+lsnareCount :: String -> ControlPattern+lsnareCount name = pStateF "lsnare" name (maybe 0 (+1))+lsnareCountTo :: String -> Pattern Double -> Pattern ValueMap+lsnareCountTo name ipat = innerJoin $ (\i -> pStateF "lsnare" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++lsnarebus :: Pattern Int -> Pattern Double -> ControlPattern+lsnarebus busid pat = (pF "lsnare" pat) # (pI "^lsnare" busid)+lsnarerecv :: Pattern Int -> ControlPattern+lsnarerecv busid = pI "^lsnare" busid++-- | +midibend :: Pattern Double -> ControlPattern+midibend = pF "midibend"+midibendTake :: String -> [Double] -> ControlPattern+midibendTake name xs = pStateListF "midibend" name xs+midibendCount :: String -> ControlPattern+midibendCount name = pStateF "midibend" name (maybe 0 (+1))+midibendCountTo :: String -> Pattern Double -> Pattern ValueMap+midibendCountTo name ipat = innerJoin $ (\i -> pStateF "midibend" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++midibendbus :: Pattern Int -> Pattern Double -> ControlPattern+midibendbus busid pat = (pF "midibend" pat) # (pI "^midibend" busid)+midibendrecv :: Pattern Int -> ControlPattern+midibendrecv busid = pI "^midibend" busid++-- | +midichan :: Pattern Double -> ControlPattern+midichan = pF "midichan"+midichanTake :: String -> [Double] -> ControlPattern+midichanTake name xs = pStateListF "midichan" name xs+midichanCount :: String -> ControlPattern+midichanCount name = pStateF "midichan" name (maybe 0 (+1))+midichanCountTo :: String -> Pattern Double -> Pattern ValueMap+midichanCountTo name ipat = innerJoin $ (\i -> pStateF "midichan" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++midichanbus :: Pattern Int -> Pattern Double -> ControlPattern+midichanbus busid pat = (pF "midichan" pat) # (pI "^midichan" busid)+midichanrecv :: Pattern Int -> ControlPattern+midichanrecv busid = pI "^midichan" busid++-- | +midicmd :: Pattern String -> ControlPattern+midicmd = pS "midicmd"+midicmdTake :: String -> [Double] -> ControlPattern+midicmdTake name xs = pStateListF "midicmd" name xs+midicmdbus :: Pattern Int -> Pattern String -> ControlPattern+midicmdbus busid pat = (pS "midicmd" pat) # (pI "^midicmd" busid)+midicmdrecv :: Pattern Int -> ControlPattern+midicmdrecv busid = pI "^midicmd" busid++-- | +miditouch :: Pattern Double -> ControlPattern+miditouch = pF "miditouch"+miditouchTake :: String -> [Double] -> ControlPattern+miditouchTake name xs = pStateListF "miditouch" name xs+miditouchCount :: String -> ControlPattern+miditouchCount name = pStateF "miditouch" name (maybe 0 (+1))+miditouchCountTo :: String -> Pattern Double -> Pattern ValueMap+miditouchCountTo name ipat = innerJoin $ (\i -> pStateF "miditouch" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++miditouchbus :: Pattern Int -> Pattern Double -> ControlPattern+miditouchbus busid pat = (pF "miditouch" pat) # (pI "^miditouch" busid)+miditouchrecv :: Pattern Int -> ControlPattern+miditouchrecv busid = pI "^miditouch" busid++-- | +minutes :: Pattern Double -> ControlPattern+minutes = pF "minutes"+minutesTake :: String -> [Double] -> ControlPattern+minutesTake name xs = pStateListF "minutes" name xs+minutesCount :: String -> ControlPattern+minutesCount name = pStateF "minutes" name (maybe 0 (+1))+minutesCountTo :: String -> Pattern Double -> Pattern ValueMap+minutesCountTo name ipat = innerJoin $ (\i -> pStateF "minutes" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++minutesbus :: Pattern Int -> Pattern Double -> ControlPattern+minutesbus busid pat = (pF "minutes" pat) # (pI "^minutes" busid)+minutesrecv :: Pattern Int -> ControlPattern+minutesrecv busid = pI "^minutes" busid++-- | +modwheel :: Pattern Double -> ControlPattern+modwheel = pF "modwheel"+modwheelTake :: String -> [Double] -> ControlPattern+modwheelTake name xs = pStateListF "modwheel" name xs+modwheelCount :: String -> ControlPattern+modwheelCount name = pStateF "modwheel" name (maybe 0 (+1))+modwheelCountTo :: String -> Pattern Double -> Pattern ValueMap+modwheelCountTo name ipat = innerJoin $ (\i -> pStateF "modwheel" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++modwheelbus :: Pattern Int -> Pattern Double -> ControlPattern+modwheelbus busid pat = (pF "modwheel" pat) # (pI "^modwheel" busid)+modwheelrecv :: Pattern Int -> ControlPattern+modwheelrecv busid = pI "^modwheel" busid++-- | +mtranspose :: Pattern Double -> ControlPattern+mtranspose = pF "mtranspose"+mtransposeTake :: String -> [Double] -> ControlPattern+mtransposeTake name xs = pStateListF "mtranspose" name xs+mtransposeCount :: String -> ControlPattern+mtransposeCount name = pStateF "mtranspose" name (maybe 0 (+1))+mtransposeCountTo :: String -> Pattern Double -> Pattern ValueMap+mtransposeCountTo name ipat = innerJoin $ (\i -> pStateF "mtranspose" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++mtransposebus :: Pattern Int -> Pattern Double -> ControlPattern+mtransposebus busid pat = (pF "mtranspose" pat) # (pI "^mtranspose" busid)+mtransposerecv :: Pattern Int -> ControlPattern+mtransposerecv busid = pI "^mtranspose" busid++-- | The note or sample number to choose for a synth or sampleset+n :: Pattern Note -> ControlPattern+n = pN "n"+nTake :: String -> [Double] -> ControlPattern+nTake name xs = pStateListF "n" name xs+nCount :: String -> ControlPattern+nCount name = pStateF "n" name (maybe 0 (+1))+nCountTo :: String -> Pattern Double -> Pattern ValueMap+nCountTo name ipat = innerJoin $ (\i -> pStateF "n" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++nbus :: Pattern Int -> Pattern Note -> ControlPattern+nbus _ _ = error $ "Control parameter 'n' can't be sent to a bus."++-- | The note or pitch to play a sound or synth with+note :: Pattern Note -> ControlPattern+note = pN "note"+noteTake :: String -> [Double] -> ControlPattern+noteTake name xs = pStateListF "note" name xs+noteCount :: String -> ControlPattern+noteCount name = pStateF "note" name (maybe 0 (+1))+noteCountTo :: String -> Pattern Double -> Pattern ValueMap+noteCountTo name ipat = innerJoin $ (\i -> pStateF "note" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++notebus :: Pattern Int -> Pattern Note -> ControlPattern+notebus _ _ = error $ "Control parameter 'note' can't be sent to a bus."++-- | +nrpnn :: Pattern Int -> ControlPattern+nrpnn = pI "nrpnn"+nrpnnTake :: String -> [Double] -> ControlPattern+nrpnnTake name xs = pStateListF "nrpnn" name xs+nrpnnCount :: String -> ControlPattern+nrpnnCount name = pStateF "nrpnn" name (maybe 0 (+1))+nrpnnCountTo :: String -> Pattern Double -> Pattern ValueMap+nrpnnCountTo name ipat = innerJoin $ (\i -> pStateF "nrpnn" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++nrpnnbus :: Pattern Int -> Pattern Int -> ControlPattern+nrpnnbus busid pat = (pI "nrpnn" pat) # (pI "^nrpnn" busid)+nrpnnrecv :: Pattern Int -> ControlPattern+nrpnnrecv busid = pI "^nrpnn" busid++-- | +nrpnv :: Pattern Int -> ControlPattern+nrpnv = pI "nrpnv"+nrpnvTake :: String -> [Double] -> ControlPattern+nrpnvTake name xs = pStateListF "nrpnv" name xs+nrpnvCount :: String -> ControlPattern+nrpnvCount name = pStateF "nrpnv" name (maybe 0 (+1))+nrpnvCountTo :: String -> Pattern Double -> Pattern ValueMap+nrpnvCountTo name ipat = innerJoin $ (\i -> pStateF "nrpnv" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++nrpnvbus :: Pattern Int -> Pattern Int -> ControlPattern+nrpnvbus busid pat = (pI "nrpnv" pat) # (pI "^nrpnv" busid)+nrpnvrecv :: Pattern Int -> ControlPattern+nrpnvrecv busid = pI "^nrpnv" busid++-- | Nudges events into the future by the specified number of seconds. Negative numbers work up to a point as well (due to internal latency)+nudge :: Pattern Double -> ControlPattern+nudge = pF "nudge"+nudgeTake :: String -> [Double] -> ControlPattern+nudgeTake name xs = pStateListF "nudge" name xs+nudgeCount :: String -> ControlPattern+nudgeCount name = pStateF "nudge" name (maybe 0 (+1))+nudgeCountTo :: String -> Pattern Double -> Pattern ValueMap+nudgeCountTo name ipat = innerJoin $ (\i -> pStateF "nudge" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++nudgebus :: Pattern Int -> Pattern Double -> ControlPattern+nudgebus busid pat = (pF "nudge" pat) # (pI "^nudge" busid)+nudgerecv :: Pattern Int -> ControlPattern+nudgerecv busid = pI "^nudge" busid++-- | +octave :: Pattern Int -> ControlPattern+octave = pI "octave"+octaveTake :: String -> [Double] -> ControlPattern+octaveTake name xs = pStateListF "octave" name xs+octaveCount :: String -> ControlPattern+octaveCount name = pStateF "octave" name (maybe 0 (+1))+octaveCountTo :: String -> Pattern Double -> Pattern ValueMap+octaveCountTo name ipat = innerJoin $ (\i -> pStateF "octave" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++octavebus :: Pattern Int -> Pattern Int -> ControlPattern+octavebus _ _ = error $ "Control parameter 'octave' can't be sent to a bus."++-- | +octaveR :: Pattern Double -> ControlPattern+octaveR = pF "octaveR"+octaveRTake :: String -> [Double] -> ControlPattern+octaveRTake name xs = pStateListF "octaveR" name xs+octaveRCount :: String -> ControlPattern+octaveRCount name = pStateF "octaveR" name (maybe 0 (+1))+octaveRCountTo :: String -> Pattern Double -> Pattern ValueMap+octaveRCountTo name ipat = innerJoin $ (\i -> pStateF "octaveR" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++octaveRbus :: Pattern Int -> Pattern Double -> ControlPattern+octaveRbus busid pat = (pF "octaveR" pat) # (pI "^octaveR" busid)+octaveRrecv :: Pattern Int -> ControlPattern+octaveRrecv busid = pI "^octaveR" busid++-- | octaver effect+octer :: Pattern Double -> ControlPattern+octer = pF "octer"+octerTake :: String -> [Double] -> ControlPattern+octerTake name xs = pStateListF "octer" name xs+octerCount :: String -> ControlPattern+octerCount name = pStateF "octer" name (maybe 0 (+1))+octerCountTo :: String -> Pattern Double -> Pattern ValueMap+octerCountTo name ipat = innerJoin $ (\i -> pStateF "octer" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++octerbus :: Pattern Int -> Pattern Double -> ControlPattern+octerbus busid pat = (pF "octer" pat) # (pI "^octer" busid)+octerrecv :: Pattern Int -> ControlPattern+octerrecv busid = pI "^octer" busid++-- | octaver effect+octersub :: Pattern Double -> ControlPattern+octersub = pF "octersub"+octersubTake :: String -> [Double] -> ControlPattern+octersubTake name xs = pStateListF "octersub" name xs+octersubCount :: String -> ControlPattern+octersubCount name = pStateF "octersub" name (maybe 0 (+1))+octersubCountTo :: String -> Pattern Double -> Pattern ValueMap+octersubCountTo name ipat = innerJoin $ (\i -> pStateF "octersub" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++octersubbus :: Pattern Int -> Pattern Double -> ControlPattern+octersubbus busid pat = (pF "octersub" pat) # (pI "^octersub" busid)+octersubrecv :: Pattern Int -> ControlPattern+octersubrecv busid = pI "^octersub" busid++-- | octaver effect+octersubsub :: Pattern Double -> ControlPattern+octersubsub = pF "octersubsub"+octersubsubTake :: String -> [Double] -> ControlPattern+octersubsubTake name xs = pStateListF "octersubsub" name xs+octersubsubCount :: String -> ControlPattern+octersubsubCount name = pStateF "octersubsub" name (maybe 0 (+1))+octersubsubCountTo :: String -> Pattern Double -> Pattern ValueMap+octersubsubCountTo name ipat = innerJoin $ (\i -> pStateF "octersubsub" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++octersubsubbus :: Pattern Int -> Pattern Double -> ControlPattern+octersubsubbus busid pat = (pF "octersubsub" pat) # (pI "^octersubsub" busid)+octersubsubrecv :: Pattern Int -> ControlPattern+octersubsubrecv busid = pI "^octersubsub" busid++-- | +offset :: Pattern Double -> ControlPattern+offset = pF "offset"+offsetTake :: String -> [Double] -> ControlPattern+offsetTake name xs = pStateListF "offset" name xs+offsetCount :: String -> ControlPattern+offsetCount name = pStateF "offset" name (maybe 0 (+1))+offsetCountTo :: String -> Pattern Double -> Pattern ValueMap+offsetCountTo name ipat = innerJoin $ (\i -> pStateF "offset" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++offsetbus :: Pattern Int -> Pattern Double -> ControlPattern+offsetbus _ _ = error $ "Control parameter 'offset' can't be sent to a bus."++-- | +ophatdecay :: Pattern Double -> ControlPattern+ophatdecay = pF "ophatdecay"+ophatdecayTake :: String -> [Double] -> ControlPattern+ophatdecayTake name xs = pStateListF "ophatdecay" name xs+ophatdecayCount :: String -> ControlPattern+ophatdecayCount name = pStateF "ophatdecay" name (maybe 0 (+1))+ophatdecayCountTo :: String -> Pattern Double -> Pattern ValueMap+ophatdecayCountTo name ipat = innerJoin $ (\i -> pStateF "ophatdecay" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++ophatdecaybus :: Pattern Int -> Pattern Double -> ControlPattern+ophatdecaybus busid pat = (pF "ophatdecay" pat) # (pI "^ophatdecay" busid)+ophatdecayrecv :: Pattern Int -> ControlPattern+ophatdecayrecv busid = pI "^ophatdecay" busid++-- | a pattern of numbers. An `orbit` is a global parameter context for patterns. Patterns with the same orbit will share hardware output bus offset and global effects, e.g. reverb and delay. The maximum number of orbits is specified in the superdirt startup, numbers higher than maximum will wrap around.+orbit :: Pattern Int -> ControlPattern+orbit = pI "orbit"+orbitTake :: String -> [Double] -> ControlPattern+orbitTake name xs = pStateListF "orbit" name xs+orbitCount :: String -> ControlPattern+orbitCount name = pStateF "orbit" name (maybe 0 (+1))+orbitCountTo :: String -> Pattern Double -> Pattern ValueMap+orbitCountTo name ipat = innerJoin $ (\i -> pStateF "orbit" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++orbitbus :: Pattern Int -> Pattern Int -> ControlPattern+orbitbus busid pat = (pI "orbit" pat) # (pI "^orbit" busid)+orbitrecv :: Pattern Int -> ControlPattern+orbitrecv busid = pI "^orbit" busid++-- | +overgain :: Pattern Double -> ControlPattern+overgain = pF "overgain"+overgainTake :: String -> [Double] -> ControlPattern+overgainTake name xs = pStateListF "overgain" name xs+overgainCount :: String -> ControlPattern+overgainCount name = pStateF "overgain" name (maybe 0 (+1))+overgainCountTo :: String -> Pattern Double -> Pattern ValueMap+overgainCountTo name ipat = innerJoin $ (\i -> pStateF "overgain" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++overgainbus :: Pattern Int -> Pattern Double -> ControlPattern+overgainbus _ _ = error $ "Control parameter 'overgain' can't be sent to a bus."++-- | +overshape :: Pattern Double -> ControlPattern+overshape = pF "overshape"+overshapeTake :: String -> [Double] -> ControlPattern+overshapeTake name xs = pStateListF "overshape" name xs+overshapeCount :: String -> ControlPattern+overshapeCount name = pStateF "overshape" name (maybe 0 (+1))+overshapeCountTo :: String -> Pattern Double -> Pattern ValueMap+overshapeCountTo name ipat = innerJoin $ (\i -> pStateF "overshape" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++overshapebus :: Pattern Int -> Pattern Double -> ControlPattern+overshapebus busid pat = (pF "overshape" pat) # (pI "^overshape" busid)+overshaperecv :: Pattern Int -> ControlPattern+overshaperecv busid = pI "^overshape" busid++-- | a pattern of numbers between 0 and 1, from left to right (assuming stereo), once round a circle (assuming multichannel)+pan :: Pattern Double -> ControlPattern+pan = pF "pan"+panTake :: String -> [Double] -> ControlPattern+panTake name xs = pStateListF "pan" name xs+panCount :: String -> ControlPattern+panCount name = pStateF "pan" name (maybe 0 (+1))+panCountTo :: String -> Pattern Double -> Pattern ValueMap+panCountTo name ipat = innerJoin $ (\i -> pStateF "pan" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++panbus :: Pattern Int -> Pattern Double -> ControlPattern+panbus busid pat = (pF "pan" pat) # (pI "^pan" busid)+panrecv :: Pattern Int -> ControlPattern+panrecv busid = pI "^pan" busid++-- | a pattern of numbers between -1.0 and 1.0, which controls the relative position of the centre pan in a pair of adjacent speakers (multichannel only)+panorient :: Pattern Double -> ControlPattern+panorient = pF "panorient"+panorientTake :: String -> [Double] -> ControlPattern+panorientTake name xs = pStateListF "panorient" name xs+panorientCount :: String -> ControlPattern+panorientCount name = pStateF "panorient" name (maybe 0 (+1))+panorientCountTo :: String -> Pattern Double -> Pattern ValueMap+panorientCountTo name ipat = innerJoin $ (\i -> pStateF "panorient" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++panorientbus :: Pattern Int -> Pattern Double -> ControlPattern+panorientbus busid pat = (pF "panorient" pat) # (pI "^panorient" busid)+panorientrecv :: Pattern Int -> ControlPattern+panorientrecv busid = pI "^panorient" busid++-- | a pattern of numbers between -inf and inf, which controls how much multichannel output is fanned out (negative is backwards ordering)+panspan :: Pattern Double -> ControlPattern+panspan = pF "panspan"+panspanTake :: String -> [Double] -> ControlPattern+panspanTake name xs = pStateListF "panspan" name xs+panspanCount :: String -> ControlPattern+panspanCount name = pStateF "panspan" name (maybe 0 (+1))+panspanCountTo :: String -> Pattern Double -> Pattern ValueMap+panspanCountTo name ipat = innerJoin $ (\i -> pStateF "panspan" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++panspanbus :: Pattern Int -> Pattern Double -> ControlPattern+panspanbus busid pat = (pF "panspan" pat) # (pI "^panspan" busid)+panspanrecv :: Pattern Int -> ControlPattern+panspanrecv busid = pI "^panspan" busid++-- | a pattern of numbers between 0.0 and 1.0, which controls the multichannel spread range (multichannel only)+pansplay :: Pattern Double -> ControlPattern+pansplay = pF "pansplay"+pansplayTake :: String -> [Double] -> ControlPattern+pansplayTake name xs = pStateListF "pansplay" name xs+pansplayCount :: String -> ControlPattern+pansplayCount name = pStateF "pansplay" name (maybe 0 (+1))+pansplayCountTo :: String -> Pattern Double -> Pattern ValueMap+pansplayCountTo name ipat = innerJoin $ (\i -> pStateF "pansplay" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++pansplaybus :: Pattern Int -> Pattern Double -> ControlPattern+pansplaybus busid pat = (pF "pansplay" pat) # (pI "^pansplay" busid)+pansplayrecv :: Pattern Int -> ControlPattern+pansplayrecv busid = pI "^pansplay" busid++-- | a pattern of numbers between 0.0 and inf, which controls how much each channel is distributed over neighbours (multichannel only)+panwidth :: Pattern Double -> ControlPattern+panwidth = pF "panwidth"+panwidthTake :: String -> [Double] -> ControlPattern+panwidthTake name xs = pStateListF "panwidth" name xs+panwidthCount :: String -> ControlPattern+panwidthCount name = pStateF "panwidth" name (maybe 0 (+1))+panwidthCountTo :: String -> Pattern Double -> Pattern ValueMap+panwidthCountTo name ipat = innerJoin $ (\i -> pStateF "panwidth" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++panwidthbus :: Pattern Int -> Pattern Double -> ControlPattern+panwidthbus busid pat = (pF "panwidth" pat) # (pI "^panwidth" busid)+panwidthrecv :: Pattern Int -> ControlPattern+panwidthrecv busid = pI "^panwidth" busid++-- | +partials :: Pattern Double -> ControlPattern+partials = pF "partials"+partialsTake :: String -> [Double] -> ControlPattern+partialsTake name xs = pStateListF "partials" name xs+partialsCount :: String -> ControlPattern+partialsCount name = pStateF "partials" name (maybe 0 (+1))+partialsCountTo :: String -> Pattern Double -> Pattern ValueMap+partialsCountTo name ipat = innerJoin $ (\i -> pStateF "partials" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++partialsbus :: Pattern Int -> Pattern Double -> ControlPattern+partialsbus busid pat = (pF "partials" pat) # (pI "^partials" busid)+partialsrecv :: Pattern Int -> ControlPattern+partialsrecv busid = pI "^partials" busid++-- | Phaser Audio DSP effect | params are 'phaserrate' and 'phaserdepth'+phaserdepth :: Pattern Double -> ControlPattern+phaserdepth = pF "phaserdepth"+phaserdepthTake :: String -> [Double] -> ControlPattern+phaserdepthTake name xs = pStateListF "phaserdepth" name xs+phaserdepthCount :: String -> ControlPattern+phaserdepthCount name = pStateF "phaserdepth" name (maybe 0 (+1))+phaserdepthCountTo :: String -> Pattern Double -> Pattern ValueMap+phaserdepthCountTo name ipat = innerJoin $ (\i -> pStateF "phaserdepth" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++phaserdepthbus :: Pattern Int -> Pattern Double -> ControlPattern+phaserdepthbus busid pat = (pF "phaserdepth" pat) # (pI "^phaserdepth" busid)+phaserdepthrecv :: Pattern Int -> ControlPattern+phaserdepthrecv busid = pI "^phaserdepth" busid++-- | Phaser Audio DSP effect | params are 'phaserrate' and 'phaserdepth'+phaserrate :: Pattern Double -> ControlPattern+phaserrate = pF "phaserrate"+phaserrateTake :: String -> [Double] -> ControlPattern+phaserrateTake name xs = pStateListF "phaserrate" name xs+phaserrateCount :: String -> ControlPattern+phaserrateCount name = pStateF "phaserrate" name (maybe 0 (+1))+phaserrateCountTo :: String -> Pattern Double -> Pattern ValueMap+phaserrateCountTo name ipat = innerJoin $ (\i -> pStateF "phaserrate" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++phaserratebus :: Pattern Int -> Pattern Double -> ControlPattern+phaserratebus busid pat = (pF "phaserrate" pat) # (pI "^phaserrate" busid)+phaserraterecv :: Pattern Int -> ControlPattern+phaserraterecv busid = pI "^phaserrate" busid++-- | +pitch1 :: Pattern Double -> ControlPattern+pitch1 = pF "pitch1"+pitch1Take :: String -> [Double] -> ControlPattern+pitch1Take name xs = pStateListF "pitch1" name xs+pitch1Count :: String -> ControlPattern+pitch1Count name = pStateF "pitch1" name (maybe 0 (+1))+pitch1CountTo :: String -> Pattern Double -> Pattern ValueMap+pitch1CountTo name ipat = innerJoin $ (\i -> pStateF "pitch1" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++pitch1bus :: Pattern Int -> Pattern Double -> ControlPattern+pitch1bus busid pat = (pF "pitch1" pat) # (pI "^pitch1" busid)+pitch1recv :: Pattern Int -> ControlPattern+pitch1recv busid = pI "^pitch1" busid++-- | +pitch2 :: Pattern Double -> ControlPattern+pitch2 = pF "pitch2"+pitch2Take :: String -> [Double] -> ControlPattern+pitch2Take name xs = pStateListF "pitch2" name xs+pitch2Count :: String -> ControlPattern+pitch2Count name = pStateF "pitch2" name (maybe 0 (+1))+pitch2CountTo :: String -> Pattern Double -> Pattern ValueMap+pitch2CountTo name ipat = innerJoin $ (\i -> pStateF "pitch2" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++pitch2bus :: Pattern Int -> Pattern Double -> ControlPattern+pitch2bus busid pat = (pF "pitch2" pat) # (pI "^pitch2" busid)+pitch2recv :: Pattern Int -> ControlPattern+pitch2recv busid = pI "^pitch2" busid++-- | +pitch3 :: Pattern Double -> ControlPattern+pitch3 = pF "pitch3"+pitch3Take :: String -> [Double] -> ControlPattern+pitch3Take name xs = pStateListF "pitch3" name xs+pitch3Count :: String -> ControlPattern+pitch3Count name = pStateF "pitch3" name (maybe 0 (+1))+pitch3CountTo :: String -> Pattern Double -> Pattern ValueMap+pitch3CountTo name ipat = innerJoin $ (\i -> pStateF "pitch3" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++pitch3bus :: Pattern Int -> Pattern Double -> ControlPattern+pitch3bus busid pat = (pF "pitch3" pat) # (pI "^pitch3" busid)+pitch3recv :: Pattern Int -> ControlPattern+pitch3recv busid = pI "^pitch3" busid++-- | +polyTouch :: Pattern Double -> ControlPattern+polyTouch = pF "polyTouch"+polyTouchTake :: String -> [Double] -> ControlPattern+polyTouchTake name xs = pStateListF "polyTouch" name xs+polyTouchCount :: String -> ControlPattern+polyTouchCount name = pStateF "polyTouch" name (maybe 0 (+1))+polyTouchCountTo :: String -> Pattern Double -> Pattern ValueMap+polyTouchCountTo name ipat = innerJoin $ (\i -> pStateF "polyTouch" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++polyTouchbus :: Pattern Int -> Pattern Double -> ControlPattern+polyTouchbus busid pat = (pF "polyTouch" pat) # (pI "^polyTouch" busid)+polyTouchrecv :: Pattern Int -> ControlPattern+polyTouchrecv busid = pI "^polyTouch" busid++-- | +portamento :: Pattern Double -> ControlPattern+portamento = pF "portamento"+portamentoTake :: String -> [Double] -> ControlPattern+portamentoTake name xs = pStateListF "portamento" name xs+portamentoCount :: String -> ControlPattern+portamentoCount name = pStateF "portamento" name (maybe 0 (+1))+portamentoCountTo :: String -> Pattern Double -> Pattern ValueMap+portamentoCountTo name ipat = innerJoin $ (\i -> pStateF "portamento" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++portamentobus :: Pattern Int -> Pattern Double -> ControlPattern+portamentobus busid pat = (pF "portamento" pat) # (pI "^portamento" busid)+portamentorecv :: Pattern Int -> ControlPattern+portamentorecv busid = pI "^portamento" busid++-- | +progNum :: Pattern Double -> ControlPattern+progNum = pF "progNum"+progNumTake :: String -> [Double] -> ControlPattern+progNumTake name xs = pStateListF "progNum" name xs+progNumCount :: String -> ControlPattern+progNumCount name = pStateF "progNum" name (maybe 0 (+1))+progNumCountTo :: String -> Pattern Double -> Pattern ValueMap+progNumCountTo name ipat = innerJoin $ (\i -> pStateF "progNum" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++progNumbus :: Pattern Int -> Pattern Double -> ControlPattern+progNumbus busid pat = (pF "progNum" pat) # (pI "^progNum" busid)+progNumrecv :: Pattern Int -> ControlPattern+progNumrecv busid = pI "^progNum" busid++-- | used in SuperDirt softsynths as a control rate or 'speed'+rate :: Pattern Double -> ControlPattern+rate = pF "rate"+rateTake :: String -> [Double] -> ControlPattern+rateTake name xs = pStateListF "rate" name xs+rateCount :: String -> ControlPattern+rateCount name = pStateF "rate" name (maybe 0 (+1))+rateCountTo :: String -> Pattern Double -> Pattern ValueMap+rateCountTo name ipat = innerJoin $ (\i -> pStateF "rate" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++ratebus :: Pattern Int -> Pattern Double -> ControlPattern+ratebus busid pat = (pF "rate" pat) # (pI "^rate" busid)+raterecv :: Pattern Int -> ControlPattern+raterecv busid = pI "^rate" busid++-- | Spectral conform+real :: Pattern Double -> ControlPattern+real = pF "real"+realTake :: String -> [Double] -> ControlPattern+realTake name xs = pStateListF "real" name xs+realCount :: String -> ControlPattern+realCount name = pStateF "real" name (maybe 0 (+1))+realCountTo :: String -> Pattern Double -> Pattern ValueMap+realCountTo name ipat = innerJoin $ (\i -> pStateF "real" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++realbus :: Pattern Int -> Pattern Double -> ControlPattern+realbus busid pat = (pF "real" pat) # (pI "^real" busid)+realrecv :: Pattern Int -> ControlPattern+realrecv busid = pI "^real" busid++-- | a pattern of numbers to specify the release time (in seconds) of an envelope applied to each sample.+release :: Pattern Double -> ControlPattern+release = pF "release"+releaseTake :: String -> [Double] -> ControlPattern+releaseTake name xs = pStateListF "release" name xs+releaseCount :: String -> ControlPattern+releaseCount name = pStateF "release" name (maybe 0 (+1))+releaseCountTo :: String -> Pattern Double -> Pattern ValueMap+releaseCountTo name ipat = innerJoin $ (\i -> pStateF "release" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++releasebus :: Pattern Int -> Pattern Double -> ControlPattern+releasebus busid pat = (pF "release" pat) # (pI "^release" busid)+releaserecv :: Pattern Int -> ControlPattern+releaserecv busid = pI "^release" busid++-- | a pattern of numbers from 0 to 1. Specifies the resonance of the low-pass filter.+resonance :: Pattern Double -> ControlPattern+resonance = pF "resonance"+resonanceTake :: String -> [Double] -> ControlPattern+resonanceTake name xs = pStateListF "resonance" name xs+resonanceCount :: String -> ControlPattern+resonanceCount name = pStateF "resonance" name (maybe 0 (+1))+resonanceCountTo :: String -> Pattern Double -> Pattern ValueMap+resonanceCountTo name ipat = innerJoin $ (\i -> pStateF "resonance" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++resonancebus :: Pattern Int -> Pattern Double -> ControlPattern+resonancebus busid pat = (pF "resonance" pat) # (pI "^resonance" busid)+resonancerecv :: Pattern Int -> ControlPattern+resonancerecv busid = pI "^resonance" busid++-- | ring modulation+ring :: Pattern Double -> ControlPattern+ring = pF "ring"+ringTake :: String -> [Double] -> ControlPattern+ringTake name xs = pStateListF "ring" name xs+ringCount :: String -> ControlPattern+ringCount name = pStateF "ring" name (maybe 0 (+1))+ringCountTo :: String -> Pattern Double -> Pattern ValueMap+ringCountTo name ipat = innerJoin $ (\i -> pStateF "ring" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++ringbus :: Pattern Int -> Pattern Double -> ControlPattern+ringbus busid pat = (pF "ring" pat) # (pI "^ring" busid)+ringrecv :: Pattern Int -> ControlPattern+ringrecv busid = pI "^ring" busid++-- | ring modulation+ringdf :: Pattern Double -> ControlPattern+ringdf = pF "ringdf"+ringdfTake :: String -> [Double] -> ControlPattern+ringdfTake name xs = pStateListF "ringdf" name xs+ringdfCount :: String -> ControlPattern+ringdfCount name = pStateF "ringdf" name (maybe 0 (+1))+ringdfCountTo :: String -> Pattern Double -> Pattern ValueMap+ringdfCountTo name ipat = innerJoin $ (\i -> pStateF "ringdf" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++ringdfbus :: Pattern Int -> Pattern Double -> ControlPattern+ringdfbus busid pat = (pF "ringdf" pat) # (pI "^ringdf" busid)+ringdfrecv :: Pattern Int -> ControlPattern+ringdfrecv busid = pI "^ringdf" busid++-- | ring modulation+ringf :: Pattern Double -> ControlPattern+ringf = pF "ringf"+ringfTake :: String -> [Double] -> ControlPattern+ringfTake name xs = pStateListF "ringf" name xs+ringfCount :: String -> ControlPattern+ringfCount name = pStateF "ringf" name (maybe 0 (+1))+ringfCountTo :: String -> Pattern Double -> Pattern ValueMap+ringfCountTo name ipat = innerJoin $ (\i -> pStateF "ringf" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++ringfbus :: Pattern Int -> Pattern Double -> ControlPattern+ringfbus busid pat = (pF "ringf" pat) # (pI "^ringf" busid)+ringfrecv :: Pattern Int -> ControlPattern+ringfrecv busid = pI "^ringf" busid++-- | a pattern of numbers from 0 to 1. Sets the level of reverb.+room :: Pattern Double -> ControlPattern+room = pF "room"+roomTake :: String -> [Double] -> ControlPattern+roomTake name xs = pStateListF "room" name xs+roomCount :: String -> ControlPattern+roomCount name = pStateF "room" name (maybe 0 (+1))+roomCountTo :: String -> Pattern Double -> Pattern ValueMap+roomCountTo name ipat = innerJoin $ (\i -> pStateF "room" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++roombus :: Pattern Int -> Pattern Double -> ControlPattern+roombus busid pat = (pF "room" pat) # (pI "^room" busid)+roomrecv :: Pattern Int -> ControlPattern+roomrecv busid = pI "^room" busid++-- | +sagogo :: Pattern Double -> ControlPattern+sagogo = pF "sagogo"+sagogoTake :: String -> [Double] -> ControlPattern+sagogoTake name xs = pStateListF "sagogo" name xs+sagogoCount :: String -> ControlPattern+sagogoCount name = pStateF "sagogo" name (maybe 0 (+1))+sagogoCountTo :: String -> Pattern Double -> Pattern ValueMap+sagogoCountTo name ipat = innerJoin $ (\i -> pStateF "sagogo" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++sagogobus :: Pattern Int -> Pattern Double -> ControlPattern+sagogobus busid pat = (pF "sagogo" pat) # (pI "^sagogo" busid)+sagogorecv :: Pattern Int -> ControlPattern+sagogorecv busid = pI "^sagogo" busid++-- | +sclap :: Pattern Double -> ControlPattern+sclap = pF "sclap"+sclapTake :: String -> [Double] -> ControlPattern+sclapTake name xs = pStateListF "sclap" name xs+sclapCount :: String -> ControlPattern+sclapCount name = pStateF "sclap" name (maybe 0 (+1))+sclapCountTo :: String -> Pattern Double -> Pattern ValueMap+sclapCountTo name ipat = innerJoin $ (\i -> pStateF "sclap" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++sclapbus :: Pattern Int -> Pattern Double -> ControlPattern+sclapbus busid pat = (pF "sclap" pat) # (pI "^sclap" busid)+sclaprecv :: Pattern Int -> ControlPattern+sclaprecv busid = pI "^sclap" busid++-- | +sclaves :: Pattern Double -> ControlPattern+sclaves = pF "sclaves"+sclavesTake :: String -> [Double] -> ControlPattern+sclavesTake name xs = pStateListF "sclaves" name xs+sclavesCount :: String -> ControlPattern+sclavesCount name = pStateF "sclaves" name (maybe 0 (+1))+sclavesCountTo :: String -> Pattern Double -> Pattern ValueMap+sclavesCountTo name ipat = innerJoin $ (\i -> pStateF "sclaves" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++sclavesbus :: Pattern Int -> Pattern Double -> ControlPattern+sclavesbus busid pat = (pF "sclaves" pat) # (pI "^sclaves" busid)+sclavesrecv :: Pattern Int -> ControlPattern+sclavesrecv busid = pI "^sclaves" busid++-- | Spectral scramble+scram :: Pattern Double -> ControlPattern+scram = pF "scram"+scramTake :: String -> [Double] -> ControlPattern+scramTake name xs = pStateListF "scram" name xs+scramCount :: String -> ControlPattern+scramCount name = pStateF "scram" name (maybe 0 (+1))+scramCountTo :: String -> Pattern Double -> Pattern ValueMap+scramCountTo name ipat = innerJoin $ (\i -> pStateF "scram" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++scrambus :: Pattern Int -> Pattern Double -> ControlPattern+scrambus busid pat = (pF "scram" pat) # (pI "^scram" busid)+scramrecv :: Pattern Int -> ControlPattern+scramrecv busid = pI "^scram" busid++-- | +scrash :: Pattern Double -> ControlPattern+scrash = pF "scrash"+scrashTake :: String -> [Double] -> ControlPattern+scrashTake name xs = pStateListF "scrash" name xs+scrashCount :: String -> ControlPattern+scrashCount name = pStateF "scrash" name (maybe 0 (+1))+scrashCountTo :: String -> Pattern Double -> Pattern ValueMap+scrashCountTo name ipat = innerJoin $ (\i -> pStateF "scrash" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++scrashbus :: Pattern Int -> Pattern Double -> ControlPattern+scrashbus busid pat = (pF "scrash" pat) # (pI "^scrash" busid)+scrashrecv :: Pattern Int -> ControlPattern+scrashrecv busid = pI "^scrash" busid++-- | +seconds :: Pattern Double -> ControlPattern+seconds = pF "seconds"+secondsTake :: String -> [Double] -> ControlPattern+secondsTake name xs = pStateListF "seconds" name xs+secondsCount :: String -> ControlPattern+secondsCount name = pStateF "seconds" name (maybe 0 (+1))+secondsCountTo :: String -> Pattern Double -> Pattern ValueMap+secondsCountTo name ipat = innerJoin $ (\i -> pStateF "seconds" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++secondsbus :: Pattern Int -> Pattern Double -> ControlPattern+secondsbus busid pat = (pF "seconds" pat) # (pI "^seconds" busid)+secondsrecv :: Pattern Int -> ControlPattern+secondsrecv busid = pI "^seconds" busid++-- | +semitone :: Pattern Double -> ControlPattern+semitone = pF "semitone"+semitoneTake :: String -> [Double] -> ControlPattern+semitoneTake name xs = pStateListF "semitone" name xs+semitoneCount :: String -> ControlPattern+semitoneCount name = pStateF "semitone" name (maybe 0 (+1))+semitoneCountTo :: String -> Pattern Double -> Pattern ValueMap+semitoneCountTo name ipat = innerJoin $ (\i -> pStateF "semitone" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++semitonebus :: Pattern Int -> Pattern Double -> ControlPattern+semitonebus busid pat = (pF "semitone" pat) # (pI "^semitone" busid)+semitonerecv :: Pattern Int -> ControlPattern+semitonerecv busid = pI "^semitone" busid++-- | wave shaping distortion, a pattern of numbers from 0 for no distortion up to 1 for loads of distortion.+shape :: Pattern Double -> ControlPattern+shape = pF "shape"+shapeTake :: String -> [Double] -> ControlPattern+shapeTake name xs = pStateListF "shape" name xs+shapeCount :: String -> ControlPattern+shapeCount name = pStateF "shape" name (maybe 0 (+1))+shapeCountTo :: String -> Pattern Double -> Pattern ValueMap+shapeCountTo name ipat = innerJoin $ (\i -> pStateF "shape" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++shapebus :: Pattern Int -> Pattern Double -> ControlPattern+shapebus busid pat = (pF "shape" pat) # (pI "^shape" busid)+shaperecv :: Pattern Int -> ControlPattern+shaperecv busid = pI "^shape" busid++-- | a pattern of numbers from 0 to 1. Sets the perceptual size (reverb time) of the `room` to be used in reverb.+size :: Pattern Double -> ControlPattern+size = pF "size"+sizeTake :: String -> [Double] -> ControlPattern+sizeTake name xs = pStateListF "size" name xs+sizeCount :: String -> ControlPattern+sizeCount name = pStateF "size" name (maybe 0 (+1))+sizeCountTo :: String -> Pattern Double -> Pattern ValueMap+sizeCountTo name ipat = innerJoin $ (\i -> pStateF "size" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++sizebus :: Pattern Int -> Pattern Double -> ControlPattern+sizebus busid pat = (pF "size" pat) # (pI "^size" busid)+sizerecv :: Pattern Int -> ControlPattern+sizerecv busid = pI "^size" busid++-- | +slide :: Pattern Double -> ControlPattern+slide = pF "slide"+slideTake :: String -> [Double] -> ControlPattern+slideTake name xs = pStateListF "slide" name xs+slideCount :: String -> ControlPattern+slideCount name = pStateF "slide" name (maybe 0 (+1))+slideCountTo :: String -> Pattern Double -> Pattern ValueMap+slideCountTo name ipat = innerJoin $ (\i -> pStateF "slide" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slidebus :: Pattern Int -> Pattern Double -> ControlPattern+slidebus busid pat = (pF "slide" pat) # (pI "^slide" busid)+sliderecv :: Pattern Int -> ControlPattern+sliderecv busid = pI "^slide" busid++-- | +slider0 :: Pattern Double -> ControlPattern+slider0 = pF "slider0"+slider0Take :: String -> [Double] -> ControlPattern+slider0Take name xs = pStateListF "slider0" name xs+slider0Count :: String -> ControlPattern+slider0Count name = pStateF "slider0" name (maybe 0 (+1))+slider0CountTo :: String -> Pattern Double -> Pattern ValueMap+slider0CountTo name ipat = innerJoin $ (\i -> pStateF "slider0" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider0bus :: Pattern Int -> Pattern Double -> ControlPattern+slider0bus busid pat = (pF "slider0" pat) # (pI "^slider0" busid)+slider0recv :: Pattern Int -> ControlPattern+slider0recv busid = pI "^slider0" busid++-- | +slider1 :: Pattern Double -> ControlPattern+slider1 = pF "slider1"+slider1Take :: String -> [Double] -> ControlPattern+slider1Take name xs = pStateListF "slider1" name xs+slider1Count :: String -> ControlPattern+slider1Count name = pStateF "slider1" name (maybe 0 (+1))+slider1CountTo :: String -> Pattern Double -> Pattern ValueMap+slider1CountTo name ipat = innerJoin $ (\i -> pStateF "slider1" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider1bus :: Pattern Int -> Pattern Double -> ControlPattern+slider1bus busid pat = (pF "slider1" pat) # (pI "^slider1" busid)+slider1recv :: Pattern Int -> ControlPattern+slider1recv busid = pI "^slider1" busid++-- | +slider10 :: Pattern Double -> ControlPattern+slider10 = pF "slider10"+slider10Take :: String -> [Double] -> ControlPattern+slider10Take name xs = pStateListF "slider10" name xs+slider10Count :: String -> ControlPattern+slider10Count name = pStateF "slider10" name (maybe 0 (+1))+slider10CountTo :: String -> Pattern Double -> Pattern ValueMap+slider10CountTo name ipat = innerJoin $ (\i -> pStateF "slider10" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider10bus :: Pattern Int -> Pattern Double -> ControlPattern+slider10bus busid pat = (pF "slider10" pat) # (pI "^slider10" busid)+slider10recv :: Pattern Int -> ControlPattern+slider10recv busid = pI "^slider10" busid++-- | +slider11 :: Pattern Double -> ControlPattern+slider11 = pF "slider11"+slider11Take :: String -> [Double] -> ControlPattern+slider11Take name xs = pStateListF "slider11" name xs+slider11Count :: String -> ControlPattern+slider11Count name = pStateF "slider11" name (maybe 0 (+1))+slider11CountTo :: String -> Pattern Double -> Pattern ValueMap+slider11CountTo name ipat = innerJoin $ (\i -> pStateF "slider11" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider11bus :: Pattern Int -> Pattern Double -> ControlPattern+slider11bus busid pat = (pF "slider11" pat) # (pI "^slider11" busid)+slider11recv :: Pattern Int -> ControlPattern+slider11recv busid = pI "^slider11" busid++-- | +slider12 :: Pattern Double -> ControlPattern+slider12 = pF "slider12"+slider12Take :: String -> [Double] -> ControlPattern+slider12Take name xs = pStateListF "slider12" name xs+slider12Count :: String -> ControlPattern+slider12Count name = pStateF "slider12" name (maybe 0 (+1))+slider12CountTo :: String -> Pattern Double -> Pattern ValueMap+slider12CountTo name ipat = innerJoin $ (\i -> pStateF "slider12" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider12bus :: Pattern Int -> Pattern Double -> ControlPattern+slider12bus busid pat = (pF "slider12" pat) # (pI "^slider12" busid)+slider12recv :: Pattern Int -> ControlPattern+slider12recv busid = pI "^slider12" busid++-- | +slider13 :: Pattern Double -> ControlPattern+slider13 = pF "slider13"+slider13Take :: String -> [Double] -> ControlPattern+slider13Take name xs = pStateListF "slider13" name xs+slider13Count :: String -> ControlPattern+slider13Count name = pStateF "slider13" name (maybe 0 (+1))+slider13CountTo :: String -> Pattern Double -> Pattern ValueMap+slider13CountTo name ipat = innerJoin $ (\i -> pStateF "slider13" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider13bus :: Pattern Int -> Pattern Double -> ControlPattern+slider13bus busid pat = (pF "slider13" pat) # (pI "^slider13" busid)+slider13recv :: Pattern Int -> ControlPattern+slider13recv busid = pI "^slider13" busid++-- | +slider14 :: Pattern Double -> ControlPattern+slider14 = pF "slider14"+slider14Take :: String -> [Double] -> ControlPattern+slider14Take name xs = pStateListF "slider14" name xs+slider14Count :: String -> ControlPattern+slider14Count name = pStateF "slider14" name (maybe 0 (+1))+slider14CountTo :: String -> Pattern Double -> Pattern ValueMap+slider14CountTo name ipat = innerJoin $ (\i -> pStateF "slider14" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider14bus :: Pattern Int -> Pattern Double -> ControlPattern+slider14bus busid pat = (pF "slider14" pat) # (pI "^slider14" busid)+slider14recv :: Pattern Int -> ControlPattern+slider14recv busid = pI "^slider14" busid++-- | +slider15 :: Pattern Double -> ControlPattern+slider15 = pF "slider15"+slider15Take :: String -> [Double] -> ControlPattern+slider15Take name xs = pStateListF "slider15" name xs+slider15Count :: String -> ControlPattern+slider15Count name = pStateF "slider15" name (maybe 0 (+1))+slider15CountTo :: String -> Pattern Double -> Pattern ValueMap+slider15CountTo name ipat = innerJoin $ (\i -> pStateF "slider15" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider15bus :: Pattern Int -> Pattern Double -> ControlPattern+slider15bus busid pat = (pF "slider15" pat) # (pI "^slider15" busid)+slider15recv :: Pattern Int -> ControlPattern+slider15recv busid = pI "^slider15" busid++-- | +slider2 :: Pattern Double -> ControlPattern+slider2 = pF "slider2"+slider2Take :: String -> [Double] -> ControlPattern+slider2Take name xs = pStateListF "slider2" name xs+slider2Count :: String -> ControlPattern+slider2Count name = pStateF "slider2" name (maybe 0 (+1))+slider2CountTo :: String -> Pattern Double -> Pattern ValueMap+slider2CountTo name ipat = innerJoin $ (\i -> pStateF "slider2" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider2bus :: Pattern Int -> Pattern Double -> ControlPattern+slider2bus busid pat = (pF "slider2" pat) # (pI "^slider2" busid)+slider2recv :: Pattern Int -> ControlPattern+slider2recv busid = pI "^slider2" busid++-- | +slider3 :: Pattern Double -> ControlPattern+slider3 = pF "slider3"+slider3Take :: String -> [Double] -> ControlPattern+slider3Take name xs = pStateListF "slider3" name xs+slider3Count :: String -> ControlPattern+slider3Count name = pStateF "slider3" name (maybe 0 (+1))+slider3CountTo :: String -> Pattern Double -> Pattern ValueMap+slider3CountTo name ipat = innerJoin $ (\i -> pStateF "slider3" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider3bus :: Pattern Int -> Pattern Double -> ControlPattern+slider3bus busid pat = (pF "slider3" pat) # (pI "^slider3" busid)+slider3recv :: Pattern Int -> ControlPattern+slider3recv busid = pI "^slider3" busid++-- | +slider4 :: Pattern Double -> ControlPattern+slider4 = pF "slider4"+slider4Take :: String -> [Double] -> ControlPattern+slider4Take name xs = pStateListF "slider4" name xs+slider4Count :: String -> ControlPattern+slider4Count name = pStateF "slider4" name (maybe 0 (+1))+slider4CountTo :: String -> Pattern Double -> Pattern ValueMap+slider4CountTo name ipat = innerJoin $ (\i -> pStateF "slider4" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider4bus :: Pattern Int -> Pattern Double -> ControlPattern+slider4bus busid pat = (pF "slider4" pat) # (pI "^slider4" busid)+slider4recv :: Pattern Int -> ControlPattern+slider4recv busid = pI "^slider4" busid++-- | +slider5 :: Pattern Double -> ControlPattern+slider5 = pF "slider5"+slider5Take :: String -> [Double] -> ControlPattern+slider5Take name xs = pStateListF "slider5" name xs+slider5Count :: String -> ControlPattern+slider5Count name = pStateF "slider5" name (maybe 0 (+1))+slider5CountTo :: String -> Pattern Double -> Pattern ValueMap+slider5CountTo name ipat = innerJoin $ (\i -> pStateF "slider5" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider5bus :: Pattern Int -> Pattern Double -> ControlPattern+slider5bus busid pat = (pF "slider5" pat) # (pI "^slider5" busid)+slider5recv :: Pattern Int -> ControlPattern+slider5recv busid = pI "^slider5" busid++-- | +slider6 :: Pattern Double -> ControlPattern+slider6 = pF "slider6"+slider6Take :: String -> [Double] -> ControlPattern+slider6Take name xs = pStateListF "slider6" name xs+slider6Count :: String -> ControlPattern+slider6Count name = pStateF "slider6" name (maybe 0 (+1))+slider6CountTo :: String -> Pattern Double -> Pattern ValueMap+slider6CountTo name ipat = innerJoin $ (\i -> pStateF "slider6" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider6bus :: Pattern Int -> Pattern Double -> ControlPattern+slider6bus busid pat = (pF "slider6" pat) # (pI "^slider6" busid)+slider6recv :: Pattern Int -> ControlPattern+slider6recv busid = pI "^slider6" busid++-- | +slider7 :: Pattern Double -> ControlPattern+slider7 = pF "slider7"+slider7Take :: String -> [Double] -> ControlPattern+slider7Take name xs = pStateListF "slider7" name xs+slider7Count :: String -> ControlPattern+slider7Count name = pStateF "slider7" name (maybe 0 (+1))+slider7CountTo :: String -> Pattern Double -> Pattern ValueMap+slider7CountTo name ipat = innerJoin $ (\i -> pStateF "slider7" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider7bus :: Pattern Int -> Pattern Double -> ControlPattern+slider7bus busid pat = (pF "slider7" pat) # (pI "^slider7" busid)+slider7recv :: Pattern Int -> ControlPattern+slider7recv busid = pI "^slider7" busid++-- | +slider8 :: Pattern Double -> ControlPattern+slider8 = pF "slider8"+slider8Take :: String -> [Double] -> ControlPattern+slider8Take name xs = pStateListF "slider8" name xs+slider8Count :: String -> ControlPattern+slider8Count name = pStateF "slider8" name (maybe 0 (+1))+slider8CountTo :: String -> Pattern Double -> Pattern ValueMap+slider8CountTo name ipat = innerJoin $ (\i -> pStateF "slider8" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider8bus :: Pattern Int -> Pattern Double -> ControlPattern+slider8bus busid pat = (pF "slider8" pat) # (pI "^slider8" busid)+slider8recv :: Pattern Int -> ControlPattern+slider8recv busid = pI "^slider8" busid++-- | +slider9 :: Pattern Double -> ControlPattern+slider9 = pF "slider9"+slider9Take :: String -> [Double] -> ControlPattern+slider9Take name xs = pStateListF "slider9" name xs+slider9Count :: String -> ControlPattern+slider9Count name = pStateF "slider9" name (maybe 0 (+1))+slider9CountTo :: String -> Pattern Double -> Pattern ValueMap+slider9CountTo name ipat = innerJoin $ (\i -> pStateF "slider9" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++slider9bus :: Pattern Int -> Pattern Double -> ControlPattern+slider9bus busid pat = (pF "slider9" pat) # (pI "^slider9" busid)+slider9recv :: Pattern Int -> ControlPattern+slider9recv busid = pI "^slider9" busid++-- | Spectral smear+smear :: Pattern Double -> ControlPattern+smear = pF "smear"+smearTake :: String -> [Double] -> ControlPattern+smearTake name xs = pStateListF "smear" name xs+smearCount :: String -> ControlPattern+smearCount name = pStateF "smear" name (maybe 0 (+1))+smearCountTo :: String -> Pattern Double -> Pattern ValueMap+smearCountTo name ipat = innerJoin $ (\i -> pStateF "smear" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++smearbus :: Pattern Int -> Pattern Double -> ControlPattern+smearbus busid pat = (pF "smear" pat) # (pI "^smear" busid)+smearrecv :: Pattern Int -> ControlPattern+smearrecv busid = pI "^smear" busid++-- | +songPtr :: Pattern Double -> ControlPattern+songPtr = pF "songPtr"+songPtrTake :: String -> [Double] -> ControlPattern+songPtrTake name xs = pStateListF "songPtr" name xs+songPtrCount :: String -> ControlPattern+songPtrCount name = pStateF "songPtr" name (maybe 0 (+1))+songPtrCountTo :: String -> Pattern Double -> Pattern ValueMap+songPtrCountTo name ipat = innerJoin $ (\i -> pStateF "songPtr" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++songPtrbus :: Pattern Int -> Pattern Double -> ControlPattern+songPtrbus busid pat = (pF "songPtr" pat) # (pI "^songPtr" busid)+songPtrrecv :: Pattern Int -> ControlPattern+songPtrrecv busid = pI "^songPtr" busid++-- | a pattern of numbers which changes the speed of sample playback, i.e. a cheap way of changing pitch. Negative values will play the sample backwards!+speed :: Pattern Double -> ControlPattern+speed = pF "speed"+speedTake :: String -> [Double] -> ControlPattern+speedTake name xs = pStateListF "speed" name xs+speedCount :: String -> ControlPattern+speedCount name = pStateF "speed" name (maybe 0 (+1))+speedCountTo :: String -> Pattern Double -> Pattern ValueMap+speedCountTo name ipat = innerJoin $ (\i -> pStateF "speed" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++speedbus :: Pattern Int -> Pattern Double -> ControlPattern+speedbus _ _ = error $ "Control parameter 'speed' can't be sent to a bus."++-- | +squiz :: Pattern Double -> ControlPattern+squiz = pF "squiz"+squizTake :: String -> [Double] -> ControlPattern+squizTake name xs = pStateListF "squiz" name xs+squizCount :: String -> ControlPattern+squizCount name = pStateF "squiz" name (maybe 0 (+1))+squizCountTo :: String -> Pattern Double -> Pattern ValueMap+squizCountTo name ipat = innerJoin $ (\i -> pStateF "squiz" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++squizbus :: Pattern Int -> Pattern Double -> ControlPattern+squizbus busid pat = (pF "squiz" pat) # (pI "^squiz" busid)+squizrecv :: Pattern Int -> ControlPattern+squizrecv busid = pI "^squiz" busid++-- | +stepsPerOctave :: Pattern Double -> ControlPattern+stepsPerOctave = pF "stepsPerOctave"+stepsPerOctaveTake :: String -> [Double] -> ControlPattern+stepsPerOctaveTake name xs = pStateListF "stepsPerOctave" name xs+stepsPerOctaveCount :: String -> ControlPattern+stepsPerOctaveCount name = pStateF "stepsPerOctave" name (maybe 0 (+1))+stepsPerOctaveCountTo :: String -> Pattern Double -> Pattern ValueMap+stepsPerOctaveCountTo name ipat = innerJoin $ (\i -> pStateF "stepsPerOctave" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++stepsPerOctavebus :: Pattern Int -> Pattern Double -> ControlPattern+stepsPerOctavebus busid pat = (pF "stepsPerOctave" pat) # (pI "^stepsPerOctave" busid)+stepsPerOctaverecv :: Pattern Int -> ControlPattern+stepsPerOctaverecv busid = pI "^stepsPerOctave" busid++-- | +stutterdepth :: Pattern Double -> ControlPattern+stutterdepth = pF "stutterdepth"+stutterdepthTake :: String -> [Double] -> ControlPattern+stutterdepthTake name xs = pStateListF "stutterdepth" name xs+stutterdepthCount :: String -> ControlPattern+stutterdepthCount name = pStateF "stutterdepth" name (maybe 0 (+1))+stutterdepthCountTo :: String -> Pattern Double -> Pattern ValueMap+stutterdepthCountTo name ipat = innerJoin $ (\i -> pStateF "stutterdepth" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++stutterdepthbus :: Pattern Int -> Pattern Double -> ControlPattern+stutterdepthbus busid pat = (pF "stutterdepth" pat) # (pI "^stutterdepth" busid)+stutterdepthrecv :: Pattern Int -> ControlPattern+stutterdepthrecv busid = pI "^stutterdepth" busid++-- | +stuttertime :: Pattern Double -> ControlPattern+stuttertime = pF "stuttertime"+stuttertimeTake :: String -> [Double] -> ControlPattern+stuttertimeTake name xs = pStateListF "stuttertime" name xs+stuttertimeCount :: String -> ControlPattern+stuttertimeCount name = pStateF "stuttertime" name (maybe 0 (+1))+stuttertimeCountTo :: String -> Pattern Double -> Pattern ValueMap+stuttertimeCountTo name ipat = innerJoin $ (\i -> pStateF "stuttertime" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++stuttertimebus :: Pattern Int -> Pattern Double -> ControlPattern+stuttertimebus busid pat = (pF "stuttertime" pat) # (pI "^stuttertime" busid)+stuttertimerecv :: Pattern Int -> ControlPattern+stuttertimerecv busid = pI "^stuttertime" busid++-- | +sustain :: Pattern Double -> ControlPattern+sustain = pF "sustain"+sustainTake :: String -> [Double] -> ControlPattern+sustainTake name xs = pStateListF "sustain" name xs+sustainCount :: String -> ControlPattern+sustainCount name = pStateF "sustain" name (maybe 0 (+1))+sustainCountTo :: String -> Pattern Double -> Pattern ValueMap+sustainCountTo name ipat = innerJoin $ (\i -> pStateF "sustain" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++sustainbus :: Pattern Int -> Pattern Double -> ControlPattern+sustainbus _ _ = error $ "Control parameter 'sustain' can't be sent to a bus."++-- | +sustainpedal :: Pattern Double -> ControlPattern+sustainpedal = pF "sustainpedal"+sustainpedalTake :: String -> [Double] -> ControlPattern+sustainpedalTake name xs = pStateListF "sustainpedal" name xs+sustainpedalCount :: String -> ControlPattern+sustainpedalCount name = pStateF "sustainpedal" name (maybe 0 (+1))+sustainpedalCountTo :: String -> Pattern Double -> Pattern ValueMap+sustainpedalCountTo name ipat = innerJoin $ (\i -> pStateF "sustainpedal" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++sustainpedalbus :: Pattern Int -> Pattern Double -> ControlPattern+sustainpedalbus busid pat = (pF "sustainpedal" pat) # (pI "^sustainpedal" busid)+sustainpedalrecv :: Pattern Int -> ControlPattern+sustainpedalrecv busid = pI "^sustainpedal" busid++-- | for internal sound routing+to :: Pattern Double -> ControlPattern+to = pF "to"+toTake :: String -> [Double] -> ControlPattern+toTake name xs = pStateListF "to" name xs+toCount :: String -> ControlPattern+toCount name = pStateF "to" name (maybe 0 (+1))+toCountTo :: String -> Pattern Double -> Pattern ValueMap+toCountTo name ipat = innerJoin $ (\i -> pStateF "to" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++tobus :: Pattern Int -> Pattern Double -> ControlPattern+tobus busid pat = (pF "to" pat) # (pI "^to" busid)+torecv :: Pattern Int -> ControlPattern+torecv busid = pI "^to" busid++-- | for internal sound routing+toArg :: Pattern String -> ControlPattern+toArg = pS "toArg"+toArgTake :: String -> [Double] -> ControlPattern+toArgTake name xs = pStateListF "toArg" name xs+toArgbus :: Pattern Int -> Pattern String -> ControlPattern+toArgbus busid pat = (pS "toArg" pat) # (pI "^toArg" busid)+toArgrecv :: Pattern Int -> ControlPattern+toArgrecv busid = pI "^toArg" busid++-- | +tomdecay :: Pattern Double -> ControlPattern+tomdecay = pF "tomdecay"+tomdecayTake :: String -> [Double] -> ControlPattern+tomdecayTake name xs = pStateListF "tomdecay" name xs+tomdecayCount :: String -> ControlPattern+tomdecayCount name = pStateF "tomdecay" name (maybe 0 (+1))+tomdecayCountTo :: String -> Pattern Double -> Pattern ValueMap+tomdecayCountTo name ipat = innerJoin $ (\i -> pStateF "tomdecay" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++tomdecaybus :: Pattern Int -> Pattern Double -> ControlPattern+tomdecaybus busid pat = (pF "tomdecay" pat) # (pI "^tomdecay" busid)+tomdecayrecv :: Pattern Int -> ControlPattern+tomdecayrecv busid = pI "^tomdecay" busid++-- | Tremolo Audio DSP effect | params are 'tremolorate' and 'tremolodepth'+tremolodepth :: Pattern Double -> ControlPattern+tremolodepth = pF "tremolodepth"+tremolodepthTake :: String -> [Double] -> ControlPattern+tremolodepthTake name xs = pStateListF "tremolodepth" name xs+tremolodepthCount :: String -> ControlPattern+tremolodepthCount name = pStateF "tremolodepth" name (maybe 0 (+1))+tremolodepthCountTo :: String -> Pattern Double -> Pattern ValueMap+tremolodepthCountTo name ipat = innerJoin $ (\i -> pStateF "tremolodepth" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++tremolodepthbus :: Pattern Int -> Pattern Double -> ControlPattern+tremolodepthbus busid pat = (pF "tremolodepth" pat) # (pI "^tremolodepth" busid)+tremolodepthrecv :: Pattern Int -> ControlPattern+tremolodepthrecv busid = pI "^tremolodepth" busid++-- | Tremolo Audio DSP effect | params are 'tremolorate' and 'tremolodepth'+tremolorate :: Pattern Double -> ControlPattern+tremolorate = pF "tremolorate"+tremolorateTake :: String -> [Double] -> ControlPattern+tremolorateTake name xs = pStateListF "tremolorate" name xs+tremolorateCount :: String -> ControlPattern+tremolorateCount name = pStateF "tremolorate" name (maybe 0 (+1))+tremolorateCountTo :: String -> Pattern Double -> Pattern ValueMap+tremolorateCountTo name ipat = innerJoin $ (\i -> pStateF "tremolorate" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++tremoloratebus :: Pattern Int -> Pattern Double -> ControlPattern+tremoloratebus busid pat = (pF "tremolorate" pat) # (pI "^tremolorate" busid)+tremoloraterecv :: Pattern Int -> ControlPattern+tremoloraterecv busid = pI "^tremolorate" busid++-- | tube distortion+triode :: Pattern Double -> ControlPattern+triode = pF "triode"+triodeTake :: String -> [Double] -> ControlPattern+triodeTake name xs = pStateListF "triode" name xs+triodeCount :: String -> ControlPattern+triodeCount name = pStateF "triode" name (maybe 0 (+1))+triodeCountTo :: String -> Pattern Double -> Pattern ValueMap+triodeCountTo name ipat = innerJoin $ (\i -> pStateF "triode" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++triodebus :: Pattern Int -> Pattern Double -> ControlPattern+triodebus busid pat = (pF "triode" pat) # (pI "^triode" busid)+trioderecv :: Pattern Int -> ControlPattern+trioderecv busid = pI "^triode" busid++-- | +tsdelay :: Pattern Double -> ControlPattern+tsdelay = pF "tsdelay"+tsdelayTake :: String -> [Double] -> ControlPattern+tsdelayTake name xs = pStateListF "tsdelay" name xs+tsdelayCount :: String -> ControlPattern+tsdelayCount name = pStateF "tsdelay" name (maybe 0 (+1))+tsdelayCountTo :: String -> Pattern Double -> Pattern ValueMap+tsdelayCountTo name ipat = innerJoin $ (\i -> pStateF "tsdelay" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++tsdelaybus :: Pattern Int -> Pattern Double -> ControlPattern+tsdelaybus busid pat = (pF "tsdelay" pat) # (pI "^tsdelay" busid)+tsdelayrecv :: Pattern Int -> ControlPattern+tsdelayrecv busid = pI "^tsdelay" busid++-- | +uid :: Pattern Double -> ControlPattern+uid = pF "uid"+uidTake :: String -> [Double] -> ControlPattern+uidTake name xs = pStateListF "uid" name xs+uidCount :: String -> ControlPattern+uidCount name = pStateF "uid" name (maybe 0 (+1))+uidCountTo :: String -> Pattern Double -> Pattern ValueMap+uidCountTo name ipat = innerJoin $ (\i -> pStateF "uid" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++uidbus :: Pattern Int -> Pattern Double -> ControlPattern+uidbus busid pat = (pF "uid" pat) # (pI "^uid" busid)+uidrecv :: Pattern Int -> ControlPattern+uidrecv busid = pI "^uid" busid++-- | used in conjunction with `speed`, accepts values of "r" (rate, default behavior), "c" (cycles), or "s" (seconds). Using `unit "c"` means `speed` will be interpreted in units of cycles, e.g. `speed "1"` means samples will be stretched to fill a cycle. Using `unit "s"` means the playback speed will be adjusted so that the duration is the number of seconds specified by `speed`.+unit :: Pattern String -> ControlPattern+unit = pS "unit"+unitTake :: String -> [Double] -> ControlPattern+unitTake name xs = pStateListF "unit" name xs+unitbus :: Pattern Int -> Pattern String -> ControlPattern+unitbus _ _ = error $ "Control parameter 'unit' can't be sent to a bus."++-- | +val :: Pattern Double -> ControlPattern+val = pF "val"+valTake :: String -> [Double] -> ControlPattern+valTake name xs = pStateListF "val" name xs+valCount :: String -> ControlPattern+valCount name = pStateF "val" name (maybe 0 (+1))+valCountTo :: String -> Pattern Double -> Pattern ValueMap+valCountTo name ipat = innerJoin $ (\i -> pStateF "val" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++valbus :: Pattern Int -> Pattern Double -> ControlPattern+valbus busid pat = (pF "val" pat) # (pI "^val" busid)+valrecv :: Pattern Int -> ControlPattern+valrecv busid = pI "^val" busid++-- | +vcfegint :: Pattern Double -> ControlPattern+vcfegint = pF "vcfegint"+vcfegintTake :: String -> [Double] -> ControlPattern+vcfegintTake name xs = pStateListF "vcfegint" name xs+vcfegintCount :: String -> ControlPattern+vcfegintCount name = pStateF "vcfegint" name (maybe 0 (+1))+vcfegintCountTo :: String -> Pattern Double -> Pattern ValueMap+vcfegintCountTo name ipat = innerJoin $ (\i -> pStateF "vcfegint" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++vcfegintbus :: Pattern Int -> Pattern Double -> ControlPattern+vcfegintbus busid pat = (pF "vcfegint" pat) # (pI "^vcfegint" busid)+vcfegintrecv :: Pattern Int -> ControlPattern+vcfegintrecv busid = pI "^vcfegint" busid++-- | +vcoegint :: Pattern Double -> ControlPattern+vcoegint = pF "vcoegint"+vcoegintTake :: String -> [Double] -> ControlPattern+vcoegintTake name xs = pStateListF "vcoegint" name xs+vcoegintCount :: String -> ControlPattern+vcoegintCount name = pStateF "vcoegint" name (maybe 0 (+1))+vcoegintCountTo :: String -> Pattern Double -> Pattern ValueMap+vcoegintCountTo name ipat = innerJoin $ (\i -> pStateF "vcoegint" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++vcoegintbus :: Pattern Int -> Pattern Double -> ControlPattern+vcoegintbus busid pat = (pF "vcoegint" pat) # (pI "^vcoegint" busid)+vcoegintrecv :: Pattern Int -> ControlPattern+vcoegintrecv busid = pI "^vcoegint" busid++-- | +velocity :: Pattern Double -> ControlPattern+velocity = pF "velocity"+velocityTake :: String -> [Double] -> ControlPattern+velocityTake name xs = pStateListF "velocity" name xs+velocityCount :: String -> ControlPattern+velocityCount name = pStateF "velocity" name (maybe 0 (+1))+velocityCountTo :: String -> Pattern Double -> Pattern ValueMap+velocityCountTo name ipat = innerJoin $ (\i -> pStateF "velocity" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++velocitybus :: Pattern Int -> Pattern Double -> ControlPattern+velocitybus busid pat = (pF "velocity" pat) # (pI "^velocity" busid)+velocityrecv :: Pattern Int -> ControlPattern+velocityrecv busid = pI "^velocity" busid++-- | +voice :: Pattern Double -> ControlPattern+voice = pF "voice"+voiceTake :: String -> [Double] -> ControlPattern+voiceTake name xs = pStateListF "voice" name xs+voiceCount :: String -> ControlPattern+voiceCount name = pStateF "voice" name (maybe 0 (+1))+voiceCountTo :: String -> Pattern Double -> Pattern ValueMap+voiceCountTo name ipat = innerJoin $ (\i -> pStateF "voice" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++voicebus :: Pattern Int -> Pattern Double -> ControlPattern+voicebus busid pat = (pF "voice" pat) # (pI "^voice" busid)+voicerecv :: Pattern Int -> ControlPattern+voicerecv busid = pI "^voice" busid++-- | formant filter to make things sound like vowels, a pattern of either `a`, `e`, `i`, `o` or `u`. Use a rest (`~`) for no effect.+vowel :: Pattern String -> ControlPattern+vowel = pS "vowel"+vowelTake :: String -> [Double] -> ControlPattern+vowelTake name xs = pStateListF "vowel" name xs+vowelbus :: Pattern Int -> Pattern String -> ControlPattern+vowelbus busid pat = (pS "vowel" pat) # (pI "^vowel" busid)+vowelrecv :: Pattern Int -> ControlPattern+vowelrecv busid = pI "^vowel" busid++-- | +waveloss :: Pattern Double -> ControlPattern+waveloss = pF "waveloss"+wavelossTake :: String -> [Double] -> ControlPattern+wavelossTake name xs = pStateListF "waveloss" name xs+wavelossCount :: String -> ControlPattern+wavelossCount name = pStateF "waveloss" name (maybe 0 (+1))+wavelossCountTo :: String -> Pattern Double -> Pattern ValueMap+wavelossCountTo name ipat = innerJoin $ (\i -> pStateF "waveloss" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat++wavelossbus :: Pattern Int -> Pattern Double -> ControlPattern+wavelossbus busid pat = (pF "waveloss" pat) # (pI "^waveloss" busid)+wavelossrecv :: Pattern Int -> ControlPattern+wavelossrecv busid = pI "^waveloss" busid++-- | +xsdelay :: Pattern Double -> ControlPattern+xsdelay = pF "xsdelay"+xsdelayTake :: String -> [Double] -> ControlPattern+xsdelayTake name xs = pStateListF "xsdelay" name xs+xsdelayCount :: String -> ControlPattern+xsdelayCount name = pStateF "xsdelay" name (maybe 0 (+1))+xsdelayCountTo :: String -> Pattern Double -> Pattern ValueMap+xsdelayCountTo name ipat = innerJoin $ (\i -> pStateF "xsdelay" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat+ xsdelaybus :: Pattern Int -> Pattern Double -> ControlPattern xsdelaybus busid pat = (pF "xsdelay" pat) # (pI "^xsdelay" busid) xsdelayrecv :: Pattern Int -> ControlPattern
src/Sound/Tidal/ParseBP.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings, TypeSynonymInstances, FlexibleInstances, CPP, DeriveFunctor #-}+{-# LANGUAGE OverloadedStrings, FlexibleInstances, CPP, DeriveFunctor #-} {-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wall -fno-warn-orphans -fno-warn-unused-do-bind #-} @@ -25,6 +25,7 @@ import Control.Applicative () import qualified Control.Exception as E+import Data.Bifunctor (first) import Data.Colour import Data.Colour.Names import Data.Functor.Identity (Identity)@@ -42,6 +43,7 @@ import Sound.Tidal.UI import Sound.Tidal.Core import Sound.Tidal.Chords (chordTable)+import Sound.Tidal.Utils (fromRight) data TidalParseError = TidalParseError {parsecError :: ParseError, code :: String@@ -78,7 +80,7 @@ deriving (Show, Functor) tShowList :: (Show a) => [TPat a] -> String-tShowList vs = "[" ++ (intercalate "," $ map tShow vs) ++ "]"+tShowList vs = "[" ++ intercalate "," (map tShow vs) ++ "]" tShow :: (Show a) => TPat a -> String tShow (TPat_Atom _ v) = "pure " ++ show v@@ -92,8 +94,8 @@ tShow (TPat_Euclid a b c v) = "doEuclid (" ++ intercalate ") (" (map tShow [a,b,c]) ++ ") $ " ++ tShow v tShow (TPat_Stack vs) = "stack " ++ tShowList vs -tShow (TPat_Polyrhythm mSteprate vs) = "stack [" ++ (intercalate ", " (map adjust_speed pats)) ++ "]"- where adjust_speed (sz, pat) = "(fast (" ++ (steprate ++ "/" ++ (show sz)) ++ ") $ " ++ pat ++ ")"+tShow (TPat_Polyrhythm mSteprate vs) = "stack [" ++ intercalate ", " (map adjust_speed pats) ++ "]"+ where adjust_speed (sz, pat) = "(fast (" ++ (steprate ++ "/" ++ show sz) ++ ") $ " ++ pat ++ ")" steprate :: String steprate = maybe base_first tShow mSteprate base_first | null pats = "0"@@ -143,9 +145,9 @@ resolve_size :: [TPat a] -> [(Rational, TPat a)] resolve_size [] = []-resolve_size ((TPat_Elongate r p):ps) = (r, p):(resolve_size ps)-resolve_size ((TPat_Repeat n p):ps) = replicate n (1,p) ++ (resolve_size ps)-resolve_size (p:ps) = (1,p):(resolve_size ps)+resolve_size ((TPat_Elongate r p):ps) = (r, p):resolve_size ps+resolve_size ((TPat_Repeat n p):ps) = replicate n (1,p) ++ resolve_size ps+resolve_size (p:ps) = (1,p):resolve_size ps steps_tpat :: (Show a) => TPat a -> (Rational, String)@@ -153,15 +155,15 @@ steps_tpat a = (1, tShow a) steps_seq :: (Show a) => [TPat a] -> (Rational, String)-steps_seq xs = (total_size, "timeCat [" ++ (intercalate "," $ map (\(r,s) -> "(" ++ show r ++ ", " ++ s ++ ")") sized_pats) ++ "]")+steps_seq xs = (total_size, "timeCat [" ++ intercalate "," (map (\(r,s) -> "(" ++ show r ++ ", " ++ s ++ ")") sized_pats) ++ "]") where sized_pats = steps_size xs total_size = sum $ map fst sized_pats steps_size :: Show a => [TPat a] -> [(Rational, String)] steps_size [] = []-steps_size ((TPat_Elongate r p):ps) = (r, tShow p):(steps_size ps)-steps_size ((TPat_Repeat n p):ps) = replicate n (1, tShow p) ++ (steps_size ps)-steps_size (p:ps) = (1,tShow p):(steps_size ps)+steps_size ((TPat_Elongate r p):ps) = (r, tShow p):steps_size ps+steps_size ((TPat_Repeat n p):ps) = replicate n (1, tShow p) ++ steps_size ps+steps_size (p:ps) = (1,tShow p):steps_size ps parseBP :: (Enumerable a, Parseable a) => String -> Either ParseError (Pattern a) parseBP s = toPat <$> parseTPat s@@ -206,7 +208,7 @@ instance Enumerable Double where fromTo = enumFromTo' fromThenTo = enumFromThenTo'- + instance Parseable Note where tPatParser = pNote doEuclid = euclidOff@@ -339,7 +341,7 @@ a <- pPart f spaces do- symbol ".."+ try $ symbol ".." b <- pPart f return $ TPat_EnumFromTo a b <|> pElongate a@@ -358,7 +360,7 @@ where (foot, pats') = takeFoot pats takeFoot [] = ([], []) takeFoot (TPat_Foot:pats'') = ([], pats'')- takeFoot (pat:pats'') = (\(a,b) -> (pat:a,b)) $ takeFoot pats''+ takeFoot (pat:pats'') = first (pat:) $ takeFoot pats'' pRepeat :: TPat a -> MyParser (TPat a) pRepeat a = do es <- many1 $ do char '!'@@ -442,7 +444,7 @@ <|> return (TPat_Atom Nothing f) <|> do TPat_Stack . map (TPat_Atom Nothing) <$> parseChord- + pNote :: MyParser (TPat Note) pNote = wrapPos $ fmap (fmap Note) $ do f <- choice [intOrFloat, parseNote] <?> "float" do TPat_Stack . map (TPat_Atom Nothing . (+ f)) <$> parseChord@@ -479,12 +481,17 @@ name <- many1 $ letter <|> digit let chord = fromMaybe [0] $ lookup name chordTable do char '\''- notFollowedBy space <?> "chord range or 'i'"+ notFollowedBy space <?> "chord range or 'i' or 'o'" let n = length chord i <- option n (fromIntegral <$> integer) j <- length <$> many (char 'i')+ o <- length <$> many (char 'o') let chord' = take i $ drop j $ concatMap (\x -> map (+ x) chord) [0,12..]- return chord'+ -- open voiced chords+ let chordo' = if o > 0 then+ [ (chord' !! 0 - 12), (chord' !! 2 - 12), (chord' !! 1) ] ++ reverse (take (length chord' - 3) (reverse chord'))+ else chord'+ return chordo' <|> return chord parseNote :: Num a => MyParser a@@ -510,7 +517,7 @@ ] fromNote :: Num a => Pattern String -> Pattern a-fromNote pat = either (const 0) id . runParser parseNote 0 "" <$> pat+fromNote pat = fromRight 0 . runParser parseNote 0 "" <$> pat pColour :: MyParser (TPat ColourD) pColour = wrapPos $ do name <- many1 letter <?> "colour name"
src/Sound/Tidal/Pattern.hs view
@@ -1,7 +1,8 @@-{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, TypeSynonymInstances #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# OPTIONS_GHC -fno-warn-orphans #-} {-@@ -22,371 +23,78 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. -} -module Sound.Tidal.Pattern where+module Sound.Tidal.Pattern (module Sound.Tidal.Pattern,+ module Sound.Tidal.Time+ )+where import Prelude hiding ((<*), (*>)) import Control.Applicative (liftA2)-import Data.Data (Data) -- toConstr import GHC.Generics-import Data.List (delete, findIndex, sort)+import Control.DeepSeq (NFData)+import Control.Monad ((>=>)) import qualified Data.Map.Strict as Map import Data.Maybe (isJust, fromJust, catMaybes, mapMaybe)-import Data.Typeable (Typeable)-import Control.DeepSeq (NFData)+import Data.List (delete, findIndex, sort) import Data.Word (Word8)---------------------------------------------------------------------------- * Types---- | Time is rational-type Time = Rational---- | Note is Double, but with a different parsing-newtype Note = Note { unNote :: Double } deriving (Typeable, Data, Generic, Eq, Ord, Show, Enum, Num, Fractional, Floating, Real)-instance NFData Note---- | The 'sam' (start of cycle) for the given time value-sam :: Time -> Time-sam = fromIntegral . (floor :: Time -> Int)---- | Turns a number into a (rational) time value. An alias for 'toRational'.-toTime :: Real a => a -> Rational-toTime = toRational---- | The end point of the current cycle (and starting point of the next cycle)-nextSam :: Time -> Time-nextSam = (1+) . sam---- | The position of a time value relative to the start of its cycle.-cyclePos :: Time -> Time-cyclePos t = t - sam t---- | An arc of time, with a start time (or onset) and a stop time (or offset)-data ArcF a = Arc- { start :: a- , stop :: a- } deriving (Eq, Ord, Functor, Show, Generic)--type Arc = ArcF Time--instance NFData a => NFData (ArcF a)--instance Num a => Num (ArcF a) where- negate = fmap negate- (+) = liftA2 (+)- (*) = liftA2 (*)- fromInteger = pure . fromInteger- abs = fmap abs- signum = fmap signum--instance (Fractional a) => Fractional (ArcF a) where- recip = fmap recip- fromRational = pure . fromRational--sect :: Arc -> Arc -> Arc-sect (Arc s e) (Arc s' e') = Arc (max s s') (min e e')---- | convex hull union-hull :: Arc -> Arc -> Arc-hull (Arc s e) (Arc s' e') = Arc (min s s') (max e e')---- | @subArc i j@ is the timespan that is the intersection of @i@ and @j@.--- intersection--- The definition is a bit fiddly as results might be zero-width, but--- not at the end of an non-zero-width arc - e.g. (0,1) and (1,2) do--- not intersect, but (1,1) (1,1) does.-subArc :: Arc -> Arc -> Maybe Arc-subArc a@(Arc s e) b@(Arc s' e')- | and [s'' == e'', s'' == e, s < e] = Nothing- | and [s'' == e'', s'' == e', s' < e'] = Nothing- | s'' <= e'' = Just (Arc s'' e'')- | otherwise = Nothing- where (Arc s'' e'') = sect a b--subMaybeArc :: Maybe Arc -> Maybe Arc -> Maybe (Maybe Arc)-subMaybeArc (Just a) (Just b) = do sa <- subArc a b- return $ Just sa-subMaybeArc _ _ = Just Nothing--instance Applicative ArcF where- pure t = Arc t t- (<*>) (Arc sf ef) (Arc sx ex) = Arc (sf sx) (ef ex)---- | The arc of the whole cycle that the given time value falls within-timeToCycleArc :: Time -> Arc-timeToCycleArc t = Arc (sam t) (sam t + 1)---- | Shifts an arc to the equivalent one that starts during cycle zero-cycleArc :: Arc -> Arc-cycleArc (Arc s e) = Arc (cyclePos s) (cyclePos s + (e-s))---- | A list of cycle numbers which are included in the given arc-cyclesInArc :: Integral a => Arc -> [a]-cyclesInArc (Arc s e)- | s > e = []- | s == e = [floor s]- | otherwise = [floor s .. ceiling e-1]---- | A list of arcs of the whole cycles which are included in the given arc-cycleArcsInArc :: Arc -> [Arc]-cycleArcsInArc = map (timeToCycleArc . (toTime :: Int -> Time)) . cyclesInArc---- | Splits the given 'Arc' into a list of 'Arc's, at cycle boundaries.-arcCycles :: Arc -> [Arc]-arcCycles (Arc s e) | s >= e = []- | sam s == sam e = [Arc s e]- | otherwise = Arc s (nextSam s) : arcCycles (Arc (nextSam s) e)---- | Like arcCycles, but returns zero-width arcs-arcCyclesZW :: Arc -> [Arc]-arcCyclesZW (Arc s e) | s == e = [Arc s e]- | otherwise = arcCycles (Arc s e)---- | Similar to 'fmap' but time is relative to the cycle (i.e. the--- sam of the start of the arc)-mapCycle :: (Time -> Time) -> Arc -> Arc-mapCycle f (Arc s e) = Arc (sam' + f (s - sam')) (sam' + f (e - sam'))- where sam' = sam s---- | @isIn a t@ is @True@ if @t@ is inside--- the arc represented by @a@.-isIn :: Arc -> Time -> Bool-isIn (Arc s e) t = t >= s && t < e--data Context = Context {contextPosition :: [((Int, Int), (Int, Int))]}- deriving (Eq, Ord, Generic)--instance NFData Context--combineContexts :: [Context] -> Context-combineContexts = Context . concatMap contextPosition--setContext :: Context -> Pattern a -> Pattern a-setContext c pat = withEvents (map (\e -> e {context = c})) pat--withContext :: (Context -> Context) -> Pattern a -> Pattern a-withContext f pat = withEvents (map (\e -> e {context = f $ context e})) pat--deltaContext :: Int -> Int -> Pattern a -> Pattern a-deltaContext column line pat = withEvents (map (\e -> e {context = f $ context e})) pat- where f :: Context -> Context- f (Context xs) = Context $ map (\((bx,by), (ex,ey)) -> ((bx+column,by+line), (ex+column,ey+line))) xs---- | 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.-data EventF a b = Event- { context :: Context- , whole :: Maybe a- , part :: a- , value :: b- } deriving (Eq, Ord, Functor, Generic)--type Event a = EventF (ArcF Time) a--instance (NFData a, NFData b) => NFData (EventF a b)--{-instance Bifunctor EventF where- bimap f g (Event w p e) = Event (f w) (f p) (g e)--}---isAnalog :: Event a -> Bool-isAnalog (Event {whole = Nothing}) = True-isAnalog _ = False--isDigital :: Event a -> Bool-isDigital = not . isAnalog---- | `True` if an `Event`'s starts is within given `Arc`-onsetIn :: Arc -> Event a -> Bool-onsetIn a e = isIn a (wholeStart e)---- | Compares two lists of events, attempting to combine fragmented events in the process--- for a 'truer' compare-compareDefrag :: (Ord a) => [Event a] -> [Event a] -> Bool-compareDefrag as bs = sort (defragParts as) == sort (defragParts bs)---- | Returns a list of events, with any adjacent parts of the same whole combined-defragParts :: Eq a => [Event a] -> [Event a]-defragParts [] = []-defragParts [e] = [e]-defragParts (e:es) | isJust i = defraged : defragParts (delete e' es)- | otherwise = e : defragParts es- where i = findIndex (isAdjacent e) es- e' = es !! fromJust i- defraged = Event (context e) (whole e) u (value e)- u = hull (part e) (part e')---- | Returns 'True' if the two given events are adjacent parts of the same whole-isAdjacent :: Eq a => Event a -> Event a -> Bool-isAdjacent e e' = (whole e == whole e')- && (value e == value e')- && ((stop (part e) == start (part e'))- ||- (stop (part e') == start (part e))- )--wholeOrPart :: Event a -> Arc-wholeOrPart (Event {whole = Just a}) = a-wholeOrPart e = part e---- | Get the onset of an event's 'whole'-wholeStart :: Event a -> Time-wholeStart = start . wholeOrPart---- | Get the offset of an event's 'whole'-wholeStop :: Event a -> Time-wholeStop = stop . wholeOrPart---- | Get the onset of an event's 'whole'-eventPartStart :: Event a -> Time-eventPartStart = start . part---- | Get the offset of an event's 'part'-eventPartStop :: Event a -> Time-eventPartStop = stop . part---- | Get the timespan of an event's 'part'-eventPart :: Event a -> Arc-eventPart = part--eventValue :: Event a -> a-eventValue = value+import Data.Data (Data) -- toConstr+import Data.Typeable (Typeable) -eventHasOnset :: Event a -> Bool-eventHasOnset e | isAnalog e = False- | otherwise = start (fromJust $ whole e) == start (part e)+import Sound.Tidal.Time --- TODO - Is this used anywhere? Just tests, it seems--- TODO - support 'context' field-toEvent :: (((Time, Time), (Time, Time)), a) -> Event a-toEvent (((ws, we), (ps, pe)), v) = Event (Context []) (Just $ Arc ws we) (Arc ps pe) v+------------------------------------------------------------------------+-- * Types -- | an Arc and some named control values data State = State {arc :: Arc,- controls :: StateMap+ controls :: ValueMap } --- | A function that represents events taking place over time-type Query a = (State -> [Event a])---- | A datatype that's basically a query-data Pattern a = Pattern {query :: Query a}+-- | A datatype representing events taking place over time+data Pattern a = Pattern {query :: State -> [Event a]} deriving Generic--data Value = VS { svalue :: String }- | VF { fvalue :: Double }- | VN { nvalue :: Note }- | VR { rvalue :: Rational }- | VI { ivalue :: Int }- | VB { bvalue :: Bool }- | VX { xvalue :: [Word8] } -- Used for OSC 'blobs'- deriving (Typeable, Data, Generic)--class Valuable a where- toValue :: a -> Value--instance NFData Value--instance Valuable String where- toValue a = VS a-instance Valuable Double where- toValue a = VF a-instance Valuable Rational where- toValue a = VR a-instance Valuable Int where- toValue a = VI a-instance Valuable Bool where- toValue a = VB a-instance Valuable [Word8] where- toValue a = VX a--instance Eq Value where- (VS x) == (VS y) = x == y- (VB x) == (VB y) = x == y- (VF x) == (VF y) = x == y- (VI x) == (VI y) = x == y- (VN x) == (VN y) = x == y- (VR x) == (VR y) = x == y- (VX x) == (VX y) = x == y- - (VF x) == (VI y) = x == fromIntegral y- (VI y) == (VF x) = x == fromIntegral y-- (VF x) == (VR y) = toRational x == y- (VR y) == (VF x) = toRational x == y- (VI x) == (VR y) = toRational x == y- (VR y) == (VI x) = toRational x == y-- _ == _ = False- -instance Ord Value where- compare (VS x) (VS y) = compare x y- compare (VB x) (VB y) = compare x y- compare (VF x) (VF y) = compare x y- compare (VN x) (VN y) = compare (unNote x) (unNote y)- compare (VI x) (VI y) = compare x y- compare (VR x) (VR y) = compare x y- compare (VX x) (VX y) = compare x y-- compare (VS _) _ = LT- compare _ (VS _) = GT- compare (VB _) _ = LT- compare _ (VB _) = GT- compare (VX _) _ = LT- compare _ (VX _) = GT-- compare (VF x) (VI y) = compare x (fromIntegral y)- compare (VI x) (VF y) = compare (fromIntegral x) y-- compare (VR x) (VI y) = compare x (fromIntegral y)- compare (VI x) (VR y) = compare (fromIntegral x) y-- compare (VF x) (VR y) = compare x (fromRational y)- compare (VR x) (VF y) = compare (fromRational x) y+instance NFData a => NFData (Pattern a) - compare (VN x) (VI y) = compare x (fromIntegral y)- compare (VI x) (VN y) = compare (fromIntegral x) y+-- type StateMap = Map.Map String (Pattern Value)+type ControlPattern = Pattern ValueMap - compare (VN x) (VR y) = compare (unNote x) (fromRational y)- compare (VR x) (VN y) = compare (fromRational x) (unNote y)+-- * Functor - compare (VF x) (VN y) = compare x (unNote y)- compare (VN x) (VF y) = compare (unNote x) y+instance Functor Pattern where+ -- | apply a function to all the values in a pattern+ fmap f p = p {query = fmap (fmap f) . query p} +-- * Applicative and friends -type StateMap = Map.Map String (Pattern Value)-type ControlMap = Map.Map String Value-type ControlPattern = Pattern ControlMap+instance Applicative Pattern where+ -- | Repeat the given value once per cycle, forever+ pure v = Pattern $ \(State a _) ->+ map (\a' -> Event (Context []) (Just a') (sect a a') v) $ cycleArcsInArc a ---------------------------------------------------------------------------- * Instances+ (<*>) = applyPatToPatBoth -instance NFData a => NFData (Pattern a)+-- | Like <*>, but the 'wholes' come from the left+(<*) :: Pattern (a -> b) -> Pattern a -> Pattern b+(<*) = applyPatToPatLeft -instance Functor Pattern where- -- | apply a function to all the values in a pattern- fmap f p = p {query = fmap (fmap f) . query p}+-- | Like <*>, but the 'wholes' come from the right+(*>) :: Pattern (a -> b) -> Pattern a -> Pattern b+(*>) = applyPatToPatRight +infixl 4 <*, *> applyPatToPat :: (Maybe Arc -> Maybe Arc -> Maybe (Maybe Arc)) -> Pattern (a -> b) -> Pattern a -> Pattern b applyPatToPat combineWholes pf px = Pattern q where q st = catMaybes $ concatMap match $ query pf st where- match (ef@(Event (Context c) _ fPart f)) =+ match ef@(Event (Context c) _ fPart f) = map (\ex@(Event (Context c') _ xPart x) -> do whole' <- combineWholes (whole ef) (whole ex) part' <- subArc fPart xPart return (Event (Context $ c ++ c') whole' part' (f x)) )- (query px $ st {arc = (wholeOrPart ef)})--instance Applicative Pattern where- -- | Repeat the given value once per cycle, forever- pure v = Pattern $ \(State a _) ->- map (\a' -> Event (Context []) (Just a') (sect a a') v) $ cycleArcsInArc a-- (<*>) = applyPatToPatBoth+ (query px $ st {arc = wholeOrPart ef}) applyPatToPatBoth :: Pattern (a -> b) -> Pattern a -> Pattern b applyPatToPatBoth pf px = Pattern q@@ -397,7 +105,7 @@ -- match digital events from pf with digital events from px match ef@(Event _ (Just fWhole) _ _) = map (withFX ef) (query (filterDigital px) $ st {arc = fWhole}) -- digital -- match analog events from px (constrained above) with digital events from px- matchX ex@(Event _ Nothing fPart _) = map (\ef -> withFX ef ex) (query (filterDigital pf) $ st {arc = fPart}) -- digital+ matchX ex@(Event _ Nothing fPart _) = map (`withFX` ex) (query (filterDigital pf) $ st {arc = fPart}) -- digital matchX _ = error "can't happen" withFX ef ex = do whole' <- subMaybeArc (whole ef) (whole ex) part' <- subArc (part ef) (part ex)@@ -405,7 +113,7 @@ applyPatToPatLeft :: Pattern (a -> b) -> Pattern a -> Pattern b applyPatToPatLeft pf px = Pattern q- where q st = catMaybes $ (concatMap match $ query pf st)+ where q st = catMaybes $ concatMap match $ query pf st where match ef = map (withFX ef) (query px $ st {arc = wholeOrPart ef}) withFX ef ex = do let whole' = whole ef@@ -414,23 +122,17 @@ applyPatToPatRight :: Pattern (a -> b) -> Pattern a -> Pattern b applyPatToPatRight pf px = Pattern q- where q st = catMaybes $ (concatMap match $ query px st)+ where q st = catMaybes $ concatMap match $ query px st where- match ex = map (\ef -> withFX ef ex) (query pf $ st {arc = wholeOrPart ex})+ match ex = map (`withFX` ex) (query pf $ st {arc = wholeOrPart ex}) withFX ef ex = do let whole' = whole ex part' <- subArc (part ef) (part ex) return (Event (combineContexts [context ef, context ex]) whole' part' (value ef $ value ex)) ---- | Like <*>, but the 'wholes' come from the left-(<*) :: Pattern (a -> b) -> Pattern a -> Pattern b-(<*) = applyPatToPatLeft---- | Like <*>, but the 'wholes' come from the right-(*>) :: Pattern (a -> b) -> Pattern a -> Pattern b-(*>) = applyPatToPatRight+-- * Monad and friends -infixl 4 <*, *>+-- Note there are four ways of joining - the default 'unwrap' used by @>>=@, as well+-- as innerJoin, outerJoin and squeezeJoin. instance Monad Pattern where return = pure@@ -501,29 +203,11 @@ p' <- subArc oPart iPart return (Event (combineContexts [iContext, oContext]) w' p' v) +-- | * Patterns as numbers+ noOv :: String -> a noOv meth = error $ meth ++ ": not supported for patterns" -class TolerantEq a where- (~==) :: a -> a -> Bool--instance TolerantEq Value where- (VS a) ~== (VS b) = a == b- (VI a) ~== (VI b) = a == b- (VR a) ~== (VR b) = a == b- (VF a) ~== (VF b) = abs (a - b) < 0.000001- _ ~== _ = False--instance TolerantEq ControlMap where- a ~== b = Map.differenceWith (\a' b' -> if a' ~== b' then Nothing else Just a') a b == Map.empty--instance TolerantEq (Event ControlMap) where- (Event _ w p x) ~== (Event _ w' p' x') = w == w' && p == p' && x ~== x'--instance TolerantEq a => TolerantEq [a] where- as ~== bs = (length as == length bs) && all (uncurry (~==)) (zip as bs)-- instance Eq (Pattern a) where (==) = noOv "(==)" @@ -606,7 +290,7 @@ isIEEE = noOv "isIEEE" atan2 = liftA2 atan2 -instance Num ControlMap where+instance Num ValueMap where negate = (applyFIS negate negate id <$>) (+) = Map.unionWith (fNum2 (+) (+)) (*) = Map.unionWith (fNum2 (*) (*))@@ -614,7 +298,7 @@ signum = (applyFIS signum signum id <$>) abs = (applyFIS abs abs id <$>) -instance Fractional ControlMap where+instance Fractional ValueMap where recip = fmap (applyFIS recip id id) fromRational r = Map.singleton "speed" $ VF (fromRational r) @@ -672,59 +356,8 @@ withPart :: (Arc -> Arc) -> Pattern a -> Pattern a withPart f = withEvent (\(Event c w p v) -> Event c w (f p) v) --- | Apply one of three functions to a Value, depending on its type-applyFIS :: (Double -> Double) -> (Int -> Int) -> (String -> String) -> Value -> Value-applyFIS f _ _ (VF f') = VF (f f')-applyFIS f _ _ (VN (Note f')) = VN (Note $ f f')-applyFIS _ f _ (VI i) = VI (f i)-applyFIS _ _ f (VS s) = VS (f s)-applyFIS _ _ _ v = v---- | Apply one of two functions to a pair of Values, depending on their types (int--- or float; strings and rationals are ignored)-fNum2 :: (Int -> Int -> Int) -> (Double -> Double -> Double) -> Value -> Value -> Value-fNum2 fInt _ (VI a) (VI b) = VI (fInt a b)-fNum2 _ fFloat (VF a) (VF b) = VF (fFloat a b)-fNum2 _ fFloat (VN (Note a)) (VN (Note b)) = VN (Note $ fFloat a b)-fNum2 _ fFloat (VI a) (VF b) = VF (fFloat (fromIntegral a) b)-fNum2 _ fFloat (VF a) (VI b) = VF (fFloat a (fromIntegral b))-fNum2 _ _ x _ = x--getI :: Value -> Maybe Int-getI (VI i) = Just i-getI (VR x) = Just $ floor x-getI (VF x) = Just $ floor x-getI _ = Nothing--getF :: Value -> Maybe Double-getF (VF f) = Just f-getF (VR x) = Just $ fromRational x-getF (VI x) = Just $ fromIntegral x-getF _ = Nothing--getN :: Value -> Maybe Note-getN (VF f) = Just $ Note f-getN (VR x) = Just $ Note $ fromRational x-getN (VI x) = Just $ Note $ fromIntegral x-getN _ = Nothing--getS :: Value -> Maybe String-getS (VS s) = Just s-getS _ = Nothing--getB :: Value -> Maybe Bool-getB (VB b) = Just b-getB _ = Nothing--getR :: Value -> Maybe Rational-getR (VR r) = Just r-getR (VF x) = Just $ toRational x-getR (VI x) = Just $ toRational x-getR _ = Nothing-- _extract :: (Value -> Maybe a) -> String -> ControlPattern -> Pattern a-_extract f name pat = filterJust $ withValue (\v -> (Map.lookup name v >>= f)) pat+_extract f name pat = filterJust $ withValue (Map.lookup name >=> f) pat -- | Extract a pattern of integer values by from a control pattern, given the name of the control extractI :: String -> ControlPattern -> Pattern Int@@ -746,10 +379,6 @@ extractR :: String -> ControlPattern -> Pattern Rational extractR = _extract getR -getBlob :: Value -> Maybe [Word8]-getBlob (VX xs) = Just xs-getBlob _ = Nothing- compressArc :: Arc -> Pattern a -> Pattern a compressArc (Arc s e) p | s > e = empty | s > 1 || e > 1 = empty@@ -780,6 +409,19 @@ rotR :: Time -> Pattern a -> Pattern a rotR t = rotL (negate t) ++-- | Mark values in the first pattern which match with at least one+-- value in the second pattern.+matchManyToOne :: (b -> a -> Bool) -> Pattern a -> Pattern b -> Pattern (Bool, b)+matchManyToOne f pa pb = pa {query = q}+ where q st = map match $ query pb st+ where+ match ex@(Event xContext xWhole xPart x) =+ Event (combineContexts $ xContext:map context as') xWhole xPart (any (f x . value) as', x)+ where as' = as $ start $ wholeOrPart ex+ as s = query pa $ fQuery s+ fQuery s = st {arc = Arc s s}+ -- ** Event filters -- | Remove events from patterns that to not meet the given test@@ -791,7 +433,6 @@ filterJust :: Pattern (Maybe a) -> Pattern a filterJust p = fromJust <$> filterValues isJust p --- formerly known as playWhen filterWhen :: (Time -> Bool) -> Pattern a -> Pattern a filterWhen test p = p {query = filter (test . wholeStart) . query p} @@ -824,14 +465,300 @@ tParamSqueeze :: (a -> Pattern b -> Pattern c) -> (Pattern a -> Pattern b -> Pattern c) tParamSqueeze f tv p = squeezeJoin $ (`f` p) <$> tv --- | Mark values in the first pattern which match with at least one--- value in the second pattern.-matchManyToOne :: (b -> a -> Bool) -> Pattern a -> Pattern b -> Pattern (Bool, b)-matchManyToOne f pa pb = pa {query = q}- where q st = map match $ query pb st- where- match (ex@(Event xContext xWhole xPart x)) =- Event (combineContexts $ xContext:(map context as')) xWhole xPart (any (f x) (map value $ as'), x)- where as' = as $ start $ wholeOrPart ex- as s = query pa $ fQuery s- fQuery s = st {arc = Arc s s}+-- ** Context++combineContexts :: [Context] -> Context+combineContexts = Context . concatMap contextPosition++setContext :: Context -> Pattern a -> Pattern a+setContext c pat = withEvents (map (\e -> e {context = c})) pat++withContext :: (Context -> Context) -> Pattern a -> Pattern a+withContext f pat = withEvents (map (\e -> e {context = f $ context e})) pat++deltaContext :: Int -> Int -> Pattern a -> Pattern a+deltaContext column line pat = withEvents (map (\e -> e {context = f $ context e})) pat+ where f :: Context -> Context+ f (Context xs) = Context $ map (\((bx,by), (ex,ey)) -> ((bx+column,by+line), (ex+column,ey+line))) xs++-- ** Events+++-- | Some context for an event, currently just position within sourcecode+data Context = Context {contextPosition :: [((Int, Int), (Int, Int))]}+ deriving (Eq, Ord, Generic)+instance NFData Context++-- | 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.+data EventF a b = Event+ { context :: Context+ , whole :: Maybe a+ , part :: a+ , value :: b+ } deriving (Eq, Ord, Functor, Generic)+instance (NFData a, NFData b) => NFData (EventF a b)++type Event a = EventF (ArcF Time) a++-- * Event utilities++isAnalog :: Event a -> Bool+isAnalog (Event {whole = Nothing}) = True+isAnalog _ = False++isDigital :: Event a -> Bool+isDigital = not . isAnalog++-- | `True` if an `Event`'s starts is within given `Arc`+onsetIn :: Arc -> Event a -> Bool+onsetIn a e = isIn a (wholeStart e)++-- | Compares two lists of events, attempting to combine fragmented events in the process+-- for a 'truer' compare+compareDefrag :: (Ord a) => [Event a] -> [Event a] -> Bool+compareDefrag as bs = sort (defragParts as) == sort (defragParts bs)++-- | Returns a list of events, with any adjacent parts of the same whole combined+defragParts :: Eq a => [Event a] -> [Event a]+defragParts [] = []+defragParts [e] = [e]+defragParts (e:es) | isJust i = defraged : defragParts (delete e' es)+ | otherwise = e : defragParts es+ where i = findIndex (isAdjacent e) es+ e' = es !! fromJust i+ defraged = Event (context e) (whole e) u (value e)+ u = hull (part e) (part e')++-- | Returns 'True' if the two given events are adjacent parts of the same whole+isAdjacent :: Eq a => Event a -> Event a -> Bool+isAdjacent e e' = (whole e == whole e')+ && (value e == value e')+ && ((stop (part e) == start (part e'))+ ||+ (stop (part e') == start (part e))+ )++wholeOrPart :: Event a -> Arc+wholeOrPart (Event {whole = Just a}) = a+wholeOrPart e = part e++-- | Get the onset of an event's 'whole'+wholeStart :: Event a -> Time+wholeStart = start . wholeOrPart++-- | Get the offset of an event's 'whole'+wholeStop :: Event a -> Time+wholeStop = stop . wholeOrPart++-- | Get the onset of an event's 'whole'+eventPartStart :: Event a -> Time+eventPartStart = start . part++-- | Get the offset of an event's 'part'+eventPartStop :: Event a -> Time+eventPartStop = stop . part++-- | Get the timespan of an event's 'part'+eventPart :: Event a -> Arc+eventPart = part++eventValue :: Event a -> a+eventValue = value++eventHasOnset :: Event a -> Bool+eventHasOnset e | isAnalog e = False+ | otherwise = start (fromJust $ whole e) == start (part e)++-- TODO - Is this used anywhere? Just tests, it seems+-- TODO - support 'context' field+toEvent :: (((Time, Time), (Time, Time)), a) -> Event a+toEvent (((ws, we), (ps, pe)), v) = Event (Context []) (Just $ Arc ws we) (Arc ps pe) v++ -- Resolves higher order VState values to plain values, by passing through (and changing) state+resolveState :: ValueMap -> [Event ValueMap] -> (ValueMap, [Event ValueMap])+resolveState sMap [] = (sMap, [])+resolveState sMap (e:es) = (sMap'', (e {value = v'}):es')+ where f sm (VState v) = v sm+ f sm v = (sm, v)+ (sMap', v') | eventHasOnset e = Map.mapAccum f sMap (value e) -- pass state through VState functions+ | otherwise = (sMap, Map.filter notVState $ value e) -- filter out VState values without onsets+ (sMap'', es') = resolveState sMap' es+ notVState (VState _) = False+ notVState _ = True++-- ** Values++-- | Polymorphic values++data Value = VS { svalue :: String }+ | VF { fvalue :: Double }+ | VN { nvalue :: Note }+ | VR { rvalue :: Rational }+ | VI { ivalue :: Int }+ | VB { bvalue :: Bool }+ | VX { xvalue :: [Word8] } -- Used for OSC 'blobs'+ | VPattern {pvalue :: Pattern Value}+ | VList {lvalue :: [Value]}+ | VState {statevalue :: ValueMap -> (ValueMap, Value)}+ deriving (Typeable, Generic)++class Valuable a where+ toValue :: a -> Value+instance NFData Value++type ValueMap = Map.Map String Value++-- | Note is Double, but with a different parser+newtype Note = Note { unNote :: Double } deriving (Typeable, Data, Generic, Eq, Ord, Show, Enum, Num, Fractional, Floating, Real)+instance NFData Note++instance Valuable String where+ toValue a = VS a+instance Valuable Double where+ toValue a = VF a+instance Valuable Rational where+ toValue a = VR a+instance Valuable Int where+ toValue a = VI a+instance Valuable Bool where+ toValue a = VB a+instance Valuable [Word8] where+ toValue a = VX a+instance Valuable [Value] where+ toValue a = VList a++instance Eq Value where+ (VS x) == (VS y) = x == y+ (VB x) == (VB y) = x == y+ (VF x) == (VF y) = x == y+ (VI x) == (VI y) = x == y+ (VN x) == (VN y) = x == y+ (VR x) == (VR y) = x == y+ (VX x) == (VX y) = x == y++ (VF x) == (VI y) = x == fromIntegral y+ (VI y) == (VF x) = x == fromIntegral y++ (VF x) == (VR y) = toRational x == y+ (VR y) == (VF x) = toRational x == y+ (VI x) == (VR y) = toRational x == y+ (VR y) == (VI x) = toRational x == y++ _ == _ = False++instance Ord Value where+ compare (VS x) (VS y) = compare x y+ compare (VB x) (VB y) = compare x y+ compare (VF x) (VF y) = compare x y+ compare (VN x) (VN y) = compare (unNote x) (unNote y)+ compare (VI x) (VI y) = compare x y+ compare (VR x) (VR y) = compare x y+ compare (VX x) (VX y) = compare x y++ compare (VS _) _ = LT+ compare _ (VS _) = GT+ compare (VB _) _ = LT+ compare _ (VB _) = GT+ compare (VX _) _ = LT+ compare _ (VX _) = GT++ compare (VF x) (VI y) = compare x (fromIntegral y)+ compare (VI x) (VF y) = compare (fromIntegral x) y++ compare (VR x) (VI y) = compare x (fromIntegral y)+ compare (VI x) (VR y) = compare (fromIntegral x) y++ compare (VF x) (VR y) = compare x (fromRational y)+ compare (VR x) (VF y) = compare (fromRational x) y++ compare (VN x) (VI y) = compare x (fromIntegral y)+ compare (VI x) (VN y) = compare (fromIntegral x) y++ compare (VN x) (VR y) = compare (unNote x) (fromRational y)+ compare (VR x) (VN y) = compare (fromRational x) (unNote y)++ compare (VF x) (VN y) = compare x (unNote y)+ compare (VN x) (VF y) = compare (unNote x) y++ -- you can't really compare patterns, state or lists..+ compare (VPattern _) (VPattern _) = EQ+ compare (VPattern _) _ = GT+ compare _ (VPattern _) = LT++ compare (VState _) (VState _) = EQ+ compare (VState _) _ = GT+ compare _ (VState _) = LT++ compare (VList _) (VList _) = EQ+ compare (VList _) _ = GT+ compare _ (VList _) = LT++-- | General utilities..++-- | Apply one of three functions to a Value, depending on its type+applyFIS :: (Double -> Double) -> (Int -> Int) -> (String -> String) -> Value -> Value+applyFIS f _ _ (VF f') = VF (f f')+applyFIS f _ _ (VN (Note f')) = VN (Note $ f f')+applyFIS _ f _ (VI i) = VI (f i)+applyFIS _ _ f (VS s) = VS (f s)+applyFIS f f' f'' (VState x) = VState $ \cmap -> (applyFIS f f' f'') <$> (x cmap)+applyFIS _ _ _ v = v++-- | Apply one of two functions to a pair of Values, depending on their types (int+-- or float; strings and rationals are ignored)+fNum2 :: (Int -> Int -> Int) -> (Double -> Double -> Double) -> Value -> Value -> Value+fNum2 fInt _ (VI a) (VI b) = VI (fInt a b)+fNum2 _ fFloat (VF a) (VF b) = VF (fFloat a b)+fNum2 _ fFloat (VN (Note a)) (VN (Note b)) = VN (Note $ fFloat a b)+fNum2 _ fFloat (VF a) (VN (Note b)) = VN (Note $ fFloat a b)+fNum2 _ fFloat (VN (Note a)) (VF b) = VN (Note $ fFloat a b)+fNum2 _ fFloat (VI a) (VF b) = VF (fFloat (fromIntegral a) b)+fNum2 _ fFloat (VF a) (VI b) = VF (fFloat a (fromIntegral b))+fNum2 fInt fFloat (VState a) b = VState $ \cmap -> ((\a' -> fNum2 fInt fFloat a' b) <$> (a cmap))+fNum2 fInt fFloat a (VState b) = VState $ \cmap -> ((\b' -> fNum2 fInt fFloat a b') <$> (b cmap))+fNum2 _ _ x _ = x++getI :: Value -> Maybe Int+getI (VI i) = Just i+getI (VR x) = Just $ floor x+getI (VF x) = Just $ floor x+getI _ = Nothing++getF :: Value -> Maybe Double+getF (VF f) = Just f+getF (VR x) = Just $ fromRational x+getF (VI x) = Just $ fromIntegral x+getF _ = Nothing++getN :: Value -> Maybe Note+getN (VF f) = Just $ Note f+getN (VR x) = Just $ Note $ fromRational x+getN (VI x) = Just $ Note $ fromIntegral x+getN _ = Nothing++getS :: Value -> Maybe String+getS (VS s) = Just s+getS _ = Nothing++getB :: Value -> Maybe Bool+getB (VB b) = Just b+getB _ = Nothing++getR :: Value -> Maybe Rational+getR (VR r) = Just r+getR (VF x) = Just $ toRational x+getR (VI x) = Just $ toRational x+getR _ = Nothing++getBlob :: Value -> Maybe [Word8]+getBlob (VX xs) = Just xs+getBlob _ = Nothing++getList :: Value -> Maybe [Value]+getList (VList vs) = Just vs+getList _ = Nothing++valueToPattern :: Value -> Pattern Value+valueToPattern (VPattern pat) = pat+valueToPattern v = pure v
src/Sound/Tidal/Show.hs view
@@ -1,7 +1,7 @@-{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, RecordWildCards #-}+{-# LANGUAGE FlexibleInstances, RecordWildCards #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -module Sound.Tidal.Show (show, showAll, draw, drawLine, drawLineSz, stepcount) where+module Sound.Tidal.Show (show, showAll, draw, drawLine, drawLineSz, stepcount, showStateful) where {-@@ -33,16 +33,27 @@ instance (Show a) => Show (Pattern a) where show = showPattern (Arc 0 1) -showPattern :: Show a => Arc -> Pattern a -> String-showPattern a p = intercalate "\n" evStrings- where evs = map showEvent $ sortOn part $ queryArc p a+showStateful :: ControlPattern -> String+showStateful p = intercalate "\n" evStrings+ where (_, evs) = resolveState (Map.empty) $ sortOn part $ queryArc (filterOnsets p) (Arc 0 1)+ evs' = map showEvent evs maxPartLength :: Int- maxPartLength = maximum $ map (length . fst) evs+ maxPartLength = maximum $ map (length . fst) evs' evString :: (String, String) -> String evString ev = ((replicate (maxPartLength - (length (fst ev))) ' ') ++ fst ev ++ snd ev )+ evStrings = map evString evs'++showPattern :: Show a => Arc -> Pattern a -> String+showPattern a p = intercalate "\n" evStrings+ where evs = map showEvent $ sortOn part $ queryArc p a+ maxPartLength :: Int+ maxPartLength = maximum $ map (length . fst) evs+ evString :: (String, String) -> String+ evString ev = replicate (maxPartLength - length (fst ev)) ' '+ ++ uncurry (++) ev evStrings = map evString evs showEvent :: Show a => Event a -> (String, String)@@ -71,15 +82,18 @@ show (VR r) = show r ++ "r" show (VB b) = show b show (VX xs) = show xs+ show (VPattern pat) = "(" ++ show pat ++ ")"+ show (VState f) = show $ f Map.empty+ show (VList _) = "<list>" -instance {-# OVERLAPPING #-} Show ControlMap where+instance {-# OVERLAPPING #-} Show ValueMap where show m = intercalate ", " $ map (\(name, v) -> name ++ ": " ++ show v) $ Map.toList m instance {-# OVERLAPPING #-} Show Arc where show (Arc s e) = prettyRat s ++ ">" ++ prettyRat e instance {-# OVERLAPPING #-} Show a => Show (Event a) where- show e = show (context e) ++ ((\(a,b) -> a ++ b) $ showEvent e)+ show e = show (context e) ++ uncurry (++) (showEvent e) prettyRat :: Rational -> String prettyRat r | unit == 0 && frac > 0 = showFrac (numerator frac) (denominator frac)@@ -136,8 +150,8 @@ down _ = Nothing stepcount :: Pattern a -> Int-stepcount pat = fromIntegral $ eventSteps $ concatMap (\ev -> [start ev, stop ev]) $ map part $ filter eventHasOnset $ queryArc pat (Arc 0 1)- where eventSteps xs = foldr lcm 1 $ map denominator xs+stepcount pat = fromIntegral $ eventSteps $ concatMap ((\ev -> [start ev, stop ev]) . part) (filter eventHasOnset $ queryArc pat (Arc 0 1))+ where eventSteps xs = foldr (lcm . denominator) 1 xs data Render = Render Int Int String @@ -153,23 +167,23 @@ drawLineSz sz pat = joinCycles sz $ drawCycles pat where drawCycles :: Pattern Char -> [Render]- drawCycles pat' = (draw pat'):(drawCycles $ rotL 1 pat')+ drawCycles pat' = draw pat':drawCycles (rotL 1 pat') joinCycles :: Int -> [Render] -> Render joinCycles _ [] = Render 0 0 "" joinCycles n ((Render cyc l s):cs) | l > n = Render 0 0 ""- | otherwise = Render (cyc+cyc') (l + l' + 1) $ intercalate "\n" $ map (\(a,b) -> a ++ b) lineZip- where + | otherwise = Render (cyc+cyc') (l + l' + 1) $ intercalate "\n" $ map (uncurry (++)) lineZip+ where (Render cyc' l' s') = joinCycles (n-l-1) cs linesN = max (length $ lines s) (length $ lines s') lineZip = take linesN $- zip (lines s ++ (repeat $ replicate l ' '))- (lines s' ++ (repeat $ replicate l' ' '))- + zip (lines s ++ repeat (replicate l ' '))+ (lines s' ++ repeat (replicate l' ' '))+ -- where maximum (map (length . head . (++ [""]) . lines) cs) draw :: Pattern Char -> Render-draw pat = Render 1 s $ (intercalate "\n" $ map ((\x -> ('|':x)) .drawLevel) ls)+draw pat = Render 1 s (intercalate "\n" $ map (('|' :) .drawLevel) ls) where ls = levels pat s = stepcount pat rs = toRational s@@ -179,8 +193,8 @@ f (' ', x) = x f (x, _) = x drawEvent :: Event Char -> String- drawEvent ev = (replicate (floor $ rs * evStart) ' ')- ++ (value ev:(replicate ((floor $ rs * (evStop - evStart)) - 1) '-'))+ drawEvent ev = replicate (floor $ rs * evStart) ' '+ ++ (value ev:replicate (floor (rs * (evStop - evStart)) - 1) '-') where evStart = start $ wholeOrPart ev evStop = stop $ wholeOrPart ev
src/Sound/Tidal/Simple.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}+{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} {-@@ -30,7 +30,7 @@ instance {-# OVERLAPPING #-} IsString ControlPattern where fromString = s . parseBP_E- + crunch :: ControlPattern -> ControlPattern crunch = (# crush 3)
src/Sound/Tidal/Stream.hs view
@@ -49,7 +49,7 @@ data Stream = Stream {sConfig :: Config, sBusses :: MVar [Int],- sInput :: MVar StateMap,+ sStateMV :: MVar ValueMap, -- sOutput :: MVar ControlPattern, sListen :: Maybe O.UDP, sPMapMV :: MVar PlayMap,@@ -207,7 +207,7 @@ ) oscmap let stream = Stream {sConfig = config, sBusses = bussesMV,- sInput = sMapMV,+ sStateMV = sMapMV, sListen = listen, sPMapMV = pMapMV, sTempoMV = tempoMV,@@ -216,7 +216,7 @@ } sendHandshakes stream _ <- T.clocked config tempoMV $ onTick stream- _ <- forkIO $ ctrlResponder config stream+ _ <- forkIO $ ctrlResponder 0 config stream return stream -- It only really works to handshake with one target at the moment..@@ -262,8 +262,9 @@ toDatum (VB True) = O.int32 (1 :: Int) toDatum (VB False) = O.int32 (0 :: Int) toDatum (VX xs) = O.Blob $ O.blob_pack xs--toData :: OSC -> Event ControlMap -> Maybe [O.Datum]+toDatum _ = error "toDatum: unhandled value"+ +toData :: OSC -> Event ValueMap -> Maybe [O.Datum] toData (OSC {args = ArgList as}) e = fmap (fmap (toDatum)) $ sequence $ map (\(n,v) -> Map.lookup n (value e) <|> v) as toData (OSC {args = Named rqrd}) e | hasRequired rqrd = Just $ concatMap (\(n,v) -> [O.string n, toDatum v]) $ Map.toList $ value e@@ -273,7 +274,7 @@ ks = Map.keys (value e) toData _ _ = Nothing -substitutePath :: String -> ControlMap -> Maybe String+substitutePath :: String -> ValueMap -> Maybe String substitutePath str cm = parse str where parse [] = Just [] parse ('{':xs) = parseWord xs@@ -285,7 +286,7 @@ return $ v ++ xs' where (a,b) = break (== '}') xs -getString :: ControlMap -> String -> Maybe String+getString :: ValueMap -> String -> Maybe String getString cm s = defaultValue $ simpleShow <$> Map.lookup s cm where simpleShow :: Value -> String simpleShow (VS str) = str@@ -295,6 +296,9 @@ simpleShow (VR r) = show r simpleShow (VB b) = show b simpleShow (VX xs) = show xs+ simpleShow (VState _) = show "<stateful>"+ simpleShow (VPattern _) = show "<pattern>"+ simpleShow (VList _) = show "<list>" (_, dflt) = break (== '=') s defaultValue :: Maybe String -> Maybe String defaultValue Nothing | null dflt = Nothing@@ -308,7 +312,7 @@ else not (mute pState) ) $ Map.elems pMap -toOSC :: Double -> [Int] -> Event ControlMap -> T.Tempo -> OSC -> [(Double, Bool, O.Message)]+toOSC :: Double -> [Int] -> Event ValueMap -> T.Tempo -> OSC -> [(Double, Bool, O.Message)] toOSC latency busses e tempo osc@(OSC _ _) = catMaybes (playmsg:busmsgs) where (playmap, busmap) = Map.partitionWithKey (\k _ -> null k || head k /= '^') $ value e@@ -374,7 +378,7 @@ onTick stream st = do doTick False stream st -processCps :: T.Tempo -> [Event ControlMap] -> ([(T.Tempo, Event ControlMap)], T.Tempo)+processCps :: T.Tempo -> [Event ValueMap] -> ([(T.Tempo, Event ValueMap)], T.Tempo) processCps t [] = ([], t) -- If an event has a tempo change, that affects the following events.. processCps t (e:evs) = (((t', e):es'), t'')@@ -427,9 +431,8 @@ hPutStrLn stderr $ "Return to previous pattern." setPreviousPatternOrSilence stream ) $- modifyMVar_ (sTempoMV stream) $ \ tempo -> do+ modifyState $ \(tempo, sMap) -> do pMap <- readMVar (sPMapMV stream)- sMap <- readMVar (sInput stream) busses <- readMVar (sBusses stream) sGlobalF <- readMVar (sGlobalFMV stream) -- putStrLn $ show st@@ -442,17 +445,21 @@ | otherwise = patstack frameEnd = snd $ T.nowTimespan st -- add cps to state- sMap' = Map.insert "_cps" (pure $ VF (T.cps tempo)) sMap+ sMap' = Map.insert "_cps" (VF (T.cps tempo)) sMap --filterOns = filter eventHasOnset extraLatency | fake = 0 | otherwise = cFrameTimespan config + T.nudged tempo+ -- First the state is used to query the pattern es = sortOn (start . part) $ query pat (State {arc = T.nowArc st, controls = sMap' } )+ -- Then it's passed through the events+ (sMap'', es') = resolveState sMap' es+ -- TODO onset is calculated in toOSC as well.. on e tempo'' = (sched tempo'' $ start $ wholeOrPart e)- (tes, tempo') = processCps tempo $ es+ (tes, tempo') = processCps tempo $ es' forM_ cxs $ \cx@(Cx target _ oscs _ _) -> do let latency = oLatency target + extraLatency ms = concatMap (\(t, e) ->@@ -463,8 +470,14 @@ forM_ ms $ \ m -> send (sListen stream) cx m `E.catch` \ (e :: E.SomeException) -> do hPutStrLn stderr $ "Failed to send. Is the '" ++ oName target ++ "' target running? " ++ show e - tempo' `seq` return tempo'-+ (tempo', sMap'') `seq` return (tempo', sMap'')+ where modifyState :: ((T.Tempo, ValueMap) -> IO (T.Tempo, ValueMap)) -> IO ()+ modifyState io = E.mask $ \restore -> do+ s <- takeMVar (sStateMV stream)+ t <- takeMVar (sTempoMV stream)+ (t', s') <- restore (io (t, s)) `E.onException` (do {putMVar (sStateMV stream) s; putMVar (sTempoMV stream) t; return ()})+ putMVar (sStateMV stream) s'+ putMVar (sTempoMV stream) t' setPreviousPatternOrSilence :: Stream -> IO () setPreviousPatternOrSilence stream =@@ -523,12 +536,12 @@ streamReplace s k !pat = E.catch (do let x = queryArc pat (Arc 0 0) tempo <- readMVar $ sTempoMV s- input <- takeMVar $ sInput s+ input <- takeMVar $ sStateMV s -- put change time in control input now <- O.time let cyc = T.timeToCycles tempo now- putMVar (sInput s) $- Map.insert ("_t_all") (pure $ VR cyc) $ Map.insert ("_t_" ++ show k) (pure $ VR cyc) input+ putMVar (sStateMV s) $+ Map.insert ("_t_all") (VR cyc) $ Map.insert ("_t_" ++ show k) (VR cyc) input -- update the pattern itself pMap <- seq x $ takeMVar $ sPMapMV s let playState = updatePS $ Map.lookup (show k) pMap@@ -580,10 +593,10 @@ return () streamSet :: Valuable a => Stream -> String -> Pattern a -> IO ()-streamSet s k pat = do sMap <- takeMVar $ sInput s+streamSet s k pat = do sMap <- takeMVar $ sStateMV s let pat' = toValue <$> pat- sMap' = Map.insert k pat' sMap- putMVar (sInput s) $ sMap'+ sMap' = Map.insert k (VPattern pat') sMap+ putMVar (sStateMV s) $ sMap' streamSetI :: Stream -> String -> Pattern Int -> IO () streamSetI = streamSet@@ -612,15 +625,17 @@ catchAny :: IO a -> (E.SomeException -> IO a) -> IO a catchAny = E.catch -ctrlResponder :: Config -> Stream -> IO ()-ctrlResponder c (stream@(Stream {sListen = Just sock})) = do ms <- recvMessagesTimeout 2 sock- if (null ms)- then checkHandshake -- there was a timeout, check handshake- else mapM_ act ms- ctrlResponder c stream+ctrlResponder :: Int -> Config -> Stream -> IO ()+ctrlResponder waits c (stream@(Stream {sListen = Just sock}))+ = do ms <- recvMessagesTimeout 2 sock+ if (null ms)+ then do checkHandshake -- there was a timeout, check handshake+ ctrlResponder (waits+1) c stream+ else do mapM_ act ms+ ctrlResponder 0 c stream where checkHandshake = do busses <- readMVar (sBusses stream)- when (null busses) $ do verbose c $ "Waiting for SuperDirt.."+ when (null busses) $ do when (waits == 0) $ verbose c $ "Waiting for SuperDirt (v.1.7.2 or higher).." sendHandshakes stream act (O.Message "/dirt/hello" _) = sendHandshakes stream@@ -642,10 +657,10 @@ = add (O.ascii_to_string k) (VI (fromIntegral v)) act m = hPutStrLn stderr $ "Unhandled OSC: " ++ show m add :: String -> Value -> IO ()- add k v = do sMap <- takeMVar (sInput stream)- putMVar (sInput stream) $ Map.insert k (pure v) sMap+ add k v = do sMap <- takeMVar (sStateMV stream)+ putMVar (sStateMV stream) $ Map.insert k v sMap return ()-ctrlResponder _ _ = return ()+ctrlResponder _ _ _ = return () verbose :: Config -> String -> IO ()@@ -653,3 +668,14 @@ recvMessagesTimeout :: (O.Transport t) => Double -> t -> IO [O.Message] recvMessagesTimeout n sock = fmap (maybe [] O.packetMessages) $ O.recvPacketTimeout n sock+++streamGetcps :: Stream -> IO O.Time+streamGetcps s = do tempo <- readMVar $ sTempoMV s+ return $ T.cps tempo++streamGetnow :: Stream -> IO Double+streamGetnow s = do tempo <- readMVar $ sTempoMV s+ now <- O.time+ return $ fromRational $ T.timeToCycles tempo now+
src/Sound/Tidal/Tempo.hs view
@@ -1,6 +1,6 @@ {-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns -fno-warn-orphans #-}-{-# LANGUAGE RecordWildCards #-} + module Sound.Tidal.Tempo where import Control.Concurrent.MVar@@ -57,7 +57,7 @@ changeTempo :: MVar Tempo -> (O.Time -> Tempo -> Tempo) -> IO Tempo changeTempo tempoMV f = do t <- O.time tempo <- takeMVar tempoMV- let tempo' = f t $ tempo+ let tempo' = f t tempo sendTempo tempo' putMVar tempoMV tempo' return tempo'@@ -99,9 +99,9 @@ cycleDelta = realToFrac (cps tempo) * delta cyclesToTime :: Tempo -> Rational -> O.Time-cyclesToTime tempo cyc = atTime tempo + (fromRational timeDelta)+cyclesToTime tempo cyc = atTime tempo + fromRational timeDelta where cycleDelta = cyc - atCycle tempo- timeDelta = cycleDelta / (toRational $ cps tempo)+ timeDelta = cycleDelta / toRational (cps tempo) {- getCurrentCycle :: MVar Tempo -> IO Rational@@ -126,7 +126,7 @@ frameTimespan = cFrameTimespan config loop st = do -- putStrLn $ show $ nowArc ts- tempo <- readMVar tempoMV + tempo <- readMVar tempoMV t <- O.time let logicalT ticks' = start st + fromIntegral ticks' * frameTimespan logicalNow = logicalT $ ticks st + 1@@ -140,9 +140,9 @@ t' <- O.time let actualTick = floor $ (t' - start st) / frameTimespan -- reset ticks if ahead/behind by skipTicks or more- ahead = (abs $ actualTick - ticks st) > (cSkipTicks config)+ ahead = abs (actualTick - ticks st) > cSkipTicks config newTick | ahead = actualTick- | otherwise = (ticks st) + 1+ | otherwise = ticks st + 1 st' = st {ticks = newTick, nowArc = P.Arc s e, nowTimespan = (logicalNow, logicalNow + frameTimespan),@@ -156,7 +156,7 @@ )-} loop st' -clientListen :: Config -> MVar Tempo -> O.Time -> IO (ThreadId)+clientListen :: Config -> MVar Tempo -> O.Time -> IO ThreadId clientListen config tempoMV s = do -- Listen on random port let tempoClientPort = cTempoClientPort config@@ -172,8 +172,7 @@ O.sendTo local (O.p_message "/hello" []) remote -- Make tempo mvar -- Listen to tempo changes- tempoChild <- forkIO $ listenTempo local tempoMV- return tempoChild+ forkIO $ listenTempo local tempoMV sendTempo :: Tempo -> IO () sendTempo tempo = O.sendTo (localUDP tempo) (O.p_bundle (atTime tempo) [m]) (remoteAddr tempo)@@ -181,7 +180,7 @@ O.Float $ realToFrac $ cps tempo, O.Int32 $ if paused tempo then 1 else 0 ]- + listenTempo :: O.UDP -> MVar Tempo -> IO () listenTempo udp tempoMV = forever $ do pkt <- O.recvPacket udp act Nothing pkt@@ -216,20 +215,20 @@ act :: O.UDP -> N.SockAddr -> Maybe O.Time -> ([N.SockAddr], O.Packet) -> O.Packet -> IO ([N.SockAddr], O.Packet) act udp c _ (cs,msg) (O.Packet_Bundle (O.Bundle ts ms)) = foldM (act udp c (Just ts)) (cs,msg) $ map O.Packet_Message ms act udp c _ (cs,msg) (O.Packet_Message (O.Message "/hello" []))- = do O.sendTo udp msg c + = do O.sendTo udp msg c return (nub (c:cs),msg) act udp _ (Just ts) (cs,_) (O.Packet_Message (O.Message "/transmit/cps/cycle" params)) = do let path' = "/cps/cycle" msg' = O.p_bundle ts [O.Message path' params] mapM_ (O.sendTo udp msg') cs return (cs, msg')- act _ x _ (cs,msg) pkt = do writeError $ "Unknown packet (serv): " ++ show pkt ++ " / " ++ (show x)+ act _ x _ (cs,msg) pkt = do writeError $ "Unknown packet (serv): " ++ show pkt ++ " / " ++ show x return (cs,msg) catchAny :: IO a -> (E.SomeException -> IO a) -> IO a catchAny = E.catch defaultCpsMessage = do ts <- O.time- return $ O.p_bundle ts [O.Message "/cps/cycle" [O.Float $ 0,- O.Float $ realToFrac $ defaultCps,+ return $ O.p_bundle ts [O.Message "/cps/cycle" [O.Float 0,+ O.Float $ realToFrac defaultCps, O.Int32 0 ] ]
+ src/Sound/Tidal/Time.hs view
@@ -0,0 +1,130 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveFunctor #-}++module Sound.Tidal.Time where++import Control.Applicative+import GHC.Generics+import Control.DeepSeq (NFData)++-- | Time is rational+type Time = Rational++-- | An arc of time, with a start time (or onset) and a stop time (or offset)+data ArcF a = Arc+ { start :: a+ , stop :: a+ } deriving (Eq, Ord, Functor, Show, Generic)++type Arc = ArcF Time++instance Applicative ArcF where+ pure t = Arc t t+ (<*>) (Arc sf ef) (Arc sx ex) = Arc (sf sx) (ef ex)++instance NFData a => NFData (ArcF a)++instance Num a => Num (ArcF a) where+ negate = fmap negate+ (+) = liftA2 (+)+ (*) = liftA2 (*)+ fromInteger = pure . fromInteger+ abs = fmap abs+ signum = fmap signum++instance (Fractional a) => Fractional (ArcF a) where+ recip = fmap recip+ fromRational = pure . fromRational++-- Utility functions - Time++-- | The 'sam' (start of cycle) for the given time value+sam :: Time -> Time+sam = fromIntegral . (floor :: Time -> Int)++-- | Turns a number into a (rational) time value. An alias for 'toRational'.+toTime :: Real a => a -> Rational+toTime = toRational++-- | Turns a (rational) time value into another number. An alias for 'fromRational'.+fromTime :: Fractional a => Time -> a+fromTime = fromRational++-- | The end point of the current cycle (and starting point of the next cycle)+nextSam :: Time -> Time+nextSam = (1+) . sam++-- | The position of a time value relative to the start of its cycle.+cyclePos :: Time -> Time+cyclePos t = t - sam t++-- Utility functions - Arc++-- | convex hull union+hull :: Arc -> Arc -> Arc+hull (Arc s e) (Arc s' e') = Arc (min s s') (max e e')++-- | @subArc i j@ is the timespan that is the intersection of @i@ and @j@.+-- intersection+-- The definition is a bit fiddly as results might be zero-width, but+-- not at the end of an non-zero-width arc - e.g. (0,1) and (1,2) do+-- not intersect, but (1,1) (1,1) does.+subArc :: Arc -> Arc -> Maybe Arc+subArc a@(Arc s e) b@(Arc s' e')+ | and [s'' == e'', s'' == e, s < e] = Nothing+ | and [s'' == e'', s'' == e', s' < e'] = Nothing+ | s'' <= e'' = Just (Arc s'' e'')+ | otherwise = Nothing+ where (Arc s'' e'') = sect a b++subMaybeArc :: Maybe Arc -> Maybe Arc -> Maybe (Maybe Arc)+subMaybeArc (Just a) (Just b) = do sa <- subArc a b+ return $ Just sa+subMaybeArc _ _ = Just Nothing+-- subMaybeArc = liftA2 subArc -- this typechecks, but doesn't work the same way.. hmm++-- | Simple intersection of two arcs+sect :: Arc -> Arc -> Arc+sect (Arc s e) (Arc s' e') = Arc (max s s') (min e e')+++-- | The arc of the whole cycle that the given time value falls within+timeToCycleArc :: Time -> Arc+timeToCycleArc t = Arc (sam t) (sam t + 1)++-- | Shifts an arc to the equivalent one that starts during cycle zero+cycleArc :: Arc -> Arc+cycleArc (Arc s e) = Arc (cyclePos s) (cyclePos s + (e-s))++-- | A list of cycle numbers which are included in the given arc+cyclesInArc :: Integral a => Arc -> [a]+cyclesInArc (Arc s e)+ | s > e = []+ | s == e = [floor s]+ | otherwise = [floor s .. ceiling e-1]++-- | A list of arcs of the whole cycles which are included in the given arc+cycleArcsInArc :: Arc -> [Arc]+cycleArcsInArc = map (timeToCycleArc . (toTime :: Int -> Time)) . cyclesInArc++-- | Splits the given 'Arc' into a list of 'Arc's, at cycle boundaries.+arcCycles :: Arc -> [Arc]+arcCycles (Arc s e) | s >= e = []+ | sam s == sam e = [Arc s e]+ | otherwise = Arc s (nextSam s) : arcCycles (Arc (nextSam s) e)++-- | Like arcCycles, but returns zero-width arcs+arcCyclesZW :: Arc -> [Arc]+arcCyclesZW (Arc s e) | s == e = [Arc s e]+ | otherwise = arcCycles (Arc s e)++-- | Similar to 'fmap' but time is relative to the cycle (i.e. the+-- sam of the start of the arc)+mapCycle :: (Time -> Time) -> Arc -> Arc+mapCycle f (Arc s e) = Arc (sam' + f (s - sam')) (sam' + f (e - sam'))+ where sam' = sam s++-- | @isIn a t@ is @True@ if @t@ is inside+-- the arc represented by @a@.+isIn :: Arc -> Time -> Bool+isIn (Arc s e) t = t >= s && t < e
src/Sound/Tidal/UI.hs view
@@ -1536,17 +1536,17 @@ @ -} jux- :: (Pattern ControlMap -> Pattern ControlMap)- -> Pattern ControlMap -> Pattern ControlMap+ :: (Pattern ValueMap -> Pattern ValueMap)+ -> Pattern ValueMap -> Pattern ValueMap jux = juxBy 1 juxcut- :: (Pattern ControlMap -> Pattern ControlMap)- -> Pattern ControlMap -> Pattern ControlMap+ :: (Pattern ValueMap -> Pattern ValueMap)+ -> Pattern ValueMap -> Pattern ValueMap juxcut f p = stack [p # P.pan (pure 0) # P.cut (pure (-1)), f $ p # P.pan (pure 1) # P.cut (pure (-2)) ] -juxcut' :: [t -> Pattern ControlMap] -> t -> Pattern ControlMap+juxcut' :: [t -> Pattern ValueMap] -> t -> Pattern ValueMap juxcut' fs p = stack $ map (\n -> ((fs !! n) p |+ P.cut (pure $ 1-n)) # P.pan (pure $ fromIntegral n / fromIntegral l)) [0 .. l-1] where l = length fs @@ -1573,14 +1573,14 @@ @ -}-jux' :: [t -> Pattern ControlMap] -> t -> Pattern ControlMap+jux' :: [t -> Pattern ValueMap] -> t -> Pattern ValueMap jux' fs p = stack $ map (\n -> (fs !! n) p |+ P.pan (pure $ fromIntegral n / fromIntegral l)) [0 .. l-1] where l = length fs -- | Multichannel variant of `jux`, _not sure what it does_ jux4- :: (Pattern ControlMap -> Pattern ControlMap)- -> Pattern ControlMap -> Pattern ControlMap+ :: (Pattern ValueMap -> Pattern ValueMap)+ -> Pattern ValueMap -> Pattern ValueMap jux4 f p = stack [p # P.pan (pure (5/8)), f $ p # P.pan (pure (1/8))] {- |@@ -1599,9 +1599,9 @@ -} juxBy :: Pattern Double- -> (Pattern ControlMap -> Pattern ControlMap)- -> Pattern ControlMap- -> Pattern ControlMap+ -> (Pattern ValueMap -> Pattern ValueMap)+ -> Pattern ValueMap+ -> Pattern ValueMap juxBy n f p = stack [p |+ P.pan 0.5 |- P.pan (n/2), f $ p |+ P.pan 0.5 |+ P.pan (n/2)] pick :: String -> Int -> String@@ -1690,10 +1690,10 @@ ghost'' :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a ghost'' a f p = superimpose (((a*2.5) `rotR`) . f) $ superimpose (((a*1.5) `rotR`) . f) p -ghost' :: Time -> Pattern ControlMap -> Pattern ControlMap+ghost' :: Time -> Pattern ValueMap -> Pattern ValueMap ghost' a p = ghost'' a ((|*| P.gain (pure 0.7)) . (|> P.end (pure 0.2)) . (|*| P.speed (pure 1.25))) p -ghost :: Pattern ControlMap -> Pattern ControlMap+ghost :: Pattern ValueMap -> Pattern ValueMap ghost = ghost' 0.125 {- |@@ -1781,16 +1781,16 @@ unfix :: (ControlPattern -> ControlPattern) -> ControlPattern -> ControlPattern -> ControlPattern unfix = contrast id -fixRange :: (ControlPattern -> Pattern ControlMap)+fixRange :: (ControlPattern -> Pattern ValueMap) -> Pattern (Map.Map String (Value, Value)) -> ControlPattern- -> Pattern ControlMap+ -> ControlPattern fixRange f = contrastRange f id -unfixRange :: (ControlPattern -> Pattern ControlMap)+unfixRange :: (ControlPattern -> Pattern ValueMap) -> Pattern (Map.Map String (Value, Value)) -> ControlPattern- -> Pattern ControlMap+ -> ControlPattern unfixRange = contrastRange id -- | limit values in a Pattern (or other Functor) to n equally spaced
src/Sound/Tidal/Utils.hs view
@@ -99,22 +99,26 @@ deltaMini = outside 0 0 where outside :: Int -> Int -> String -> String outside _ _ [] = []- outside column line ('"':xs) = ("(deltaContext "+ outside column line ('"':xs) = "(deltaContext " ++ show column ++ " " ++ show line ++ " \"" ++ inside (column+1) line xs- )- outside _ line ('\n':xs) = '\n':(outside 0 (line+1) xs)- outside column line (x:xs) = x:(outside (column+1) line xs)+ outside _ line ('\n':xs) = '\n':outside 0 (line+1) xs+ outside column line (x:xs) = x:outside (column+1) line xs inside :: Int -> Int -> String -> String inside _ _ [] = []- inside column line ('"':xs) = '"':')':(outside (column+1) line xs)- inside _ line ('\n':xs) = '\n':(inside 0 (line+1) xs)- inside column line (x:xs) = x:(inside (column+1) line xs)+ inside column line ('"':xs) = '"':')':outside (column+1) line xs+ inside _ line ('\n':xs) = '\n':inside 0 (line+1) xs+ inside column line (x:xs) = x:inside (column+1) line xs matchMaybe :: Maybe a -> Maybe a -> Maybe a matchMaybe Nothing y = y matchMaybe x _ = x++-- Available in Data.Either, but only since 4.10+fromRight :: b -> Either a b -> b+fromRight _ (Right b) = b+fromRight b _ = b
src/Sound/Tidal/Version.hs view
@@ -21,7 +21,7 @@ -} tidal_version :: String-tidal_version = "1.7.1"+tidal_version = "1.7.2" tidal_status :: IO () tidal_status = tidal_status_string >>= putStrLn
test/Sound/Tidal/ParseTest.hs view
@@ -23,6 +23,14 @@ compareP (Arc 0 2) ("0 1 2 3 4 5 6 7 8 0 10 20 30 40 50" :: Pattern Int) (fastCat $ map (pure . read) $ words "0 1 2 3 4 5 6 7 8 0 10 20 30 40 50")+ it "can parse pattern groups" $ do+ compareP (Arc 0 1)+ ("[bd sd] hh" :: Pattern String)+ (fastCat ["bd sd", "hh"])+ it "can parse pattern groups shorthand " $ do+ compareP (Arc 0 1)+ ("bd sd . hh hh hh" :: Pattern String)+ ("[bd sd] [hh hh hh]") it "can alternate with <>" $ do compareP (Arc 0 2) ("a <b c>" :: Pattern String)
test/Sound/Tidal/PatternTest.hs view
@@ -249,7 +249,7 @@ describe "controlI" $ do it "can retrieve values from state" $- (query (pure 3 + cF_ "hello") $ State (Arc 0 1) (Map.singleton "hello" (pure $ VF 0.5)))+ (query (pure 3 + cF_ "hello") $ State (Arc 0 1) (Map.singleton "hello" (VF 0.5))) `shouldBe` [(Event (Context []) (Just $ Arc (0 % 1) (1 % 1)) (Arc (0 % 1) (1 % 1)) 3.5)] describe "wholeStart" $ do
test/TestUtils.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedStrings, FlexibleInstances, TypeSynonymInstances #-} module TestUtils where @@ -11,6 +11,25 @@ import Sound.Tidal.Context import qualified Data.Map.Strict as Map++class TolerantEq a where+ (~==) :: a -> a -> Bool++instance TolerantEq Value where+ (VS a) ~== (VS b) = a == b+ (VI a) ~== (VI b) = a == b+ (VR a) ~== (VR b) = a == b+ (VF a) ~== (VF b) = abs (a - b) < 0.000001+ _ ~== _ = False++instance TolerantEq a => TolerantEq [a] where+ as ~== bs = (length as == length bs) && all (uncurry (~==)) (zip as bs)++instance TolerantEq ValueMap where+ a ~== b = Map.differenceWith (\a' b' -> if a' ~== b' then Nothing else Just a') a b == Map.empty++instance TolerantEq (Event ValueMap) where+ (Event _ w p x) ~== (Event _ w' p' x') = w == w' && p == p' && x ~== x' -- | Compare the events of two patterns using the given arc compareP :: (Ord a, Show a) => Arc -> Pattern a -> Pattern a -> Property
tidal.cabal view
@@ -1,5 +1,5 @@ name: tidal-version: 1.7.1+version: 1.7.2 synopsis: Pattern language for improvised music -- description: homepage: http://tidalcycles.org/@@ -43,13 +43,12 @@ Sound.Tidal.Simple Sound.Tidal.Stream Sound.Tidal.Tempo+ Sound.Tidal.Time Sound.Tidal.Transition Sound.Tidal.UI Sound.Tidal.Utils Sound.Tidal.Version Sound.Tidal.EspGrid- -- Sound.Tidal.Light- -- Sound.Tidal.TH Paths_tidal Build-depends: base >=4.8 && <5@@ -67,8 +66,6 @@ , deepseq >= 1.1.0.0 , primitive < 0.8 , random < 1.3- -- , serialport- -- , hashable if !impl(ghc >= 8.4.1) build-depends: semigroups >= 0.18 && < 0.20