Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/Sound/Tidal/Config.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module Sound.Tidal.Config where

import qualified Sound.Tidal.Link as Link
import Data.Int(Int64)
import Foreign.C.Types (CDouble)

Expand Down Expand Up @@ -35,7 +34,7 @@ data Config = Config {cCtrlListen :: Bool,
cSkipTicks :: Int64,
cVerbose :: Bool,
cQuantum :: CDouble,
cCyclesPerBeat :: CDouble
cBeatsPerCycle :: CDouble
}

defaultConfig :: Config
Expand All @@ -52,5 +51,5 @@ defaultConfig = Config {cCtrlListen = True,
cSkipTicks = 10,
cVerbose = True,
cQuantum = 4,
cCyclesPerBeat = 4
cBeatsPerCycle = 4
}
7 changes: 3 additions & 4 deletions src/Sound/Tidal/Safe/Context.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ module Sound.Tidal.Safe.Context
, streamSetB
, transition
, module C
, startTidal, superdirtTarget, Target(..)
, Target(..)
)
where

Expand All @@ -66,16 +66,15 @@ import Sound.Tidal.UI as C
import Sound.Tidal.Version as C

import qualified Sound.Tidal.Context as C
import Sound.Tidal.Context
(Stream, Pattern, ControlPattern, Time)
import Sound.Tidal.Context (Stream)
import Control.Monad.Reader
import Control.Monad.Catch

newtype Op r = Op ( ReaderT Stream IO r )
deriving (Functor, Applicative, Monad, MonadCatch,MonadThrow)

exec :: Stream -> Op r -> IO r
exec s (Op m) = runReaderT m s
exec stream (Op m) = runReaderT m stream

op1 f = Op $ do a <- ask; lift $ f a
op2 f b = Op $ do a <- ask; lift $ f a b
Expand Down
18 changes: 5 additions & 13 deletions src/Sound/Tidal/Stream.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import Sound.Tidal.Utils ((!!!))
import Data.List (sortOn)
import System.Random (getStdRandom, randomR)
import Sound.Tidal.Show ()
import Data.Word (Word8)

import Sound.Tidal.Version

Expand Down Expand Up @@ -206,7 +205,6 @@ startStream config oscmap
pMapMV <- newMVar Map.empty
bussesMV <- newMVar []
globalFMV <- newMVar id
tempoMV <- newEmptyMVar
actionsMV <- newEmptyMVar

tidal_status_string >>= verbose config
Expand All @@ -223,7 +221,7 @@ startStream config oscmap
) (oAddress target) (oPort target)
return $ Cx {cxUDP = u, cxAddr = remote_addr, cxBusAddr = remote_bus_addr, cxTarget = target, cxOSCs = os}
) oscmap
let bpm = (coerce defaultCps) * 60 * (cCyclesPerBeat config)
let bpm = (coerce defaultCps) * 60 * (cBeatsPerCycle config)
abletonLink <- Link.create bpm
let stream = Stream {sConfig = config,
sBusses = bussesMV,
Expand Down Expand Up @@ -359,8 +357,6 @@ toOSC busses pe osc@(OSC _ _)
-- Map.mapKeys tail is used to remove ^ from the keys.
-- In case (value e) has the key "", we will get a crash here.
playmap' = Map.union (Map.mapKeys tail $ Map.map (\(VI i) -> VS ('c':(show $ toBus i))) busmap) playmap
toChannelId (VI i) = VS ('c':(show $ toBus i))
toChannelId _ = error "All channels IDs should be VI"
val = value . peEvent
-- Only events that start within the current nowArc are included
playmsg | peHasOnset pe = do
Expand Down Expand Up @@ -469,17 +465,15 @@ onTick stream st ops s
-- However, since the full arc is processed at once and since Link does not support
-- scheduling, tempo change may affect scheduling of events that happen earlier
-- in the normal stream (the one handled by onTick).
onSingleTick :: Stream -> Link.Micros -> T.LinkOperations -> ValueMap -> ControlPattern -> IO ValueMap
onSingleTick stream now ops s pat = do
onSingleTick :: Stream -> T.LinkOperations -> ValueMap -> ControlPattern -> IO ValueMap
onSingleTick stream ops s pat = do
pMapMV <- newMVar $ Map.singleton "fake"
(PlayState {pattern = pat,
mute = False,
solo = False,
history = []
}
)
bpm <- (T.getTempo ops)
let cps = realToFrac $ ((T.beatToCycles ops) bpm) / 60

-- The nowArc is a full cycle
let state = TickState {tickArc = (Arc 0 1), tickNudge = 0}
Expand Down Expand Up @@ -511,7 +505,6 @@ doTick stream st ops sMap =
sGlobalF <- readMVar (sGlobalFMV stream)
bpm <- (T.getTempo ops)
let
config = sConfig stream
cxs = sCxs stream
patstack = sGlobalF $ playStack pMap
cps = ((T.beatToCycles ops) bpm) / 60
Expand Down Expand Up @@ -743,15 +736,14 @@ recvMessagesTimeout n sock = fmap (maybe [] O.packetMessages) $ O.recvPacketTime
streamGetcps :: Stream -> IO Double
streamGetcps s = do
let config = sConfig s
now <- Link.clock (sLink s)
ss <- Link.createAndCaptureAppSessionState (sLink s)
bpm <- Link.getTempo ss
return $! coerce $ bpm / (cCyclesPerBeat config) / 60
return $! coerce $ bpm / (cBeatsPerCycle config) / 60

streamGetnow :: Stream -> IO Double
streamGetnow s = do
let config = sConfig s
ss <- Link.createAndCaptureAppSessionState (sLink s)
now <- Link.clock (sLink s)
beat <- Link.beatAtTime ss now (cQuantum config)
return $! coerce $ beat / (cCyclesPerBeat config)
return $! coerce $ beat / (cBeatsPerCycle config)
1 change: 0 additions & 1 deletion src/Sound/Tidal/StreamTypes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module Sound.Tidal.StreamTypes where
import qualified Data.Map.Strict as Map
import Sound.Tidal.Pattern
import Sound.Tidal.Show ()
import qualified Sound.Tidal.Link as Link

data PlayState = PlayState {pattern :: ControlPattern,
mute :: Bool,
Expand Down
17 changes: 8 additions & 9 deletions src/Sound/Tidal/Tempo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import Sound.Tidal.Config
import Sound.Tidal.Utils (writeError)
import qualified Sound.Tidal.Link as Link
import Foreign.C.Types (CDouble(..))
import Data.Coerce (coerce)
import System.IO (hPutStrLn, stderr)
import Data.Int(Int64)

Expand Down Expand Up @@ -64,7 +63,7 @@ data State = State {ticks :: Int64,
data ActionHandler =
ActionHandler {
onTick :: TickState -> LinkOperations -> P.ValueMap -> IO P.ValueMap,
onSingleTick :: Link.Micros -> LinkOperations -> P.ValueMap -> P.ControlPattern -> IO P.ValueMap,
onSingleTick :: LinkOperations -> P.ValueMap -> P.ControlPattern -> IO P.ValueMap,
updatePattern :: ID -> P.ControlPattern -> IO ()
}

Expand All @@ -88,11 +87,11 @@ setNudge actionsMV nudge = modifyMVar_ actionsMV (\actions -> return $ SetNudge
timeToCycles' :: Config -> Link.SessionState -> Link.Micros -> IO P.Time
timeToCycles' config ss time = do
beat <- Link.beatAtTime ss time (cQuantum config)
return $! (toRational beat) / (toRational (cCyclesPerBeat config))
return $! (toRational beat) / (toRational (cBeatsPerCycle config))

cyclesToTime :: Config -> Link.SessionState -> P.Time -> IO Link.Micros
cyclesToTime config ss cyc = do
let beat = (fromRational cyc) * (cCyclesPerBeat config)
let beat = (fromRational cyc) * (cBeatsPerCycle config)
Link.timeAtBeat ss beat (cQuantum config)

addMicrosToOsc :: Link.Micros -> O.Time -> O.Time
Expand All @@ -108,8 +107,8 @@ clocked config stateMV mapMV actionsMV ac abletonLink
frameTimespan = round $ (cFrameTimespan config) * 1000000
quantum :: CDouble
quantum = cQuantum config
cyclesPerBeat :: CDouble
cyclesPerBeat = cCyclesPerBeat config
beatsPerCycle :: CDouble
beatsPerCycle = cBeatsPerCycle config
loopInit :: IO a
loopInit =
do
Expand Down Expand Up @@ -202,9 +201,9 @@ clocked config stateMV mapMV actionsMV ac abletonLink
putMVar stateMV streamState'
tick st'
btc :: CDouble -> CDouble
btc beat = beat / cyclesPerBeat
btc beat = beat / beatsPerCycle
ctb :: CDouble -> CDouble
ctb cyc = cyc * cyclesPerBeat
ctb cyc = cyc * beatsPerCycle
processActions :: State -> [TempoAction] -> IO State
processActions st [] = return $! st
processActions st actions = do
Expand Down Expand Up @@ -252,7 +251,7 @@ clocked config stateMV mapMV actionsMV ac abletonLink
beatToCycles = btc,
cyclesToBeat = ctb
}
streamState'' <- (onSingleTick ac) nowLink ops streamState' pat
streamState'' <- (onSingleTick ac) ops streamState' pat
Link.commitAndDestroyAppSessionState abletonLink sessionState
Link.destroySessionState zeroedSessionState
return (st', streamState'')
Expand Down
3 changes: 1 addition & 2 deletions src/Sound/Tidal/Transition.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ module Sound.Tidal.Transition where

import Prelude hiding ((<*), (*>))

import Control.Concurrent.MVar (readMVar, swapMVar, modifyMVar_)
import Control.Concurrent.MVar (modifyMVar_)

import qualified Sound.OSC.FD as O
import qualified Data.Map.Strict as Map
-- import Data.Maybe (fromJust)

Expand Down