tidal 0.5.3 → 0.6
raw patch · 11 files changed
+334/−131 lines, 11 filesdep ~basedep ~hosc
Dependency ranges changed: base, hosc
Files
- README.md +1/−1
- Sound/Tidal/Context.hs +4/−0
- Sound/Tidal/Dirt.hs +38/−100
- Sound/Tidal/Params.hs +116/−0
- Sound/Tidal/Parse.hs +10/−5
- Sound/Tidal/Pattern.hs +25/−5
- Sound/Tidal/Strategies.hs +25/−8
- Sound/Tidal/Stream.hs +24/−11
- Sound/Tidal/Transition.hs +85/−0
- Sound/Tidal/Utils.hs +3/−0
- tidal.cabal +3/−1
README.md view
@@ -6,7 +6,7 @@ For documentation, mailing list and more info see here: http://tidal.lurk.org/ -(c) Alex McLean and contributors, 2014+(c) Alex McLean and contributors, 2015 Distributed under the terms of the GNU Public license version 3 (or later).
Sound/Tidal/Context.hs view
@@ -4,6 +4,7 @@ import Data.List as C import Control.Applicative as C import Data.Ratio as C+import Data.Monoid as C import Sound.Tidal.Parse as C import Sound.Tidal.Pattern as C import Sound.Tidal.Stream as C@@ -12,3 +13,6 @@ import Sound.Tidal.Tempo as C import Sound.Tidal.Time as C import Sound.Tidal.SuperCollider as C+import Sound.Tidal.Params as C+import Sound.Tidal.Transition as C+
Sound/Tidal/Dirt.hs view
@@ -19,37 +19,38 @@ import Sound.Tidal.Stream import Sound.Tidal.Pattern import Sound.Tidal.Parse+import Sound.Tidal.Params import Sound.Tidal.Time import Sound.Tidal.Utils (enumerate) dirt :: OscShape dirt = OscShape {path = "/play",- params = [ S "sound" Nothing,- F "offset" (Just 0),- F "begin" (Just 0),- F "end" (Just 1),- F "speed" (Just 1),- F "pan" (Just 0.5),- F "velocity" (Just 0),- S "vowel" (Just ""),- F "cutoff" (Just 0),- F "resonance" (Just 0),- F "accelerate" (Just 0),- F "shape" (Just 0),- I "kriole" (Just 0),- F "gain" (Just 1),- I "cut" (Just (0)),- F "delay" (Just (0)),- F "delaytime" (Just (-1)),- F "delayfeedback" (Just (-1)),- F "crush" (Just 0),- I "coarse" (Just 0),- F "hcutoff" (Just 0),- F "hresonance" (Just 0),- F "bandf" (Just 0),- F "bandq" (Just 0),- S "unit" (Just "rate"),- I "loop" (Just 1)+ params = [ sound_p,+ offset_p,+ begin_p,+ end_p,+ speed_p,+ pan_p,+ velocity_p,+ vowel_p,+ cutoff_p,+ resonance_p,+ accelerate_p,+ shape_p,+ kriole_p,+ gain_p,+ cut_p,+ delay_p,+ delaytime_p,+ delayfeedback_p,+ crush_p,+ coarse_p,+ hcutoff_p,+ hresonance_p,+ bandf_p,+ bandq_p,+ unit_p,+ loop_p ], cpsStamp = True, timestamp = MessageStamp,@@ -58,18 +59,6 @@ preamble = [] } -kriole :: OscShape-kriole = OscShape {path = "/trigger",- params = [ I "ksymbol" Nothing,- F "kpitch" (Just 1)- ],- cpsStamp = False,- timestamp = MessageStamp,- latency = 0.04,- namedParams = False,- preamble = []- }- dirtstart name = start "127.0.0.1" 7771 dirt dirtStream = stream "127.0.0.1" 7771 dirt dirtState = Sound.Tidal.Stream.state "127.0.0.1" 7771 dirt@@ -77,8 +66,6 @@ -- disused parameter.. dirtstream _ = dirtStream -kstream name = stream "127.0.0.1" 6040 kriole- doubledirt = do remote <- stream "178.77.72.138" 7777 dirt local <- stream "192.168.0.102" 7771 dirt return $ \p -> do remote p@@ -118,68 +105,30 @@ -- streamcallback cb "127.0.0.1" "127.0.0.1" name "127.0.0.1" 7771 dirt -sound = makeS dirt "sound"-offset = makeF dirt "offset"-begin = makeF dirt "begin"-end = makeF dirt "end"-speed = makeF dirt "speed"-pan = makeF dirt "pan"-velocity = makeF dirt "velocity"-vowel = makeS dirt "vowel"-cutoff = makeF dirt "cutoff"-resonance = makeF dirt "resonance"-accelerate = makeF dirt "accelerate"-shape = makeF dirt "shape"-gain = makeF dirt "gain"-delay = makeF dirt "delay"-delaytime = makeF dirt "delaytime"-delayfeedback = makeF dirt "delayfeedback"-crush = makeF dirt "crush"--coarse :: Pattern Int -> OscPattern-coarse = makeI dirt "coarse"-hcutoff = makeF dirt "hcutoff"-hresonance = makeF dirt "hresonance"-bandf = makeF dirt "bandf"-bandq = makeF dirt "bandq"-unit = makeS dirt "unit"-loop = makeI dirt "loop"--cut :: Pattern Int -> OscPattern-cut = makeI dirt "cut"--ksymbol = makeF kriole "ksymbol"-kpitch = makeF kriole "kpitch"-- pick :: String -> Int -> String pick name n = name ++ ":" ++ (show n) striate :: Int -> OscPattern -> OscPattern striate n p = cat $ map (\x -> off (fromIntegral x) p) [0 .. n-1] where off i p = p - |+| begin (atom (fromIntegral i / fromIntegral n)) - |+| end (atom (fromIntegral (i+1) / fromIntegral n))+ # begin (atom (fromIntegral i / fromIntegral n)) + # end (atom (fromIntegral (i+1) / fromIntegral n)) striate' :: Int -> Double -> OscPattern -> OscPattern striate' n f p = cat $ map (\x -> off (fromIntegral x) p) [0 .. n-1]- where off i p = p |+| begin (atom (slot * i) :: Pattern Double) |+| end (atom ((slot * i) + f) :: Pattern Double)+ where off i p = p # begin (atom (slot * i) :: Pattern Double) # end (atom ((slot * i) + f) :: Pattern Double) slot = (1 - f) / (fromIntegral n) striateO :: OscPattern -> Int -> Double -> OscPattern striateO p n o = cat $ map (\x -> off (fromIntegral x) p) [0 .. n-1]- where off i p = p |+| begin ((atom $ (fromIntegral i / fromIntegral n) + o) :: Pattern Double) |+| end ((atom $ (fromIntegral (i+1) / fromIntegral n) + o) :: Pattern Double)+ where off i p = p # begin ((atom $ (fromIntegral i / fromIntegral n) + o) :: Pattern Double) # end ((atom $ (fromIntegral (i+1) / fromIntegral n) + o) :: Pattern Double) striateL :: Int -> Int -> OscPattern -> OscPattern-striateL n l p = striate n p |+| loop (atom $ fromIntegral l)-striateL' n f l p = striate' n f p |+| loop (atom $ fromIntegral l)+striateL n l p = striate n p # loop (atom $ fromIntegral l)+striateL' n f l p = striate' n f p # loop (atom $ fromIntegral l) metronome = slow 2 $ sound (p "[odx, [hh]*8]") -dirtSetters :: IO Time -> IO (OscPattern -> IO (), (Time -> [OscPattern] -> OscPattern) -> OscPattern -> IO ())-dirtSetters getNow = do ds <- dirtState- return (setter ds, transition getNow ds)- clutchIn :: Time -> Time -> [Pattern a] -> Pattern a clutchIn _ _ [] = silence clutchIn _ _ (p:[]) = p@@ -191,27 +140,16 @@ xfadeIn :: Time -> Time -> [OscPattern] -> OscPattern xfadeIn _ _ [] = silence xfadeIn _ _ (p:[]) = p-xfadeIn t now (p:p':_) = overlay (p |+| gain (now ~> (slow t envEqR))) (p' |+| gain (now ~> (slow t (envEq))))+xfadeIn t now (p:p':_) = overlay (p |*| gain (now ~> (slow t envEqR))) (p' |*| gain (now ~> (slow t (envEq)))) xfade :: Time -> [OscPattern] -> OscPattern xfade = xfadeIn 2 stut :: Integer -> Double -> Rational -> OscPattern -> OscPattern-stut steps feedback time p = stack (p:(map (\x -> (((x%steps)*time) ~> (p |+| gain (pure $ scale (fromIntegral x))))) [1..(steps-1)])) +stut steps feedback time p = stack (p:(map (\x -> (((x%steps)*time) ~> (p |*| gain (pure $ scale (fromIntegral x))))) [1..(steps-1)])) where scale x = ((+feedback) . (*(1-feedback)) . (/(fromIntegral steps)) . ((fromIntegral steps)-)) x -anticipateIn :: Time -> Time -> [OscPattern] -> OscPattern-anticipateIn _ _ [] = silence-anticipateIn _ _ (p:[]) = p-anticipateIn t now (p:p':_) = overlay (playWhen (< (now + t)) $ spread' (stut 8 0.2) (now ~> (slow t $ toRational <$> envL)) p') (playWhen (>= (now + t)) p)--anticipate :: Time -> [OscPattern] -> OscPattern-anticipate = anticipateIn 4--histpan :: Int -> Time -> [OscPattern] -> OscPattern-histpan _ _ [] = silence-histpan 0 _ _ = silence-histpan n _ ps = stack $ map (\(i,p) -> p |+| pan (atom $ (fromIntegral i) / (fromIntegral n'))) (enumerate ps')- where ps' = take n ps- n' = length ps' -- in case there's fewer patterns than requested+stut' :: Integer -> Time -> (OscPattern -> OscPattern) -> OscPattern -> OscPattern+stut' steps steptime f p | steps <= 0 = p+ | otherwise = overlay (f (steptime ~> stut' (steps-1) steptime f p)) p
+ Sound/Tidal/Params.hs view
@@ -0,0 +1,116 @@+module Sound.Tidal.Params where++import Sound.Tidal.Stream+import Sound.Tidal.Pattern+import Sound.OSC.FD+import Sound.OSC.Datum+import Data.Map as Map++make' :: (a -> Datum) -> Param -> Pattern a -> OscPattern+make' toOsc par p = fmap (\x -> Map.singleton par (defaultV x)) p+ where defaultV a = Just $ toOsc a++sound :: Pattern String -> OscPattern+sound = make' string sound_p+sound_p = S "sound" Nothing++offset :: Pattern Double -> OscPattern+offset = make' float offset_p+offset_p = F "offset" (Just 0)++begin :: Pattern Double -> OscPattern+begin = make' float begin_p+begin_p = F "begin" (Just 0)++end :: Pattern Double -> OscPattern+end = make' float end_p+end_p = F "end" (Just 1)++speed :: Pattern Double -> OscPattern+speed = make' float speed_p+speed_p = F "speed" (Just 1)++pan :: Pattern Double -> OscPattern+pan = make' float pan_p+pan_p = F "pan" (Just 0.5)++velocity :: Pattern Double -> OscPattern+velocity = make' float velocity_p+velocity_p = F "velocity" (Just 0)++vowel :: Pattern String -> OscPattern+vowel = make' string vowel_p+vowel_p = S "vowel" (Just "")++cutoff :: Pattern Double -> OscPattern+cutoff = make' float cutoff_p+cutoff_p = F "cutoff" (Just 0)++resonance :: Pattern Double -> OscPattern+resonance = make' float resonance_p+resonance_p = F "resonance" (Just 0)++accelerate :: Pattern Double -> OscPattern+accelerate = make' float accelerate_p+accelerate_p = F "accelerate" (Just 0)++shape :: Pattern Double -> OscPattern+shape = make' float shape_p+shape_p = F "shape" (Just 0)++kriole :: Pattern Int -> OscPattern+kriole = make' int32 kriole_p+kriole_p = I "kriole" (Just 0)++gain :: Pattern Double -> OscPattern+gain = make' float gain_p+gain_p = F "gain" (Just 1)++cut :: Pattern Int -> OscPattern+cut = make' int32 cut_p+cut_p = I "cut" (Just (0))++delay :: Pattern Double -> OscPattern+delay = make' float delay_p+delay_p = F "delay" (Just (0))++delaytime :: Pattern Double -> OscPattern+delaytime = make' float delaytime_p+delaytime_p = F "delaytime" (Just (-1))++delayfeedback :: Pattern Double -> OscPattern+delayfeedback = make' float delayfeedback_p+delayfeedback_p = F "delayfeedback" (Just (-1))++crush :: Pattern Double -> OscPattern+crush = make' float crush_p+crush_p = F "crush" (Just 0)++coarse :: Pattern Int -> OscPattern+coarse = make' int32 coarse_p+coarse_p = I "coarse" (Just 0)++hcutoff :: Pattern Double -> OscPattern+hcutoff = make' float hcutoff_p+hcutoff_p = F "hcutoff" (Just 0)++hresonance :: Pattern Double -> OscPattern+hresonance = make' float hresonance_p+hresonance_p = F "hresonance" (Just 0)++bandf :: Pattern Double -> OscPattern+bandf = make' float bandf_p+bandf_p = F "bandf" (Just 0)++bandq :: Pattern Double -> OscPattern+bandq = make' float bandq_p+bandq_p = F "bandq" (Just 0)++unit :: Pattern String -> OscPattern+unit = make' string unit_p+unit_p = S "unit" (Just "rate")++loop :: Pattern Int -> OscPattern+loop = make' int32 loop_p+loop_p = I "loop" (Just 1)+
Sound/Tidal/Parse.hs view
@@ -182,15 +182,20 @@ <|> return thing pE :: Pattern a -> Parser (Pattern a)-pE thing = do (n,k) <- parens (pair)- return $ e n k thing+pE thing = do (n,k,s) <- parens (pair)+ return $ unwrap $ eoff <$> n <*> k <*> s <*> atom thing <|> return thing- where pair = do a <- integer+ where pair = do a <- pSequence pInt spaces symbol "," spaces- b <- integer- return (fromIntegral a, fromIntegral b)+ b <- pSequence pInt+ c <- do symbol ","+ spaces+ pSequence pInt+ <|> return (atom 0)+ return (fromIntegral <$> a, fromIntegral <$> b, fromIntegral <$> c)+ eoff n k s p = ((s%(fromIntegral k)) <~) (e n k p) pReplicate :: Pattern a -> Parser ([Pattern a])
Sound/Tidal/Pattern.hs view
@@ -127,10 +127,10 @@ withResultTime = withResultArc . mapArc -- | @overlay@ combines two @Pattern@s into a new pattern, so that--- their events are combined over time.+-- their events are combined over time. This is the same as the infix+-- operator `<>`. overlay :: Pattern a -> Pattern a -> Pattern a overlay p p' = Pattern $ \a -> (arc p a) ++ (arc p' a)-(>+<) = overlay -- | @stack@ combines a list of @Pattern@s into a new pattern, so that -- their events are combined over time.@@ -368,9 +368,9 @@ -- 'Equal power' for gain-based transitions envEq :: Pattern Double-envEq = sig $ \t -> sin (pi/2 * (max 0 $ min (fromRational (1-t)) 1))+envEq = sig $ \t -> sqrt (sin (pi/2 * (max 0 $ min (fromRational (1-t)) 1))) -- Equal power reversed-envEqR = sig $ \t -> cos (pi/2 * (max 0 $ min (fromRational (1-t)) 1))+envEqR = sig $ \t -> sqrt (cos (pi/2 * (max 0 $ min (fromRational (1-t)) 1))) fadeOut :: Time -> Pattern a -> Pattern a fadeOut n = spread' (degradeBy) (slow n $ envL)@@ -476,7 +476,7 @@ -- @p@ into the portion of each cycle given by @t@, and @p'@ into the -- remainer of each cycle. wedge :: Time -> Pattern a -> Pattern a -> Pattern a-wedge t p p' = overlay (densityGap (1/t) p) (t <~ densityGap (1/(1-t)) p')+wedge t p p' = overlay (densityGap (1/t) p) (t ~> densityGap (1/(1-t)) p') whenmod :: Int -> Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a whenmod a b = Sound.Tidal.Pattern.when ((\t -> (t `mod` a) >= b ))@@ -631,3 +631,23 @@ -- randomises the order in which they are played. randcat :: [Pattern a] -> Pattern a randcat ps = spread' (<~) (discretise 1 $ ((%1) . fromIntegral) <$> irand (fromIntegral $ length ps)) (slowcat ps)++toMIDI :: Pattern String -> Pattern Int+toMIDI p = fromJust <$> (filterValues (isJust) (noteLookup <$> p))+ where+ noteLookup [] = Nothing+ noteLookup s | last s `elem` ['0' .. '9'] = elemIndex s names+ | otherwise = noteLookup (s ++ "5")+ names = take 128 [(n ++ show o)+ | o <- octaves,+ n <- notes+ ]+ notes = ["c","cs","d","ds","e","f","fs","g","gs","a","as","b"]+ octaves = [0 .. 10]++tom = toMIDI++fit :: Int -> [a] -> Pattern Int -> Pattern a+fit perCycle xs p = (xs !!!) <$> (Pattern $ \a -> map ((\e -> (mapThd' (+ (cyclePos perCycle e)) e))) (arc p a))+ where cyclePos perCycle e = perCycle * (floor $ eventStart e)+
Sound/Tidal/Strategies.hs view
@@ -12,6 +12,7 @@ import Sound.Tidal.Stream import Sound.Tidal.Time import Sound.Tidal.Utils+import Sound.Tidal.Params import qualified Sound.OSC.FD as OSC.FD stutter n t p = stack $ map (\i -> (t * (fromIntegral i)) ~> p) [0 .. (n-1)]@@ -21,14 +22,19 @@ quad = stutter 4 double = echo -jux f p = stack [p |+| pan (pure 0), f $ p |+| pan (pure 1)]-juxcut f p = stack [p |+| pan (pure 0) |+| cut (pure (-1)), - f $ p |+| pan (pure 1) |+| cut (pure (-2))+jux f p = stack [p # pan (pure 0), f $ p # pan (pure 1)]+juxcut f p = stack [p # pan (pure 0) # cut (pure (-1)), + f $ p # pan (pure 1) # cut (pure (-2)) ]-jux4 f p = stack [p |+| pan (pure 0), f $ p |+| pan (pure 2)] -juxBy n f p = stack [p |+| pan (pure $ 0.5 - (n/2)), f $ p |+| pan (pure $ 0.5 + (n/2))]+jux' fs p = stack $ map (\n -> ((fs !! n) p) # pan (pure $ fromIntegral n / fromIntegral l)) [0 .. l-1]+ where l = length fs +-- For multichannel+jux4 f p = stack [p # pan (pure (5/8)), f $ p # pan (pure (1/8))]++juxBy n f p = stack [p # pan (pure $ 0.5 - (n/2)), f $ p # pan (pure $ 0.5 + (n/2))]+ -- every 4 (smash 4 [1, 2, 3]) $ sound "[odx sn/2 [~ odx] sn/3, [~ hh]*4]" smash n xs p = slowcat $ map (\n -> slow n p') xs@@ -42,6 +48,8 @@ samples :: Applicative f => f String -> f Int -> f String samples p p' = pick <$> p <*> p' +samples' :: Applicative f => f String -> f Int -> f String+samples' p p' = (flip pick) <$> p' <*> p {- scrumple :: Time -> Pattern a -> Pattern a -> Pattern a@@ -68,7 +76,7 @@ spin copies p = stack $ map (\n -> let offset = toInteger n % toInteger copies in offset <~ p- |+| pan (pure $ fromRational offset)+ # pan (pure $ fromRational offset) ) [0 .. (copies - 1)] @@ -84,7 +92,7 @@ rand4 = ((*4) <$> rand) stackwith p ps | null ps = silence- | otherwise = stack $ map (\(i, p') -> p' |+| (((fromIntegral i) % l) <~ p)) (zip [0 ..] ps)+ | otherwise = stack $ map (\(i, p') -> p' # (((fromIntegral i) % l) <~ p)) (zip [0 ..] ps) where l = fromIntegral $ length ps {-@@ -141,7 +149,7 @@ en ns p = stack $ map (\(i, (k, n)) -> e k n (samples p (pure i))) $ enumerate ns weave :: Rational -> OscPattern -> [OscPattern] -> OscPattern-weave t p ps = weave' t p (map (\x -> (x |+|)) ps)+weave t p ps = weave' t p (map (\x -> (x #)) ps) weave' :: Rational -> Pattern a -> [Pattern a -> Pattern a] -> Pattern a weave' t p fs | l == 0 = silence@@ -160,3 +168,12 @@ steps :: [(String, String)] -> Pattern String steps = stack . map (\(a,b) -> step a b)++off :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a+off t f p = superimpose (f . (t ~>)) p++offadd :: Num a => Time -> a -> Pattern a -> Pattern a+offadd t n p = off t ((+n) <$>) p++up :: Pattern Double -> OscPattern+up = speed . ((1.059466**) <$>)
Sound/Tidal/Stream.hs view
@@ -192,20 +192,33 @@ merge :: OscPattern -> OscPattern -> OscPattern merge x y = (flip Map.union) <$> x <*> y +infixl 1 |=|+(|=|) :: OscPattern -> OscPattern -> OscPattern+(|=|) = merge++(#) = (|=|)++mergeWith op x y = (Map.unionWithKey f) <$> x <*> y+ where f (F _ _) (Just a) (Just b) = do a' <- datum_float a+ b' <- datum_float b+ return $ float (op a' b')+ f _ a b = b++infixl 1 |*|+(|*|) :: OscPattern -> OscPattern -> OscPattern+(|*|) = mergeWith (*)+ infixl 1 |+| (|+|) :: OscPattern -> OscPattern -> OscPattern-(|+|) = merge+(|+|) = mergeWith (+) -transition :: (IO T.Time) -> MVar (OscPattern, [OscPattern]) -> (T.Time -> [OscPattern] -> OscPattern) -> OscPattern -> IO ()-transition getNow mv f p =- do now <- getNow- ps <- takeMVar mv- let p' = f now (p:snd ps)- -- don't put the transition in history, only- -- the target pattern, or things get overcomplex- -- (transitions of transitions)- putMVar mv (p', (p:snd ps))- return ()+infixl 1 |-|+(|-|) :: OscPattern -> OscPattern -> OscPattern+(|-|) = mergeWith (-)++infixl 1 |/|+(|/|) :: OscPattern -> OscPattern -> OscPattern+(|/|) = mergeWith (/) setter :: MVar (a, [a]) -> a -> IO () setter ds p = do ps <- takeMVar ds
+ Sound/Tidal/Transition.hs view
@@ -0,0 +1,85 @@+module Sound.Tidal.Transition where++import Sound.Tidal.Dirt+import Sound.Tidal.Stream+import Sound.Tidal.Pattern+import Sound.Tidal.Time+import Sound.Tidal.Params+import Sound.Tidal.Utils++import Control.Concurrent.MVar+import Control.Applicative++import Data.Monoid++transition :: (IO Time) -> MVar (OscPattern, [OscPattern]) -> (Time -> [OscPattern] -> OscPattern) -> OscPattern -> IO ()+transition getNow mv f p =+ do now <- getNow+ ps <- takeMVar mv+ let p' = f now (p:snd ps)+ -- don't put the transition in history, only+ -- the target pattern, or things get overcomplex+ -- (transitions of transitions)+ putMVar mv (p', (p:snd ps))+ return ()++-- Pans the last n versions of the pattern across the field+histpan :: Int -> Time -> [OscPattern] -> OscPattern+histpan _ _ [] = silence+histpan 0 _ _ = silence+histpan n _ ps = stack $ map (\(i,p) -> p # pan (atom $ (fromIntegral i) / (fromIntegral n'))) (enumerate ps')+ where ps' = take n ps+ n' = length ps' -- in case there's fewer patterns than requested++-- generalizing wash to use pattern transformers on fadeout, fadein, and delay+-- to start of transition+superwash :: (Pattern a -> Pattern a) -> (Pattern a -> Pattern a) -> Time -> Time -> Time -> [Pattern a] -> Pattern a+superwash _ _ _ _ _ [] = silence+superwash _ _ _ _ _ (p:[]) = p+superwash fout fin delay dur now (p:p':_) = + (playWhen (< (now + delay)) p') <>+ (playWhen (between (now + delay) (now + delay + dur)) $ fout p') <>+ (playWhen (>= (now + delay + dur)) $ fin p)+ where+ between lo hi x = (x >= lo) && (x < hi)++wash :: (Pattern a -> Pattern a) -> Time -> Time -> [Pattern a] -> Pattern a+wash _ _ _ [] = silence+wash _ _ _ (p:[]) = p+wash f t now (p:p':_) = overlay (playWhen (< (now + t)) $ f p') (playWhen (>= (now + t)) p)++-- Increase comb filter to anticipate 'drop' to next pattern+anticipateIn :: Time -> Time -> [OscPattern] -> OscPattern+anticipateIn t now = wash (spread' (stut 8 0.2) (now ~> (slow t $ (toRational . (1-)) <$> envL))) t now++anticipate :: Time -> [OscPattern] -> OscPattern+anticipate = anticipateIn 8++-- Just stop for a bit before playing new pattern+wait :: Time -> Time -> [OscPattern] -> OscPattern+wait t _ [] = silence+wait t now (p:_) = playWhen (>= (nextSam (now+t-1))) p++-- transition at cycle boundary after n cycles+jumpIn' :: Int -> Time -> [OscPattern] -> OscPattern+jumpIn' n now = superwash id id ((nextSam now) - now + (fromIntegral n)) 0 now++-- sharp transition a certain number of cycles in the future+jumpIn :: Int -> Time -> [OscPattern] -> OscPattern+jumpIn n = superwash id id (fromIntegral n) 0++jump :: Time -> [OscPattern] -> OscPattern+jump = jumpIn 0++-- transition at next cycle boundary where cycle mod n == 0+jumpMod :: Int -> Time -> [OscPattern] -> OscPattern+jumpMod n now = jumpIn ((n-1) - ((floor now) `mod` n)) now++-- Degrade the new pattern over time until it goes to nothing+mortal :: Time -> Time -> Time -> [OscPattern] -> OscPattern+mortal _ _ _ [] = silence+mortal lifespan release now (p:_) = overlay (playWhen (<(now+lifespan)) p) (playWhen (>= (now+lifespan)) (fadeOut' (now + lifespan) release p))++dirtSetters :: IO Time -> IO (OscPattern -> IO (), (Time -> [OscPattern] -> OscPattern) -> OscPattern -> IO ())+dirtSetters getNow = do ds <- dirtState+ return (setter ds, transition getNow ds)
Sound/Tidal/Utils.hs view
@@ -63,3 +63,6 @@ mergelists xs [] = xs mergelists [] ys = ys mergelists (x:xs) (y:ys) = x : y : mergelists xs ys++(!!!) :: [a] -> Int -> a+(!!!) xs n = xs !! (n `mod` length xs)
tidal.cabal view
@@ -1,5 +1,5 @@ name: tidal-version: 0.5.3+version: 0.6 synopsis: Pattern language for improvised music -- description: homepage: http://tidal.lurk.org/@@ -28,5 +28,7 @@ Sound.Tidal.Context Sound.Tidal.Utils Sound.Tidal.SuperCollider+ Sound.Tidal.Params+ Sound.Tidal.Transition Build-depends: base < 5, process, parsec, hosc > 0.13, hashable, colour, containers, time, websockets > 0.8, text, mtl >=2.1, transformers, mersenne-random-pure64,binary, bytestring, hmt