From c7a78102b4d2db7068ebb3ad3cfa8bdf11ca8a8f Mon Sep 17 00:00:00 2001 From: Eric Conlon Date: Tue, 25 Apr 2023 12:14:24 -0700 Subject: [PATCH 1/7] Add Sound.Tidal.Boot module with standard aliases --- BootTidal.hs | 105 ++++++------------ example.tidal | 5 + src/Sound/Tidal/Boot.hs | 231 ++++++++++++++++++++++++++++++++++++++++ tidal.cabal | 4 +- 4 files changed, 272 insertions(+), 73 deletions(-) create mode 100644 example.tidal create mode 100644 src/Sound/Tidal/Boot.hs diff --git a/BootTidal.hs b/BootTidal.hs index c2548d2d3..e3639b5ae 100644 --- a/BootTidal.hs +++ b/BootTidal.hs @@ -1,82 +1,43 @@ +:set -fno-warn-orphans +:set -XMultiParamTypeClasses :set -XOverloadedStrings :set prompt "" -import Sound.Tidal.Context +default (Signal String, Integer, Double) -import System.IO (hSetEncoding, stdout, utf8) -hSetEncoding stdout utf8 +-- Import all the boot functions and aliases. +import Sound.Tidal.Boot -tidal <- startTidal (superdirtTarget {oLatency = 0.05, oAddress = "127.0.0.1", oPort = 57120}) (defaultConfig {cVerbose = True, cFrameTimespan = 1/20}) +-- Create a Tidal Stream with the default settings. +-- Use 'mkTidalWith' to customize these settings. +tidalInst <- mkTidal -:{ -let only = (hush >>) - p = streamReplace tidal - hush = streamHush tidal - panic = do hush - once $ sound "superpanic" - list = streamList tidal - mute = streamMute tidal - unmute = streamUnmute tidal - unmuteAll = streamUnmuteAll tidal - unsoloAll = streamUnsoloAll tidal - solo = streamSolo tidal - unsolo = streamUnsolo tidal - once = streamOnce tidal - first = streamFirst tidal - asap = once - nudgeAll = streamNudgeAll tidal - all = streamAll tidal - resetCycles = streamResetCycles tidal - setCycle = streamSetCycle tidal - setcps = asap . cps - 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 - wait i t = transition tidal True (Sound.Tidal.Transition.wait t) i - waitT i f t = transition tidal True (Sound.Tidal.Transition.waitT f t) i - jump i = transition tidal True (Sound.Tidal.Transition.jump) i - jumpIn i t = transition tidal True (Sound.Tidal.Transition.jumpIn t) i - jumpIn' i t = transition tidal True (Sound.Tidal.Transition.jumpIn' t) i - jumpMod i t = transition tidal True (Sound.Tidal.Transition.jumpMod t) i - jumpMod' i t p = transition tidal True (Sound.Tidal.Transition.jumpMod' t p) i - mortal i lifespan release = transition tidal True (Sound.Tidal.Transition.mortal lifespan release) i - interpolate i = transition tidal True (Sound.Tidal.Transition.interpolate) i - interpolateIn i t = transition tidal True (Sound.Tidal.Transition.interpolateIn t) i - clutch i = transition tidal True (Sound.Tidal.Transition.clutch) i - clutchIn i t = transition tidal True (Sound.Tidal.Transition.clutchIn t) i - anticipate i = transition tidal True (Sound.Tidal.Transition.anticipate) i - anticipateIn i t = transition tidal True (Sound.Tidal.Transition.anticipateIn t) i - forId i t = transition tidal False (Sound.Tidal.Transition.mortalOverlay t) i - d1 = p 1 . (|< orbit 0) - d2 = p 2 . (|< orbit 1) - d3 = p 3 . (|< orbit 2) - d4 = p 4 . (|< orbit 3) - d5 = p 5 . (|< orbit 4) - d6 = p 6 . (|< orbit 5) - d7 = p 7 . (|< orbit 6) - d8 = p 8 . (|< orbit 7) - d9 = p 9 . (|< orbit 8) - d10 = p 10 . (|< orbit 9) - d11 = p 11 . (|< orbit 10) - d12 = p 12 . (|< orbit 11) - d13 = p 13 - d14 = p 14 - d15 = p 15 - d16 = p 16 -:} +-- This orphan instance makes the boot aliases work! +-- It has to go after you define 'tidalInst'. +instance Tidally where tidal = tidalInst -:{ -let getState = streamGet tidal - setI = streamSetI tidal - setF = streamSetF tidal - setS = streamSetS tidal - setR = streamSetR tidal - setB = streamSetB tidal -:} +-- You can add your own aliases in this file. Here are some examples: +-- :{ +-- let 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 +-- wait i t = transition tidal True (Sound.Tidal.Transition.wait t) i +-- waitT i f t = transition tidal True (Sound.Tidal.Transition.waitT f t) i +-- jump i = transition tidal True (Sound.Tidal.Transition.jump) i +-- jumpIn i t = transition tidal True (Sound.Tidal.Transition.jumpIn t) i +-- jumpIn' i t = transition tidal True (Sound.Tidal.Transition.jumpIn' t) i +-- jumpMod i t = transition tidal True (Sound.Tidal.Transition.jumpMod t) i +-- jumpMod' i t p = transition tidal True (Sound.Tidal.Transition.jumpMod' t p) i +-- mortal i lifespan release = transition tidal True (Sound.Tidal.Transition.mortal lifespan release) i +-- interpolate i = transition tidal True (Sound.Tidal.Transition.interpolate) i +-- interpolateIn i t = transition tidal True (Sound.Tidal.Transition.interpolateIn t) i +-- clutch i = transition tidal True (Sound.Tidal.Transition.clutch) i +-- clutchIn i t = transition tidal True (Sound.Tidal.Transition.clutchIn t) i +-- anticipate i = transition tidal True (Sound.Tidal.Transition.anticipate) i +-- anticipateIn i t = transition tidal True (Sound.Tidal.Transition.anticipateIn t) i +-- forId i t = transition tidal False (Sound.Tidal.Transition.mortalOverlay t) i +-- :} +:set -fwarn-orphans :set prompt "tidal> " :set prompt-cont "" - -default (Pattern String, Integer, Double) diff --git a/example.tidal b/example.tidal new file mode 100644 index 000000000..795b44045 --- /dev/null +++ b/example.tidal @@ -0,0 +1,5 @@ +-- This is an example file you can use to quickly test Tidal editor integration. + +d1 $ s "bd sd bd [~ sd] bd sd bd*3 sd" + +hush diff --git a/src/Sound/Tidal/Boot.hs b/src/Sound/Tidal/Boot.hs new file mode 100644 index 000000000..124d06835 --- /dev/null +++ b/src/Sound/Tidal/Boot.hs @@ -0,0 +1,231 @@ +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedStrings #-} + +module Sound.Tidal.Boot + ( Tidally (..) + , OscMap + , mkConfig + , mkOscMap + , mkTidal + , mkTidalWith + , only + , p + , hush + , panic + , list + , mute + , unmute + , unmuteAll + , unsoloAll + , solo + , unsolo + , once + , asap + , first + , nudgeAll + , all + , resetCycles + , setCycle + , setcps + , getcps + , getnow + , d1 + , d2 + , d3 + , d4 + , d5 + , d6 + , d7 + , d8 + , d9 + , d10 + , d11 + , d12 + , d13 + , d14 + , d15 + , d16 + , getState + , setI + , setF + , setS + , setR + , setB + , module Sound.Tidal.Context + ) +where + +{- + Boot.hs - Shortcuts for using an in-scope Tidal Stream. + Copyright (C) 2023, Alex McLean and contributors + + This library is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library. If not, see . +-} + +import Prelude hiding (all, (*>), (<*)) +import Sound.Tidal.Context hiding (mute, solo) +import Sound.Tidal.ID (ID) +import System.IO (hSetEncoding, stdout, utf8) + +-- | Functions using this constraint can access the in-scope Tidal instance. +-- You must implement an instance of this in 'BootTidal.hs'. Note that GHC +-- will complain that it is an "orphan" instance, but that is ok. +class Tidally where + tidal :: Stream + +type OscMap = [(Target, [OSC])] + +-- | A reasonable config. +mkConfig :: Config +mkConfig = defaultConfig {cVerbose = True, cFrameTimespan = 1 / 20} + +-- | A reasonable OscMap +mkOscMap :: OscMap +mkOscMap = [(superdirtTarget {oLatency = 0.05, oAddress = "127.0.0.1", oPort = 57120}, [superdirtShape])] + +-- | Creates a Tidal instance using default config. Use 'mkTidalWith' to customize. +mkTidal :: IO Stream +mkTidal = mkTidalWith mkConfig mkOscMap + +-- | See 'Sound.Tidal.Stream.startStream'. +mkTidalWith :: Config -> OscMap -> IO Stream +mkTidalWith config oscmap = do + hSetEncoding stdout utf8 + startStream config oscmap + +-- | 'hush' then execute the given action. +only :: Tidally => IO () -> IO () +only = (hush >>) + +-- | See 'Sound.Tidal.Stream.streamReplace'. +p :: Tidally => ID -> ControlSignal -> IO () +p = streamReplace tidal + +-- | See 'Sound.Tidal.Stream.streamHush'. +hush :: Tidally => IO () +hush = streamHush tidal + +panic :: Tidally => IO () +panic = hush >> once (sound "superpanic") + +-- | See 'Sound.Tidal.Stream.streamList'. +list :: Tidally => IO () +list = streamList tidal + +-- | See 'Sound.Tidal.Stream.streamMute'. +mute :: Tidally => ID -> IO () +mute = streamMute tidal + +-- | See 'Sound.Tidal.Stream.streamUnmute'. +unmute :: Tidally => ID -> IO () +unmute = streamUnmute tidal + +-- | See 'Sound.Tidal.Stream.streamUnmuteAll'. +unmuteAll :: Tidally => IO () +unmuteAll = streamUnmuteAll tidal + +-- | See 'Sound.Tidal.Stream.streamUnsoloAll'. +unsoloAll :: Tidally => IO () +unsoloAll = streamUnsoloAll tidal + +-- | See 'Sound.Tidal.Stream.streamSolo'. +solo :: Tidally => ID -> IO () +solo = streamSolo tidal + +-- | See 'Sound.Tidal.Stream.streamUnsolo'. +unsolo :: Tidally => ID -> IO () +unsolo = streamUnsolo tidal + +-- | See 'Sound.Tidal.Stream.streamOnce'. +once :: Tidally => ControlSignal -> IO () +once = streamOnce tidal + +-- | An alias for 'once'. +asap :: Tidally => ControlSignal -> IO () +asap = once + +-- | See 'Sound.Tidal.Stream.first'. +first :: Tidally => ControlSignal -> IO () +first = streamFirst tidal + +-- | See 'Sound.Tidal.Stream.nudgeAll'. +nudgeAll :: Tidally => Double -> IO () +nudgeAll = streamNudgeAll tidal + +-- | See 'Sound.Tidal.Stream.streamAll'. +all :: Tidally => (ControlSignal -> ControlSignal) -> IO () +all = streamAll tidal + +-- | See 'Sound.Tidal.Stream.resetCycles'. +resetCycles :: Tidally => IO () +resetCycles = streamResetCycles tidal + +-- | See 'Sound.Tidal.Stream.streamSetCycle'. +setCycle :: Tidally => Time -> IO () +setCycle = streamSetCycle tidal + +-- | See 'Sound.Tidal.Params.cps'. +setcps :: Tidally => Signal Double -> IO () +setcps = once . cps + +-- | See 'Sound.Tidal.Stream.streamGetcps'. +getcps :: Tidally => IO Double +getcps = streamGetcps tidal + +-- | See 'Sound.Tidal.Stream.streamGetnow'. +getnow :: Tidally => IO Double +getnow = streamGetnow tidal + +-- | Replace what's playing on the given orbit. +d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16 :: Tidally => ControlSignal -> IO () +d1 = p 1 . (|. orbit 0) +d2 = p 2 . (|. orbit 1) +d3 = p 3 . (|. orbit 2) +d4 = p 4 . (|. orbit 3) +d5 = p 5 . (|. orbit 4) +d6 = p 6 . (|. orbit 5) +d7 = p 7 . (|. orbit 6) +d8 = p 8 . (|. orbit 7) +d9 = p 9 . (|. orbit 8) +d10 = p 10 . (|. orbit 9) +d11 = p 11 . (|. orbit 10) +d12 = p 12 . (|. orbit 11) +d13 = p 13 +d14 = p 14 +d15 = p 15 +d16 = p 16 + +-- | See 'Sound.Tidal.Stream.streamGet'. +getState :: Tidally => String -> IO (Maybe Value) +getState = streamGet tidal + +-- | See 'Sound.Tidal.Stream.streamSetI'. +setI :: Tidally => String -> Signal Int -> IO () +setI = streamSetI tidal + +-- | See 'Sound.Tidal.Stream.streamSetF'. +setF :: Tidally => String -> Signal Double -> IO () +setF = streamSetF tidal + +-- | See 'Sound.Tidal.Stream.streamSetS'. +setS :: Tidally => String -> Signal String -> IO () +setS = streamSetS tidal + +-- | See 'Sound.Tidal.Stream.streamSetR'. +setR :: Tidally => String -> Signal Rational -> IO () +setR = streamSetR tidal + +-- | See 'Sound.Tidal.Stream.streamSetB'. +setB :: Tidally => String -> Signal Bool -> IO () +setB = streamSetB tidal diff --git a/tidal.cabal b/tidal.cabal index 453437587..77af41dc4 100644 --- a/tidal.cabal +++ b/tidal.cabal @@ -27,7 +27,9 @@ library autogen-modules: Paths_tidal - Exposed-modules: Sound.Tidal.Bjorklund + Exposed-modules: Sound.Tidal.Arc + Sound.Tidal.Bjorklund + Sound.Tidal.Boot Sound.Tidal.Chords Sound.Tidal.Control Sound.Tidal.Context From 73d5f4d5e4212bfe4b699a7e79e1ad1bff956964 Mon Sep 17 00:00:00 2001 From: Matthew Kaney Date: Fri, 12 Apr 2024 13:44:57 -0400 Subject: [PATCH 2/7] Update clock function names in Boot --- src/Sound/Tidal/Boot.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Sound/Tidal/Boot.hs b/src/Sound/Tidal/Boot.hs index 124d06835..6d95fc620 100644 --- a/src/Sound/Tidal/Boot.hs +++ b/src/Sound/Tidal/Boot.hs @@ -181,11 +181,11 @@ setcps = once . cps -- | See 'Sound.Tidal.Stream.streamGetcps'. getcps :: Tidally => IO Double -getcps = streamGetcps tidal +getcps = streamGetCPS tidal -- | See 'Sound.Tidal.Stream.streamGetnow'. getnow :: Tidally => IO Double -getnow = streamGetnow tidal +getnow = streamGetNow tidal -- | Replace what's playing on the given orbit. d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16 :: Tidally => ControlSignal -> IO () From db9c29eaa3cc6d57a057502692e9d5e3b7241914 Mon Sep 17 00:00:00 2001 From: Matthew Kaney Date: Sat, 13 Apr 2024 11:33:16 -0400 Subject: [PATCH 3/7] Remove 2.0 signals and Arc module --- src/Sound/Tidal/Boot.hs | 24 ++++++++++++------------ tidal.cabal | 3 +-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Sound/Tidal/Boot.hs b/src/Sound/Tidal/Boot.hs index 6d95fc620..40803c5e7 100644 --- a/src/Sound/Tidal/Boot.hs +++ b/src/Sound/Tidal/Boot.hs @@ -109,7 +109,7 @@ only :: Tidally => IO () -> IO () only = (hush >>) -- | See 'Sound.Tidal.Stream.streamReplace'. -p :: Tidally => ID -> ControlSignal -> IO () +p :: Tidally => ID -> ControlPattern -> IO () p = streamReplace tidal -- | See 'Sound.Tidal.Stream.streamHush'. @@ -148,15 +148,15 @@ unsolo :: Tidally => ID -> IO () unsolo = streamUnsolo tidal -- | See 'Sound.Tidal.Stream.streamOnce'. -once :: Tidally => ControlSignal -> IO () +once :: Tidally => ControlPattern -> IO () once = streamOnce tidal -- | An alias for 'once'. -asap :: Tidally => ControlSignal -> IO () +asap :: Tidally => ControlPattern -> IO () asap = once -- | See 'Sound.Tidal.Stream.first'. -first :: Tidally => ControlSignal -> IO () +first :: Tidally => ControlPattern -> IO () first = streamFirst tidal -- | See 'Sound.Tidal.Stream.nudgeAll'. @@ -164,7 +164,7 @@ nudgeAll :: Tidally => Double -> IO () nudgeAll = streamNudgeAll tidal -- | See 'Sound.Tidal.Stream.streamAll'. -all :: Tidally => (ControlSignal -> ControlSignal) -> IO () +all :: Tidally => (ControlPattern -> ControlPattern) -> IO () all = streamAll tidal -- | See 'Sound.Tidal.Stream.resetCycles'. @@ -176,7 +176,7 @@ setCycle :: Tidally => Time -> IO () setCycle = streamSetCycle tidal -- | See 'Sound.Tidal.Params.cps'. -setcps :: Tidally => Signal Double -> IO () +setcps :: Tidally => Pattern Double -> IO () setcps = once . cps -- | See 'Sound.Tidal.Stream.streamGetcps'. @@ -188,7 +188,7 @@ getnow :: Tidally => IO Double getnow = streamGetNow tidal -- | Replace what's playing on the given orbit. -d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16 :: Tidally => ControlSignal -> IO () +d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16 :: Tidally => ControlPattern -> IO () d1 = p 1 . (|. orbit 0) d2 = p 2 . (|. orbit 1) d3 = p 3 . (|. orbit 2) @@ -211,21 +211,21 @@ getState :: Tidally => String -> IO (Maybe Value) getState = streamGet tidal -- | See 'Sound.Tidal.Stream.streamSetI'. -setI :: Tidally => String -> Signal Int -> IO () +setI :: Tidally => String -> Pattern Int -> IO () setI = streamSetI tidal -- | See 'Sound.Tidal.Stream.streamSetF'. -setF :: Tidally => String -> Signal Double -> IO () +setF :: Tidally => String -> Pattern Double -> IO () setF = streamSetF tidal -- | See 'Sound.Tidal.Stream.streamSetS'. -setS :: Tidally => String -> Signal String -> IO () +setS :: Tidally => String -> Pattern String -> IO () setS = streamSetS tidal -- | See 'Sound.Tidal.Stream.streamSetR'. -setR :: Tidally => String -> Signal Rational -> IO () +setR :: Tidally => String -> Pattern Rational -> IO () setR = streamSetR tidal -- | See 'Sound.Tidal.Stream.streamSetB'. -setB :: Tidally => String -> Signal Bool -> IO () +setB :: Tidally => String -> Pattern Bool -> IO () setB = streamSetB tidal diff --git a/tidal.cabal b/tidal.cabal index 77af41dc4..3fc9ef7e5 100644 --- a/tidal.cabal +++ b/tidal.cabal @@ -27,8 +27,7 @@ library autogen-modules: Paths_tidal - Exposed-modules: Sound.Tidal.Arc - Sound.Tidal.Bjorklund + Exposed-modules: Sound.Tidal.Bjorklund Sound.Tidal.Boot Sound.Tidal.Chords Sound.Tidal.Control From f24251f6f47d508e0e531a2a5493f63ee8eefa40 Mon Sep 17 00:00:00 2001 From: heyarne Date: Wed, 19 Apr 2023 18:51:58 +0200 Subject: [PATCH 4/7] Add capital-M aliases for major chords --- src/Sound/Tidal/Chords.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Sound/Tidal/Chords.hs b/src/Sound/Tidal/Chords.hs index 8131dac48..323bc05e7 100644 --- a/src/Sound/Tidal/Chords.hs +++ b/src/Sound/Tidal/Chords.hs @@ -184,14 +184,18 @@ chordTable = [("major", major), ("6by9", sixNine), ("major7", major7), ("maj7", major7), + ("M7", major7), ("major9", major9), ("maj9", major9), + ("M9", major9), ("add9", add9), ("major11", major11), ("maj11", major11), + ("M11", major11), ("add11", add11), ("major13", major13), ("maj13", major13), + ("M13", major13), ("add13", add13), ("dom7", dom7), ("dom9", dom9), From 73070728461c9dcd01cad9ef830a15ccb83f1ede Mon Sep 17 00:00:00 2001 From: Alex McLean Date: Mon, 15 Apr 2024 10:18:14 +0100 Subject: [PATCH 5/7] more efficient sew, plus some auto-reformatting --- src/Sound/Tidal/UI.hs | 78 ++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/src/Sound/Tidal/UI.hs b/src/Sound/Tidal/UI.hs index d0c28c952..ea3ca48a8 100644 --- a/src/Sound/Tidal/UI.hs +++ b/src/Sound/Tidal/UI.hs @@ -1,4 +1,6 @@ -{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, OverloadedStrings #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeSynonymInstances #-} {- UI.hs - Tidal's main 'user interface' functions, for transforming @@ -33,22 +35,25 @@ module Sound.Tidal.UI where -import Prelude hiding ((<*), (*>)) +import Prelude hiding ((*>), (<*)) -import Data.Char (digitToInt, isDigit, ord) -import Data.Bits (testBit, Bits, xor, shiftL, shiftR) +import Data.Bits (Bits, shiftL, shiftR, testBit, xor) +import Data.Char (digitToInt, isDigit, ord) -import Data.Ratio ((%), Ratio) -import Data.Fixed (mod') -import Data.List (sort, sortOn, findIndices, elemIndex, groupBy, transpose, intercalate, findIndex) -import Data.Maybe (isJust, fromJust, fromMaybe, mapMaybe) -import qualified Data.Text as T -import qualified Data.Map.Strict as Map -import Data.Bool (bool) +import Data.Bool (bool) +import Data.Fixed (mod') +import Data.List (elemIndex, findIndex, findIndices, + groupBy, intercalate, sort, sortOn, + transpose) +import qualified Data.Map.Strict as Map +import Data.Maybe (catMaybes, fromJust, fromMaybe, isJust, + mapMaybe) +import Data.Ratio (Ratio, (%)) +import qualified Data.Text as T import Sound.Tidal.Bjorklund (bjorklund) import Sound.Tidal.Core -import qualified Sound.Tidal.Params as P +import qualified Sound.Tidal.Params as P import Sound.Tidal.Pattern import Sound.Tidal.Utils @@ -689,7 +694,7 @@ wedge pt pa pb = innerJoin $ (\t -> _wedge t pa pb) <$> pt _wedge :: Time -> Pattern a -> Pattern a -> Pattern a _wedge 0 _ p' = p' -_wedge 1 p _ = p +_wedge 1 p _ = p _wedge t p p' = overlay (_fastGap (1/t) p) (t `rotR` _fastGap (1/(1-t)) p') @@ -976,10 +981,10 @@ _distrib :: [Int] -> Pattern a -> Pattern a _distrib xs p = boolsToPat (foldr distrib' (replicate (last xs) True) (reverse $ layers xs)) p where distrib' :: [Bool] -> [Bool] -> [Bool] - distrib' [] _ = [] - distrib' (_:a) [] = False : distrib' a [] + distrib' [] _ = [] + distrib' (_:a) [] = False : distrib' a [] distrib' (True:a) (x:b) = x : distrib' a b - distrib' (False:a) b = False : distrib' a b + distrib' (False:a) b = False : distrib' a b layers = map bjorklund . (zip<*>tail) boolsToPat a b' = flip const <$> filterValues (== True) (fastFromList a) <* b' @@ -1296,9 +1301,9 @@ randArcs n = return pairs where pairUp [] = [] pairUp xs = Arc 0 (head xs) : pairUp' xs - pairUp' [] = [] - pairUp' [_] = [] - pairUp' [a, _] = [Arc a 1] + pairUp' [] = [] + pairUp' [_] = [] + pairUp' [a, _] = [Arc a 1] pairUp' (a:b:xs) = Arc a b: pairUp' (b:xs) @@ -1850,12 +1855,12 @@ ur t outer_p ps fs = _slow t $ unwrap $ adjust <$> timedValues (getPat . split < where split = wordsBy (==':') getPat (s:xs) = (match s, transform xs) -- TODO - check this really can't happen.. - getPat _ = error "can't happen?" + getPat _ = error "can't happen?" match s = fromMaybe silence $ lookup s ps' ps' = map (fmap (_fast t)) ps adjust (a, (p, f)) = f a p transform (x:_) a = transform' x a - transform _ _ = id + transform _ _ = id transform' str (Arc s e) p = s `rotR` inside (pure $ 1/(e-s)) (matchF str) p matchF str = fromMaybe id $ lookup str fs timedValues = withEvent (\(Event c (Just a) a' v) -> Event c (Just a) a' (a,v)) . filterDigital @@ -1886,7 +1891,7 @@ inhabit ps p = squeezeJoin $ (\s -> fromMaybe silence $ lookup s ps) <$> p spaceOut :: [Time] -> Pattern a -> Pattern a spaceOut xs p = _slow (toRational $ sum xs) $ stack $ map (`compressArc` p) spaceArcs where markOut :: Time -> [Time] -> [Arc] - markOut _ [] = [] + markOut _ [] = [] markOut offset (x:xs') = Arc offset (offset+x):markOut (offset+x) xs' spaceArcs = map (\(Arc a b) -> Arc (a/s) (b/s)) $ markOut 0 xs s = sum xs @@ -1979,7 +1984,7 @@ _arp name p = arpWith f p ("thumbup", thumbup), ("thumbupdown", \x -> init (thumbup x) ++ init (reverse $ thumbup x)) ] - converge [] = [] + converge [] = [] converge (x:xs) = x : converge' xs converge' [] = [] converge' xs = last xs : converge (init xs) @@ -2020,7 +2025,7 @@ rolledWith t = withEvents aux where aux es = concatMap (steppityIn) (groupBy (\a b -> whole a == whole b) $ ((isRev t) es)) isRev b = (\x -> if x > 0 then id else reverse ) b steppityIn xs = mapMaybe (\(n, ev) -> (timeguard n xs ev t)) $ enumerate xs - timeguard _ _ ev 0 = return ev + timeguard _ _ ev 0 = return ev timeguard n xs ev _ = (shiftIt n (length xs) ev) shiftIt n d (Event c (Just (Arc s e)) a' v) = do a'' <- subArc (Arc newS e) a' @@ -2171,7 +2176,18 @@ _pressBy r pat = squeezeJoin $ (compressTo (r,1) . pure) <$> pat > (s "cp:3*16" # speed sine + 1.5) -} sew :: Pattern Bool -> Pattern a -> Pattern a -> Pattern a -sew pb a b = overlay (mask pb a) (mask (inv pb) b) +-- Replaced with more efficient version below +-- sew pb a b = overlay (mask pb a) (mask (inv pb) b) +sew pb a b = Pattern $ pf + where pf st = concatMap match evs + where evs = query pb st + parts = map part evs + subarc = Arc (minimum $ map start parts) (maximum $ map stop parts) + match ev | value ev = find (query a st {arc = subarc}) ev + | otherwise = find (query b st {arc = subarc}) ev + find evs' ev = catMaybes $ map (check ev) evs' + check bev xev = do newarc <- subArc (part bev) (part xev) + return $ xev {part = newarc} {-| Uses the first (binary) pattern to switch between the following two patterns. The resulting structure comes from the binary @@ -2595,7 +2611,7 @@ contrastRange = contrastBy f f (VF s, VF e) (VF v) = v >= s && v <= e f (VN s, VN e) (VN v) = v >= s && v <= e f (VS s, VS e) (VS v) = v == s && v == e - f _ _ = False + f _ _ = False {- | The @fix@ function applies another function to matching events in a pattern of @@ -2694,7 +2710,7 @@ mono :: Pattern a -> Pattern a 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 [] = [] + truncateOverlaps [] = [] truncateOverlaps (e:es) = e : truncateOverlaps (mapMaybe (snip e) es) -- TODO - decide what to do about analog events.. snip a b | start (wholeOrPart b) >= stop (wholeOrPart a) = Just b @@ -2782,9 +2798,9 @@ deconstruct :: Int -> Pattern String -> String deconstruct n p = intercalate " " $ map showStep $ toList p where showStep :: [String] -> String - showStep [] = "~" + showStep [] = "~" showStep [x] = x - showStep xs = "[" ++ (intercalate ", " xs) ++ "]" + showStep xs = "[" ++ (intercalate ", " xs) ++ "]" toList :: Pattern a -> [[a]] toList pat = map (\(s,e) -> map value $ queryArc (_segment n' pat) (Arc s e)) arcs where breaks = [0, (1/n') ..] @@ -2820,7 +2836,7 @@ _bite n ipat pat = squeezeJoin $ zoompat <$> ipat -- | Chooses from a list of patterns, using a pattern of integers. squeeze :: Pattern Int -> [Pattern a] -> Pattern a -squeeze _ [] = silence +squeeze _ [] = silence squeeze ipat pats = squeezeJoin $ (pats !!!) <$> ipat squeezeJoinUp :: Pattern (ControlPattern) -> ControlPattern @@ -2896,5 +2912,5 @@ grain s w = P.begin b # P.end e necklace :: Rational -> [Int] -> Pattern Bool necklace perCycle xs = _slow ((toRational $ sum xs) / perCycle) $ listToPat $ list xs where list :: [Int] -> [Bool] - list [] = [] + list [] = [] list (x:xs') = (True:(replicate (x-1) False)) ++ list xs' From d48d3d59491353cd9a6373cf8fcca14940654ef0 Mon Sep 17 00:00:00 2001 From: Alex McLean Date: Mon, 15 Apr 2024 14:22:47 +0100 Subject: [PATCH 6/7] bump upper bounds of network dependency to 3.3 --- tidal.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tidal.cabal b/tidal.cabal index 453437587..dd39bb43c 100644 --- a/tidal.cabal +++ b/tidal.cabal @@ -62,7 +62,7 @@ library , hosc >= 0.20 && < 0.21 , text < 2.2 , parsec >= 3.1.12 && < 3.2 - , network < 3.2 + , network < 3.3 , transformers >= 0.5 && < 0.7 , bytestring < 0.13 , clock < 0.9 From 1f38f4a93ae1fd52d19d2f88522792ee9ab16325 Mon Sep 17 00:00:00 2001 From: Matthew Kaney Date: Mon, 15 Apr 2024 10:07:01 -0400 Subject: [PATCH 7/7] Integrate new clock changes into Boot file --- src/Sound/Tidal/Boot.hs | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/Sound/Tidal/Boot.hs b/src/Sound/Tidal/Boot.hs index 40803c5e7..9d4d04a6e 100644 --- a/src/Sound/Tidal/Boot.hs +++ b/src/Sound/Tidal/Boot.hs @@ -4,7 +4,6 @@ module Sound.Tidal.Boot ( Tidally (..) , OscMap - , mkConfig , mkOscMap , mkTidal , mkTidalWith @@ -86,17 +85,13 @@ class Tidally where type OscMap = [(Target, [OSC])] --- | A reasonable config. -mkConfig :: Config -mkConfig = defaultConfig {cVerbose = True, cFrameTimespan = 1 / 20} - -- | A reasonable OscMap mkOscMap :: OscMap mkOscMap = [(superdirtTarget {oLatency = 0.05, oAddress = "127.0.0.1", oPort = 57120}, [superdirtShape])] -- | Creates a Tidal instance using default config. Use 'mkTidalWith' to customize. mkTidal :: IO Stream -mkTidal = mkTidalWith mkConfig mkOscMap +mkTidal = mkTidalWith defaultConfig mkOscMap -- | See 'Sound.Tidal.Stream.startStream'. mkTidalWith :: Config -> OscMap -> IO Stream @@ -180,27 +175,27 @@ setcps :: Tidally => Pattern Double -> IO () setcps = once . cps -- | See 'Sound.Tidal.Stream.streamGetcps'. -getcps :: Tidally => IO Double +getcps :: Tidally => IO Time getcps = streamGetCPS tidal -- | See 'Sound.Tidal.Stream.streamGetnow'. -getnow :: Tidally => IO Double +getnow :: Tidally => IO Time getnow = streamGetNow tidal -- | Replace what's playing on the given orbit. d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16 :: Tidally => ControlPattern -> IO () -d1 = p 1 . (|. orbit 0) -d2 = p 2 . (|. orbit 1) -d3 = p 3 . (|. orbit 2) -d4 = p 4 . (|. orbit 3) -d5 = p 5 . (|. orbit 4) -d6 = p 6 . (|. orbit 5) -d7 = p 7 . (|. orbit 6) -d8 = p 8 . (|. orbit 7) -d9 = p 9 . (|. orbit 8) -d10 = p 10 . (|. orbit 9) -d11 = p 11 . (|. orbit 10) -d12 = p 12 . (|. orbit 11) +d1 = p 1 . (|< orbit 0) +d2 = p 2 . (|< orbit 1) +d3 = p 3 . (|< orbit 2) +d4 = p 4 . (|< orbit 3) +d5 = p 5 . (|< orbit 4) +d6 = p 6 . (|< orbit 5) +d7 = p 7 . (|< orbit 6) +d8 = p 8 . (|< orbit 7) +d9 = p 9 . (|< orbit 8) +d10 = p 10 . (|< orbit 9) +d11 = p 11 . (|< orbit 10) +d12 = p 12 . (|< orbit 11) d13 = p 13 d14 = p 14 d15 = p 15