tidal 1.7.4 → 1.7.5
raw patch · 13 files changed
+123/−38 lines, 13 filesdep −semigroups
Dependencies removed: semigroups
Files
- CHANGELOG.md +10/−0
- src/Sound/Tidal/Control.hs +3/−1
- src/Sound/Tidal/ParseBP.hs +22/−19
- src/Sound/Tidal/Pattern.hs +2/−7
- src/Sound/Tidal/Show.hs +4/−4
- src/Sound/Tidal/Stream.hs +2/−0
- src/Sound/Tidal/Tempo.hs +8/−0
- src/Sound/Tidal/Version.hs +1/−1
- test/Sound/Tidal/ChordsTest.hs +55/−0
- test/Sound/Tidal/ParseTest.hs +4/−0
- test/Sound/Tidal/UITest.hs +8/−2
- test/Test.hs +2/−0
- tidal.cabal +2/−4
CHANGELOG.md view
@@ -1,5 +1,15 @@ # TidalCycles log of changes +## 1.7.5 - Dalbeattie+ * Minor change to _splice so that it respects if the speed parameter was already declared @onthepeakofnormal+ * Some tests for chords @cleary+ * Remove direct semigroups dependency @yaxu+ * Derive functor for pattern @yaxu+ * Handle negative ratio shorthands for rationals @ndr_brt+ * drawLine - draw non-events with periods @yaxu+ * Parse chord without root note @yaxu+ * Fix clock sharing between tidal processes @yaxu+ ## 1.7.4 - Symonds Yat b * Fixes for bipolar waveforms (sine2, etc) @mindofmatthew * More playback controls for OSC API @mindofmatthew
src/Sound/Tidal/Control.hs view
@@ -285,7 +285,9 @@ _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 f ev = case Map.lookup "speed" (value ev) of+ (Just (VF s)) -> ev {value = Map.insert "speed" (VF $ d*s) (value ev)} -- if there is a speed parameter already present+ _ -> ev {value = Map.insert "speed" (VF d) (value ev)} where d = sz / fromRational (wholeStop ev - wholeStart ev) sz = 1/fromIntegral bits
src/Sound/Tidal/ParseBP.hs view
@@ -452,8 +452,8 @@ let v = applySign s f do TPat_Stack . map (TPat_Atom Nothing . (+ v)) <$> parseChord <|> return (TPat_Atom Nothing v)- <|> do TPat_Stack . map (TPat_Atom Nothing) <$> parseChord- <|> do TPat_Atom Nothing <$> pRatioChar+ <|> do TPat_Stack . map (TPat_Atom Nothing) <$> parseChord+ <|> do TPat_Atom Nothing <$> pRatioChar pBool :: MyParser (TPat Bool) pBool = wrapPos $ do oneOf "t1"@@ -491,7 +491,7 @@ o <- length <$> many (char 'o') let chord' = take i $ drop j $ concatMap (\x -> map (+ x) chord) [0,12..] -- open voiced chords- let chordo' = if o > 0 then+ let chordo' = if o > 0 && n > 2 then [ (chord' !! 0 - 12), (chord' !! 2 - 12), (chord' !! 1) ] ++ reverse (take (length chord' - 3) (reverse chord')) else chord' return chordo'@@ -565,22 +565,25 @@ return (a, b, c) pRatio :: MyParser Rational-pRatio = do s <- sign- n <- read <$> many1 digit- result <- do char '%'- d <- decimal- return (n%d)- <|>- do char '.'- frac <- many1 digit- -- A hack, but not sure if doing this- -- numerically would be any faster..- return (toRational ((read $ show n ++ "." ++ frac) :: Double))- <|>- return (n%1)- c <- pRatioChar <|> return 1- return $ applySign s (result * c)- <|> pRatioChar+pRatio = do + s <- sign+ r <- do n <- read <$> many1 digit+ result <- do char '%'+ d <- decimal+ return (n%d)+ <|>+ do char '.'+ frac <- many1 digit+ -- A hack, but not sure if doing this+ -- numerically would be any faster..+ return (toRational ((read $ show n ++ "." ++ frac) :: Double))+ <|>+ return (n%1)+ c <- pRatioChar <|> return 1+ return (result * c)+ <|> + pRatioChar+ return $ applySign s r pRatioChar :: Fractional a => MyParser a pRatioChar = do char 'w'
src/Sound/Tidal/Pattern.hs view
@@ -53,17 +53,12 @@ -- | A datatype representing events taking place over time data Pattern a = Pattern {query :: State -> [Event a]}- deriving Generic+ deriving (Generic, Functor)+ instance NFData a => NFData (Pattern a) -- type StateMap = Map.Map String (Pattern Value) type ControlPattern = Pattern ValueMap---- * Functor--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
src/Sound/Tidal/Show.hs view
@@ -188,12 +188,12 @@ s = stepcount pat rs = toRational s drawLevel :: [Event Char] -> String- drawLevel [] = replicate s ' '- drawLevel (e:es) = map f $ take s $ zip (drawLevel es ++ repeat ' ') (drawEvent e ++ repeat ' ')- f (' ', x) = x+ drawLevel [] = replicate s '.'+ drawLevel (e:es) = map f $ take s $ zip (drawLevel es ++ repeat '.') (drawEvent e ++ repeat '.')+ f ('.', x) = x f (x, _) = x drawEvent :: Event Char -> String- drawEvent ev = replicate (floor $ rs * evStart) ' '+ 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/Stream.hs view
@@ -469,6 +469,8 @@ 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 + when (tempo /= tempo') $ T.sendTempo tempo'+ (tempo', sMap'') `seq` return (tempo', sMap'') where modifyState :: ((T.Tempo, ValueMap) -> IO (T.Tempo, ValueMap)) -> IO () modifyState io = E.mask $ \restore -> do
src/Sound/Tidal/Tempo.hs view
@@ -46,6 +46,14 @@ } deriving Show +instance Eq Tempo where+ (==) t t' = and [(atTime t) == (atTime t'),+ (atCycle t) == (atCycle t'),+ (cps t) == (cps t'),+ (paused t) == (paused t'),+ (nudged t) == (nudged t')+ ]+ data State = State {ticks :: Int, start :: O.Time, nowTimespan :: (O.Time, O.Time),
src/Sound/Tidal/Version.hs view
@@ -21,7 +21,7 @@ -} tidal_version :: String-tidal_version = "1.7.4"+tidal_version = "1.7.5" tidal_status :: IO () tidal_status = tidal_status_string >>= putStrLn
+ test/Sound/Tidal/ChordsTest.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE OverloadedStrings #-}++module Sound.Tidal.ChordsTest where++import TestUtils+import Test.Microspec++import Prelude hiding ((<*), (*>))++import Sound.Tidal.Pattern++run :: Microspec ()+run =+ describe "Sound.Tidal.Chords" $ do+ describe "chord" $ do+ describe "chord length adjustments" $ do+ it "can remove notes from the end of the list when length given is less than the standard chord length" $ do+ compareP (Arc 0 1)+ ("'major'1")+ ("[0]" :: Pattern Note)+ it "can do nothing when the length given is the same as the standard chord length" $ do+ compareP (Arc 0 1)+ ("'major'3")+ ("[0, 4, 7]" :: Pattern Note)+ it "can append chord notes at higher octaves to the list when length given is greater than the standard chord length" $ do+ compareP (Arc 0 1)+ ("'major'5")+ ("[0, 4, 7, 12, 16]" :: Pattern Note)+ describe "open voiced chords" $ do+ it "can subtract 12 from the first and third element of a list, and sort them in ascending numerical order" $ do+ compareP (Arc 0 1)+ ("'major'o")+ ("[-12, -5, 4]" :: Pattern Note)+ it "not crash if chord length is < 3" $ do+ compareP (Arc 0 1)+ ("'five'o")+ ("[0, 7]" :: Pattern Note)+ describe "chord inversions" $ do+ it "can add 12 to the first element of a list, and sort in ascending numeric order (1st inversion)" $ do+ compareP (Arc 0 1)+ ("'major'i")+ ("[4, 7, 12]" :: Pattern Note)+ it "can add 12 to the first two elements of a list, and sort in ascending numeric order (2nd inversion)" $ do+ compareP (Arc 0 1)+ ("'major'ii")+ ("[7, 12, 16]" :: Pattern Note)+ it "can add 12 to the first three elements of a list, and sort in ascending numeric order (3rd inversion)" $ do+ compareP (Arc 0 1)+ ("'major'iii")+ ("[12, 16, 19]" :: Pattern Note)+ describe "edge cases" $ do+ it "gracefully handle an inversion when there are more inversions than notes in the chord (4th inversion of a 3 note chord)" $ do+ compareP (Arc 0 1)+ ("'major'iiii")+ ("[16, 19, 24]" :: Pattern Note)
test/Sound/Tidal/ParseTest.hs view
@@ -127,6 +127,10 @@ compareP (Arc 0 2) ("c'major e'minor f'dim7" :: Pattern Int) ("c e f" + "'major 'minor 'dim7")+ it "can parse note chords" $ do+ compareP (Arc 0 2)+ ("c'major c'minor" :: Pattern Note)+ ("'major 'minor") it "handle trailing and leading whitespaces" $ do compareP (Arc 0 1) (" bd " :: Pattern String)
test/Sound/Tidal/UITest.hs view
@@ -330,11 +330,17 @@ ("t f f f f f f f" :: Pattern Bool) describe "binaryN" $ do- it "convert a number to a pattern of boolean of specified length" $ do+ it "converts a number to a pattern of boolean of specified length" $ do compareP (Arc 0 1) (binaryN 4 "8") ("t f f f" :: Pattern Bool)- it "convert a number to a pattern of boolean of specified patternable length" $ do+ it "converts a number to a pattern of boolean of specified patternable length" $ do compareP (Arc 0 2) (binaryN "<4 8>" "8") (cat ["t f f f", "f f f f t f f f"] :: Pattern Bool)++ describe "off" $ do+ it "superimposes and shifts pattern" $ do+ compareP (Arc 0 1)+ (off "-e" id $ s "0")+ (superimpose ("e" <~) $ s "0")
test/Test.hs view
@@ -8,6 +8,7 @@ import Sound.Tidal.PatternTest import Sound.Tidal.ControlTest import Sound.Tidal.ScalesTest+import Sound.Tidal.ChordsTest import Sound.Tidal.StreamTest import Sound.Tidal.UITest import Sound.Tidal.UtilsTest@@ -21,6 +22,7 @@ Sound.Tidal.PatternTest.run Sound.Tidal.ControlTest.run Sound.Tidal.ScalesTest.run+ Sound.Tidal.ChordsTest.run Sound.Tidal.StreamTest.run Sound.Tidal.UITest.run Sound.Tidal.UtilsTest.run
tidal.cabal view
@@ -1,5 +1,5 @@ name: tidal-version: 1.7.4+version: 1.7.5 synopsis: Pattern language for improvised music description: Tidal is a domain specific language for live coding patterns. homepage: http://tidalcycles.org/@@ -64,9 +64,6 @@ , primitive < 0.8 , random < 1.3 - if !impl(ghc >= 8.4.1)- build-depends: semigroups >= 0.18 && < 0.20- test-suite tests type: exitcode-stdio-1.0 main-is: Test.hs@@ -79,6 +76,7 @@ Sound.Tidal.ParseTest Sound.Tidal.PatternTest Sound.Tidal.ScalesTest+ Sound.Tidal.ChordsTest Sound.Tidal.StreamTest Sound.Tidal.UITest Sound.Tidal.UtilsTest