zwirn-0.2.3.1: src/zwirn-doux/Zwirn/Doux/UI.hs
module Zwirn.Doux.UI where
import Control.Concurrent.MVar
import qualified Data.Map as Map
import qualified Data.Text as T
import Sound.Doux.Engine
import Sound.Tidal.Clock
import qualified Sound.Tidal.Clock as Clock
import Zwirn.Core.Lib.Modulate (shift)
import Zwirn.Doux.Process
import Zwirn.Doux.Types (Stream (..), StreamConfig (..))
import Zwirn.Language.Evaluate (Expression, Zwirn)
import Zwirn.Language.Play
startStream :: StreamConfig -> IO Stream
startStream config = do
let conf = (streamConfigClock config) {clockFrameTimespan = 10 * realToFrac (streamConfigPrecision config)}
d <- create (Config (streamConfigSamples config) (streamConfigInput config) (streamConfigOutput config) (streamConfigHost config) (streamConfigBufferSize config) (streamConfigChannels config) (streamConfigBlockSize config) (streamConfigMaxVoices config))
zMV <- newMVar Map.empty
stMV <- newMVar Map.empty
busMapMV <- newMVar Map.empty
actionMapMV <- newMVar Map.empty
cref <- clocked conf (tickAction d zMV actionMapMV busMapMV stMV (streamConfigPrecision config))
let str = Stream d zMV actionMapMV busMapMV stMV cref config
streamSetBPM str (realToFrac streamDefaultBPM)
return str
streamDefaultBPM :: Double
streamDefaultBPM = 138
streamSet :: Stream -> T.Text -> Expression -> IO ()
streamSet str x ex = modifyMVar_ (sState str) (return . Map.insert x ex)
streamSetCPS :: Stream -> Time -> IO ()
streamSetCPS str c = streamSetBPM str (c * toRational (clockBeatsPerCycle (streamConfigClock $ sConfig str) * 60))
-- | set the bpm in the clock
streamSetBPM :: Stream -> Time -> IO ()
streamSetBPM s = Clock.setBPM (sClockRef s)
streamGetBPM :: Stream -> IO Double
streamGetBPM str = realToFrac <$> Clock.getBPM (sClockRef str)
streamGetCPS :: Stream -> IO Double
streamGetCPS str = realToFrac <$> Clock.getCPS (streamConfigClock $ sConfig str) (sClockRef str)
streamResetCycles :: Stream -> IO ()
streamResetCycles s = streamSetCycle s 0
streamSetCycle :: Stream -> Time -> IO ()
streamSetCycle s = Clock.setClock (sClockRef s)
streamGetCycle :: Stream -> IO Int
streamGetCycle s = floor <$> streamGetNow s
streamEnableLink :: Stream -> IO ()
streamEnableLink s = Clock.enableLink (sClockRef s)
streamDisableLink :: Stream -> IO ()
streamDisableLink s = Clock.disableLink (sClockRef s)
streamGetNow :: Stream -> IO Time
streamGetNow s = Clock.getCycleTime (streamConfigClock $ sConfig s) (sClockRef s)
streamNudge :: Stream -> Double -> IO ()
streamNudge s = Clock.setNudge (sClockRef s)
streamFirst :: Stream -> Zwirn Expression -> IO ()
streamFirst str z = do
dummy <- newMVar $ Map.singleton (TextID $ T.pack "_streamOnceDummy_") (Targeted [] (Normal, z, Nothing))
Clock.clockOnce (tickActionOnce (sDoux str) dummy (sState str) (streamConfigPrecision $ sConfig str)) (streamConfigClock $ sConfig str) (sClockRef str)
streamNow :: Stream -> Zwirn Expression -> IO ()
streamNow str z = do
now <- streamGetNow str
dummy <- newMVar $ Map.singleton (TextID $ T.pack "_streamOnceDummy_") (Targeted [] (Normal, shift (realToFrac $ -now) z, Nothing))
Clock.clockOnce (tickActionOnce (sDoux str) dummy (sState str) (streamConfigPrecision $ sConfig str)) (streamConfigClock $ sConfig str) (sClockRef str)