packages feed

tidal 1.1.2 → 1.2.0

raw patch · 9 files changed

+40/−108 lines, 9 files

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # TidalCycles log of changes +## 1.2.0 - Hunters Bar++* Simplify <* and *>, removing any distinction between analogue and digital patterns+ ## 1.1.2 - Eccy Road  * Usability fix for `binary` / `binaryN` (use squeezeJoin on input pattern)
src/Sound/Tidal/Control.hs view
@@ -392,10 +392,10 @@ _getP d f pat = (fromMaybe d . f) <$> pat  _cX :: a -> (Value -> Maybe a) -> String -> Pattern a-_cX d f s = Pattern Analog $ \(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) $ Map.lookup s m) a  _cX_ :: (Value -> Maybe a) -> String -> Pattern a-_cX_ f s = Pattern Analog $ \(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) $ Map.lookup s m) a  cF :: Double -> String -> Pattern Double cF d = _cX d getF
src/Sound/Tidal/Core.hs view
@@ -17,7 +17,7 @@  -- | Takes a function from time to values, and turns it into a 'Pattern'. sig :: (Time -> a) -> Pattern a-sig f = Pattern Analog q+sig f = Pattern q   where q (State (Arc s e) _)           | s > e = []           | otherwise = [Event (Arc s e) (Arc s e) (f (s+((e-s)/2)))]@@ -190,8 +190,7 @@ -- in turn, then the second cycle from each, and so on. cat :: [Pattern a] -> Pattern a cat [] = silence--- TODO I *guess* it would be digital..-cat ps = Pattern Digital 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))}@@ -234,10 +233,7 @@ -- | 'overlay' combines two 'Pattern's into a new pattern, so that -- their events are combined over time.  overlay :: Pattern a -> Pattern a -> Pattern a--- Analog if they're both analog-overlay !p@(Pattern Analog _) !p'@(Pattern Analog _) = Pattern Analog $ \st -> query p st ++ query p' st--- Otherwise digital. Won't really work to have a mixture.. Hmm-overlay !p !p' = Pattern Digital $ \st -> query p st ++ query p' st+overlay !p !p' = Pattern $ \st -> query p st ++ query p' st  -- | An infix alias of @overlay@ (<>) :: Pattern a -> Pattern a -> Pattern a
src/Sound/Tidal/Pattern.hs view
@@ -223,13 +223,8 @@ -- | A function that represents events taking place over time type Query a = (State -> [Event a]) --- | Also known as Continuous vs Discrete/Amorphous vs Pulsating etc.-data Nature = Analog | Digital-            deriving (Eq, Show)---- | A datatype that's basically a query, plus a hint about whether its events--- are Analogue or Digital by nature-data Pattern a = Pattern {nature :: Nature, query :: Query a}+-- | A datatype that's basically a query+data Pattern a = Pattern {query :: Query a}  data Value = VS { svalue :: String }            | VF { fvalue :: Double }@@ -306,96 +301,39 @@  instance NFData a =>    NFData (Pattern a) where -    rnf (Pattern _ q) = rnf $ \s -> q s+    rnf (Pattern q) = rnf $ \s -> q s  instance Functor Pattern where   -- | apply a function to all the values in a pattern   fmap f p = p {query = fmap (fmap f) . query p} -instance Applicative Pattern where-  -- | Repeat the given value once per cycle, forever-  pure v = Pattern Digital $ \(State a _) ->-    map (\a' -> Event a' (sect a a') v) $ cycleArcsInArc a--  (<*>) pf@(Pattern Digital _) px@(Pattern Digital _) = Pattern Digital q+applyPatToPat :: (Arc -> Arc -> 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 (Event fWhole fPart f) =                 map                 (\(Event xWhole xPart x) ->-                  do whole' <- subArc xWhole fWhole+                  do whole' <- combineWholes fWhole xWhole                      part' <- subArc fPart xPart                      return (Event whole' part' (f x))                 )-                (query px $ st {arc = fPart})-  (<*>) pf@(Pattern Digital _) px@(Pattern Analog _) = Pattern Digital q-    where q st = concatMap match $ query pf st-            where-              match (Event fWhole fPart f) =-                map-                (Event fWhole fPart . f . value)-                (query px $ st {arc = pure (start fPart)})+                (query px $ st {arc = fWhole}) -  (<*>) pf@(Pattern Analog _) px@(Pattern Digital _) = Pattern Digital q-    where q st = concatMap match $ query px st-            where-              match (Event xWhole xPart x) =-                map-                (\e -> Event xWhole xPart (value e x))-                (query pf st {arc = pure (start xPart)})+instance Applicative Pattern where+  -- | Repeat the given value once per cycle, forever+  pure v = Pattern $ \(State a _) ->+    map (\a' -> Event a' (sect a a') v) $ cycleArcsInArc a -  (<*>) pf px = Pattern Analog q-    where q st = concatMap match $ query pf st-            where-              match ef =-                map-                (Event (arc st) (arc st) . value ef . value)-                (query px st)+  (<*>) = applyPatToPat subArc --- | Like <*>, but the structure only comes from the left+-- | Like <*>, but the 'wholes' come from the left (<*) :: Pattern (a -> b) -> Pattern a -> Pattern b-(<*) pf@(Pattern Analog _) px@(Pattern Analog _) = Pattern Analog q-  where q st = concatMap match $ query pf st-          where-            match (Event fWhole fPart f) =-              map-              (Event fWhole fPart . f . value) $-              query px st -- for continuous events, use the original query---- If one of the patterns is digital, treat both as digital.. (TODO - needs extra thought)-(<*) pf px = Pattern Digital q-    where q st = catMaybes $ concatMap match $ query pf st-            where-              match (Event fWhole fPart f) =-                map-                (\(Event _ xPart x) ->-                  do let whole' = fWhole-                     part' <- subArc fPart xPart-                     return (Event whole' part' (f x))-                )-                (query px $ st {arc = fPart})+(<*) = applyPatToPat (\a _ -> Just a) --- | Like <*>, but the structure only comes from the right+-- | Like <*>, but the 'wholes' come from the right (*>) :: Pattern (a -> b) -> Pattern a -> Pattern b-(*>) pf@(Pattern Analog _) px@(Pattern Analog _) = Pattern Analog q-  where q st = concatMap match $ query px st-          where-            match (Event xWhole xPart x) =-              map-              (\e -> Event xWhole xPart (value e x)) $-              query pf st -- for continuous events, use the original query--(*>) pf px = Pattern Digital q-    where q st = catMaybes $ concatMap match $ query pf st-            where-              match (Event _ fPart f) =-                map-                (\(Event xWhole xPart x) ->-                  do let whole' = xWhole-                     part' <- subArc fPart xPart-                     return (Event whole' part' (f x))-                )-                (query px $ st {arc = fPart})+(*>) = applyPatToPat (\_ b -> Just b)  infixl 4 <*, *> @@ -659,16 +597,10 @@ -- * Internal functions  empty :: Pattern a-empty = Pattern {nature = Digital, query = const []}+empty = Pattern {query = const []}  queryArc :: Pattern a -> Arc -> [Event a] queryArc p a = query p $ State a Map.empty --isDigital :: Pattern a -> Bool-isDigital = (== Digital) . nature--isAnalog :: Pattern a -> Bool-isAnalog = not . isDigital  -- | Splits queries that span cycles. For example `query p (0.5, 1.5)` would be -- turned into two queries, `(0.5,1)` and `(1,1.5)`, and the results
src/Sound/Tidal/UI.hs view
@@ -79,7 +79,7 @@ @ -} rand :: Fractional a => Pattern a-rand = Pattern Analog (\(State a@(Arc s e) _) -> [Event a a (realToFrac $ timeToRand $ (e + s)/2)])+rand = Pattern (\(State a@(Arc s e) _) -> [Event a a (realToFrac $ timeToRand $ (e + s)/2)])  {- | Just like `rand` but for whole numbers, `irand n` generates a pattern of (pseudo-) random whole numbers between `0` to `n-1` inclusive. Notably used to pick a random samples from a folder:@@ -987,7 +987,7 @@  -- TODO - what does this do? Something for @stripe@ .. randStruct :: Int -> Pattern Int-randStruct n = splitQueries $ Pattern {nature = Digital, query = f}+randStruct n = splitQueries $ Pattern {query = f}   where f st = map (\(a,b,c) -> Event a (fromJust b) c) $ filter (\(_,x,_) -> isJust x) as           where as = map (\(i, Arc s' e') ->                     (Arc (s' + sam s) (e' + sam s),@@ -1088,7 +1088,7 @@ markovPat = tParam2 _markovPat  _markovPat :: Int -> Int -> [[Double]] -> Pattern Int-_markovPat n xi tp = splitQueries $ Pattern Digital (\(State a@(Arc s e) _) -> +_markovPat n xi tp = splitQueries $ Pattern (\(State a@(Arc s e) _) ->    queryArc (listToPat $ runMarkov n tp xi (sam s)) a)  {-|@@ -1281,7 +1281,7 @@ randrun :: Int -> Pattern Int randrun 0 = silence randrun n' =-  splitQueries $ Pattern Digital (\(State a@(Arc s _) _) -> events a $ sam s)+  splitQueries $ Pattern (\(State a@(Arc s _) _) -> events a $ sam s)   where events a seed = mapMaybe toEv $ zip arcs shuffled           where shuffled = map snd $ sortOn fst $ zip rs [0 .. (n'-1)]                 rs = timeToRands seed n'@@ -1718,7 +1718,7 @@ -- | Serialises a pattern so there's only one event playing at any one -- time, making it 'monophonic'. Events which start/end earlier are given priority. mono :: Pattern a -> Pattern a-mono p = Pattern Digital $ \(State a cm) -> flatten $ query p (State a cm) where+mono p = Pattern $ \(State a cm) -> flatten $ query p (State a cm) where   flatten :: [Event a] -> [Event a]   flatten = mapMaybe constrainPart . truncateOverlaps . sortOn whole   truncateOverlaps [] = []@@ -1739,7 +1739,7 @@ -- smooth :: Pattern Double -> Pattern Double  smooth :: Fractional a => Pattern a -> Pattern a-smooth p = Pattern Analog $ \st@(State a cm) -> tween st a $ query monoP (State (midArc a) cm)+smooth p = Pattern $ \st@(State a cm) -> tween st a $ query monoP (State (midArc a) cm)   where     midArc a = Arc (mid (start a, stop a)) (mid (start a, stop a))     tween _ _ [] = []
src/Sound/Tidal/Version.hs view
@@ -1,4 +1,4 @@ module Sound.Tidal.Version where  tidal_version :: String-tidal_version = "1.1.2"+tidal_version = "1.2.0"
test/Sound/Tidal/CoreTest.hs view
@@ -105,14 +105,14 @@         (map value $ queryArc ((+1) <$> saw) (Arc 0.5 0.5)) `shouldBe` [1.5 :: Float]       it "works on the left of <*>" $ do         (queryArc ((+) <$> saw <*> pure 3) (Arc 0 1))-          `shouldBe` fmap toEvent [(((0,1), (0,1)), 3 :: Float)]+          `shouldBe` fmap toEvent [(((0,1), (0,1)), 3.5 :: Float)]       it "works on the right of <*>" $ do         (queryArc ((fast 4 $ pure (+3)) <*> saw) (Arc 0 1))           `shouldBe` fmap toEvent-          [(((0,0.25), (0,0.25)), 3 :: Float),-            (((0.25,0.5), (0.25,0.5)), 3.25),-            (((0.5,0.75), (0.5,0.75)), 3.5),-            (((0.75,1), (0.75,1)), 3.75)+          [(((0,0.25), (0,0.25)), 3.125 :: Float),+            (((0.25,0.5), (0.25,0.5)), 3.375),+            (((0.5,0.75), (0.5,0.75)), 3.625),+            (((0.75,1), (0.75,1)), 3.875)           ]       it "can be reversed" $ do         it "works with whole cycles" $
test/Sound/Tidal/UITest.hs view
@@ -44,7 +44,7 @@       it "can hold a value over multiple cycles" $ do         comparePD (Arc 0 8)           (segment 0.5 saw)-          (slow 2 "0.5" :: Pattern Double)+          (slow 2 "0" :: Pattern Double)       {-       -- not sure what this is supposed to do!       it "holding values over multiple cycles works in combination" $ do
tidal.cabal view
@@ -1,5 +1,5 @@ name:                tidal-version:             1.1.2+version:             1.2.0 synopsis:            Pattern language for improvised music -- description: homepage:            http://tidalcycles.org/