packages feed

tidal 0.2.13 → 0.3

raw patch · 8 files changed

+115/−50 lines, 8 files

Files

Sound/Tidal/Pattern.hs view
@@ -30,21 +30,25 @@   show p@(Pattern _) = show $ arc p (0, 1)  instance Functor Pattern where-  fmap f (Pattern a) = Pattern $ fmap (fmap (mapSnd f)) a+  fmap f (Pattern a) = Pattern $ fmap (fmap (mapThd' f)) a  -- | @pure a@ returns a pattern with an event with value @a@, which -- has a duration of one cycle, and repeats every cycle. instance Applicative Pattern where   pure x = Pattern $ \(s, e) -> map -                                (\t -> ((t%1, (t+1)%1), x)) +                                (\t -> ((t%1, (t+1)%1), +                                        (t%1, (t+1)%1),+                                        x+                                       )+                                )                                  [floor s .. ((ceiling e) - 1)]   (Pattern fs) <*> (Pattern xs) =      Pattern $ \a -> concatMap applyX (fs a)-    where applyX ((s,e), f) = -            map (\(_, x) -> ((s,e), f x)) +    where applyX ((s,e), (s', e'), f) = +            map (\(_, _, x) -> ((s,e), (s', e'), f x))                  (filter -                 (\(a', _) -> isIn a' s)-                 (xs (s,e))+                 (\(_, a', _) -> isIn a' s)+                 (xs (s',e'))                 )  -- | @mempty@ is a synonym for @silence@.@@ -58,10 +62,11 @@   return = pure   p >>= f =      Pattern (\a -> concatMap-                   (\((s,e), x) -> mapFsts (const (s,e)) $-                                   filter-                                   (\(a', _) -> isIn a' s)-                                   (arc (f x) (s,e))+                   -- TODO - this is a total guess+                   (\((s,e), (s',e'), x) -> mapSnds' (const (s',e')) $+                                            filter+                                            (\(_, a', _) -> isIn a' s)+                                            (arc (f x) (s',e'))                    )                    (arc p a)              )@@ -89,7 +94,7 @@ -- applied to the @Arc@ values in the events returned from the -- original @Pattern@ @p@. mapResultArc :: (Arc -> Arc) -> Pattern a -> Pattern a-mapResultArc f p = Pattern $ \a -> mapFsts f $ arc p a+mapResultArc f p = Pattern $ \a -> mapArcs f $ arc p a  -- | @mapResultTime f p@ returns a new @Pattern@ with function @f@ -- applied to the both the start and end @Time@ of the @Arc@ values in@@ -126,14 +131,11 @@ cat :: [Pattern a] -> Pattern a cat ps = density (fromIntegral $ length ps) $ slowcat ps -{-slowcat' ps = Pattern $ \a -> concatMap f (arcCycles a)-  where l = length ps-        f (s,e) = arc p (s,e)-          where p = ps !! n-                n = (floor s) `mod` l-} --- Concatenates so that the first loop of each pattern is played in--- turn, second loop of each pattern, and so on..+splitAtSam :: Pattern a -> Pattern a+splitAtSam p = +  Pattern $ \a -> concatMap (\(s,e) -> mapSnds' (trimArc (sam s)) $ arc p (s,e)) (arcCycles a)+  where trimArc s' (s,e) = (max (s') s, min (s'+1) e)  -- | @slowcat@ does the same as @cat@, but maintaining the duration of -- the original patterns. It is the equivalent of @append'@, but with@@ -142,9 +144,10 @@ slowcat :: [Pattern a] -> Pattern a slowcat [] = silence slowcat ps = Pattern $ \a -> concatMap f (arcCycles a)-  where l = length ps+  where ps' = map splitAtSam ps+        l = length ps'         f (s,e) = arc (mapResultTime (+offset) p) (s',e')-          where p = ps !! n+          where p = ps' !! n                 r = (floor s) :: Int                 n = (r `mod` l) :: Int                 offset = (fromIntegral $ r - ((r - n) `div` l)) :: Time@@ -182,12 +185,12 @@ slow t = density (1/t)   --- | The @<~@ operator shift (or rotate) a pattern to the left (or+-- | The @<~@ operator shifts (or rotates) a pattern to the left (or -- counter-clockwise) by the given @Time@ value. For example  -- @(1%16) <~ p@ will return a pattern with all the events moved  -- one 16th of a cycle to the left. (<~) :: Time -> Pattern a -> Pattern a-(<~) t p = filterOffsets $ mapResultTime (+ t) $ mapQueryTime (subtract t) p+(<~) t p = mapResultTime (+ t) $ mapQueryTime (subtract t) p  -- | The @~>@ operator does the same as @~>@ but shifts events to the -- right (or clockwise) rather than to the left.@@ -198,7 +201,7 @@ -- reversed (or mirrored). rev :: Pattern a -> Pattern a rev p = Pattern $ \a -> concatMap -                        (\a' -> mapFsts mirrorArc $ +                        (\a' -> mapArcs mirrorArc $                                  (arc p (mirrorArc a')))                         (arcCycles a) @@ -225,7 +228,7 @@ sig :: (Time -> a) -> Pattern a sig f = Pattern f'   where f' (s,e) | s > e = []-                 | otherwise = [((s,e), f s)]+                 | otherwise = [((s,e), (s,e), f s)]  -- | @sinewave@ returns a @Pattern@ of continuous @Double@ values following a -- sinewave with frequency of one cycle, and amplitude from -1 to 1.@@ -297,16 +300,23 @@ squarewave = ((subtract 1) . (* 2)) <$> squarewave1 square = squarewave --- Filter out events that start before range-filterOffsets :: Pattern a -> Pattern a-filterOffsets (Pattern f) = -  Pattern $ \(s, e) -> filter ((>= s) . eventStart) $ f (s, e)+-- Filter out events that have had their onsets cut off+filterOnsets :: Pattern a -> Pattern a+filterOnsets (Pattern f) = +  Pattern $ (filter (\e -> eventOnset e >= eventStart e)) . f +-- Filter events which have onsets, which are within the given range+filterStartInRange :: Pattern a -> Pattern a+filterStartInRange (Pattern f) = +  Pattern $ \(s,e) -> filter ((>= s) . eventOnset) $ f (s,e)++filterOnsetsInRange = filterOnsets . filterStartInRange+ seqToRelOnsets :: Arc -> Pattern a -> [(Double, a)]-seqToRelOnsets (s, e) p = mapFsts (fromRational . (/ (e-s)) . (subtract s) . fst) $ arc (filterOffsets p) (s, e)+seqToRelOnsets (s, e) p = map (\((s', _), _, x) -> (fromRational $ (s'-s) / (e-s), x)) $ arc (filterOnsetsInRange p) (s, e)  segment :: Pattern a -> Pattern [a]-segment p = Pattern $ \(s,e) -> filter (\((s',e'),_) -> s' < e && e' > s) $ groupByTime (segment' (arc p (s,e)))+segment p = Pattern $ \(s,e) -> filter (\(_,(s',e'),_) -> s' < e && e' > s) $ groupByTime (segment' (arc p (s,e)))  segment' :: [Event a] -> [Event a] segment' es = foldr split es pts@@ -314,16 +324,16 @@  split :: Time -> [Event a] -> [Event a] split _ [] = []-split t ((ev@((s,e), v)):es) | t > s && t < e = ((s,t),v):((t,e),v):(split t es)-                             | otherwise = ev:split t es+split t ((ev@(a,(s,e), v)):es) | t > s && t < e = (a,(s,t),v):(a,(t,e),v):(split t es)+                               | otherwise = ev:split t es  points :: [Event a] -> [Time] points [] = []-points (((s,e), _):es) = s:e:(points es)+points ((_,(s,e), _):es) = s:e:(points es)  groupByTime :: [Event a] -> [Event [a]]-groupByTime es = map mrg $ groupBy ((==) `on` fst) $ sortBy (compare `on` fst) es-  where mrg es@((a, _):_) = (a, map snd es)+groupByTime es = map mrg $ groupBy ((==) `on` snd') $ sortBy (compare `on` snd') es+  where mrg es@((a, a', _):_) = (a, a', map thd' es)  ifp :: (Int -> Bool) -> (Pattern a -> Pattern a) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a ifp test f1 f2 p = Pattern $ \a -> concatMap apply (arcCycles a)@@ -331,4 +341,4 @@                 | otherwise = (arc $ f2 p) a  rand :: Pattern Double-rand = Pattern $ \a -> [(a, fst $ randomDouble $ pureMT $ floor $ (*1000000) $ (midPoint a))]+rand = Pattern $ \a -> [(a, a, fst $ randomDouble $ pureMT $ floor $ (*1000000) $ (midPoint a))]
Sound/Tidal/Strategies.hs view
@@ -42,12 +42,12 @@ spread f xs p = cat $ map (\x -> f x p) xs  slowspread :: (a -> t -> Pattern b) -> [a] -> t -> Pattern b-slowspread f xs p = slow (fromIntegral $ length $ xs) $ spread f xs p+slowspread f xs p = slowcat $ map (\x -> f x p) xs  spread' :: (a -> Pattern b -> Pattern c) -> Pattern a -> Pattern b -> Pattern c spread' f timepat pat =-  Pattern $ \r -> concatMap (\(r', x) -> (arc (f x pat) r')) (rs r)-  where rs r = arc (filterOffsets timepat) r+  Pattern $ \r -> concatMap (\(_,r', x) -> (arc (f x pat) r')) (rs r)+  where rs r = arc (filterOnsetsInRange timepat) r  {- scrumple :: Time -> Pattern a -> Pattern a -> Pattern a@@ -72,14 +72,16 @@  trunc :: Time -> Pattern a -> Pattern a trunc t p = slow t $ Pattern $ \a -> concatMap f $ arcCycles a-  where f a = mapFsts (stretch . trunc') $ arc p (trunc' a)+  where f a = mapArcs (stretch . trunc') $ arc p (trunc' a)         trunc' (s,e) = (min s ((sam s) + t), min e ((sam s) + t))         stretch (s,e) = (sam s + ((s - sam s) / t), sam s + ((e - sam s) / t)) +--spreadf :: [Pattern a -> Pattern b] -> Pattern a -> Pattern b+spreadf ts p = spread ($)+ spin :: Int -> OscPattern -> OscPattern spin steps p = stack $ map (\n -> (((fromIntegral n)%(fromIntegral steps)) <~ p |+| pan (pure $ (fromIntegral n)/(fromIntegral steps)))) [0 .. steps] - {-stripe :: Arc -> Pattern a -> Pattern a stripe (stripeS, stripeE) p = slow t $ Pattern $ \a -> concatMap f $ arcCycles a   where f a = mapFsts (stretch . stripe') $ arc p (stripe' a)@@ -87,7 +89,7 @@         stretch (s,e) = (sam s + ((s - sam s) / t), sam s + ((e - sam s) / t)) -} -+iter :: Int -> Pattern a -> Pattern a iter n p = slowcat $ map (\i -> ((fromIntegral i)%(fromIntegral n)) <~ p) [0 .. n]  spin4 step p = stack $ map (\n -> ((toRational n)/4) <~ p |+| pan (pure $ n)) [0,step .. 3]@@ -102,10 +104,12 @@                | otherwise = stack $ map (\(i, p') -> p' |+| (((fromIntegral i) % l) <~ p)) (zip [0 ..] ps)   where l = fromIntegral $ length ps +{- cross f p p' = Pattern $ \t -> concat [filter flt $ arc p t,                                        filter (not . flt) $ arc p' t                                       ]   where flt = f . cyclePos . fst . fst+-}  inside n f p = density n $ f (slow n p) 
Sound/Tidal/Stream.hs view
@@ -39,6 +39,8 @@  type OscPattern = Pattern OscMap +latency = 0.04+ defaultDatum :: Param -> Maybe Datum defaultDatum (S _ (Just x)) = Just $ string x defaultDatum (I _ (Just x)) = Just $ int32 x@@ -74,7 +76,6 @@ toMessage s shape change ticks (o, m) =   do m' <- applyShape' shape m      let beat = fromIntegral ticks / fromIntegral tpb-         latency = 0.02          logicalNow = (logicalTime change beat)          beat' = (fromIntegral ticks + 1) / fromIntegral tpb          logicalPeriod = (logicalTime change (beat + 1)) - logicalNow@@ -155,14 +156,17 @@         --defaultV Nothing = defaultDatum nParam  makeS = make string++makeF :: OscShape -> String -> Pattern Double -> OscPattern makeF = make float+ makeI = make int32  param :: OscShape -> String -> Param param shape n = head $ filter (\x -> name x == n) (params shape)                  merge :: OscPattern -> OscPattern -> OscPattern-merge x y = Map.union <$> x <*> y+merge x y = (flip Map.union) <$> x <*> y  infixl 1 |+| (|+|) :: OscPattern -> OscPattern -> OscPattern
Sound/Tidal/Time.hs view
@@ -1,5 +1,7 @@ module Sound.Tidal.Time where +import Sound.Tidal.Utils+ -- | Time is represented by a rational number. Each natural number -- represents both the start of the next rhythmic cycle, and the end -- of the previous one. Rational numbers are used so that subdivisions@@ -10,8 +12,14 @@ -- @ { t : s <= t && t < e } @ type Arc = (Time, Time) --- | An Event is a value that occurs during the given @Arc@-type Event a = (Arc, a)+-- | An Event is a value that occurs during the period given by the+-- first @Arc@. The second one indicates the event's "domain of+-- influence". These will often be the same, but many temporal+-- transformations, such as rotation and scaling time, may resuqlt in+-- arcs being split or truncated. In such cases, the first arc is+-- preserved, but the second arc reflects the portion of the event+-- which is relevant.+type Event a = (Arc, Arc, a)  -- | The starting point of the current cycle. A cycle occurs from each -- natural number to the next, so this is equivalent to @floor@.@@ -57,8 +65,15 @@  -- | The start time of the given @Event@ eventStart :: Event a -> Time-eventStart = fst . fst+eventStart = fst . snd' +-- | The start time of the given @Event@+eventOnset :: Event a -> Time+eventOnset = fst . fst'+ -- | The midpoint of an @Arc@ midPoint :: Arc -> Time midPoint (s,e) = s + ((e - s) / 2)++hasOnset :: Event a -> Bool+hasOnset ((s,_), (s',_), _) = s == s'
Sound/Tidal/Utils.hs view
@@ -25,3 +25,29 @@  maybeRead :: String -> Maybe Double maybeRead = fmap fst . listToMaybe . reads++fst' (a, _, _) = a+snd' (_, b, _) = b+thd' (_, _, c) = c+++mapFst' :: (a -> x) -> (a, b, c) -> (x, b, c)+mapFst' f (x,y,z) = (f x,y,z)++mapSnd' :: (b -> x) -> (a, b, c) -> (a, x, c)+mapSnd' f (x,y,z) = (x,f y,z)++mapThd' :: (c -> x) -> (a, b, c) -> (a, b, x)+mapThd' f (x,y,z) = (x,y,f z)++mapFsts' :: (a -> x) -> [(a, b, c)] -> [(x, b, c)]+mapFsts' = fmap . mapFst'++mapSnds' :: (b -> x) -> [(a, b, c)] -> [(a, x, c)]+mapSnds' = fmap . mapSnd'++mapThds' :: (c -> x) -> [(a, b, c)] -> [(a, b, x)]+mapThds' = fmap . mapThd'++mapArcs :: (a -> a) -> [(a, a, x)] -> [(a, a, x)] +mapArcs f = (mapFsts' f) . (mapSnds' f)
doc/tidal.md view
@@ -99,7 +99,7 @@ different parts:  ~~~~ {#mycode .haskell}-d1 $ sound "[bd ht lt, sn cp]"+d1 $ sound "[bd bd bd, sn cp sn cp]" ~~~~  This would play the sequence `bd bd bd` at the same time as `sn cp sn@@ -123,9 +123,11 @@ ~~~~  You can make parts of patterns repeat by using `*`, for example the-following example produces the same pattern as the previous one:+following expressions produce the same pattern:  ~~~~ {#mycode .haskell}+d1 $ sound "[bd bd bd, sn cp sn cp]"+ d1 $ sound "[bd*3, [sn cp]*2]" ~~~~ 
tidal.cabal view
@@ -1,5 +1,5 @@ name:                tidal-version:             0.2.13+version:             0.3 synopsis:            Pattern language for improvised music -- description:          homepage:            http://yaxu.org/tidal/
tidal.el view
@@ -56,6 +56,9 @@     (tidal-see-output))   (tidal-send-string ":set prompt \"\"")   (tidal-send-string ":module Sound.Tidal.Context")+;  (tidal-send-string ":module Volca.Beat Volca.Key")+;  (tidal-send-string "(note, [portamento, expression, voice, octave, detune, vcoegint, cutoff, vcfegint, lforate, lfopitchint, lfocutoffint, attack, decay, sustain, delaytime , delayfeedback], keystop) <- keystart")+;  (tidal-send-string "(drum, [clapSpeed, clavesSpeed, agogoSpeed, crashSpeed, stutterTime, stutterDepth, tomDecay, clhatDecay, ophatDecay, hatGrain], beatstop) <- startbeat")   (tidal-send-string "d1 <- dirtStream")   (tidal-send-string "d2 <- dirtStream")   (tidal-send-string "d3 <- dirtStream")@@ -67,6 +70,7 @@   (tidal-send-string "d9 <- dirtStream")   (tidal-send-string "bps <- bpsSetter")   (tidal-send-string "let hush = mapM_ ($ silence) [d1,d2,d3,d4,d5,d6,d7,d8,d9]")+  (tidal-send-string "let solo = (>>) hush")   (tidal-send-string ":set prompt \"tidal> \"") )