From c7a78102b4d2db7068ebb3ad3cfa8bdf11ca8a8f Mon Sep 17 00:00:00 2001 From: Eric Conlon Date: Tue, 25 Apr 2023 12:14:24 -0700 Subject: [PATCH 1/4] 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/4] 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/4] 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 1f38f4a93ae1fd52d19d2f88522792ee9ab16325 Mon Sep 17 00:00:00 2001 From: Matthew Kaney Date: Mon, 15 Apr 2024 10:07:01 -0400 Subject: [PATCH 4/4] 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