module Csound.Typed.Types.MixSco(
M(..), delayAndRescaleCsdEventListM, renderMixSco, renderMixSco_
) where
import Control.Monad
import Csound.Dynamic
import Csound.Typed.GlobalState.Elements
data M
= Snd InstrId (CsdEventList [E])
| Eff InstrId (CsdEventList M) Int
delayAndRescaleCsdEventListM :: CsdEventList M -> CsdEventList M
delayAndRescaleCsdEventListM = delayCsdEventListM . rescaleCsdEventListM
delayCsdEventListM :: CsdEventList M -> CsdEventList M
delayCsdEventListM es =
es { csdEventListNotes = fmap delayCsdEventM $ csdEventListNotes es }
delayCsdEventM :: CsdEvent M -> CsdEvent M
delayCsdEventM (start, dur, evt) = (start, dur, phi evt)
where phi x = case x of
Snd n evts -> Snd n $ delayCsdEventList start evts
Eff n evts arityIn -> Eff n (delayCsdEventListM $ delayCsdEventList start evts) arityIn
rescaleCsdEventListM :: CsdEventList M -> CsdEventList M
rescaleCsdEventListM es =
es { csdEventListNotes = fmap rescaleCsdEventM $ csdEventListNotes es }
rescaleCsdEventM :: CsdEvent M -> CsdEvent M
rescaleCsdEventM (start, dur, evt) = (start, dur, phi evt)
where phi x = case x of
Snd n evts -> Snd n $ rescaleCsdEventList (dur/localDur) evts
Eff n evts arityIn -> Eff n (rescaleCsdEventListM $ rescaleCsdEventList (dur/localDur) evts) arityIn
where localDur = case x of
Snd _ evts -> csdEventListDur evts
Eff _ evts _ -> csdEventListDur evts
renderMixSco :: Monad m => Int -> CsdEventList M -> DepT m [E]
renderMixSco arity evts = do
chnId <- chnRefAlloc arity
go chnId evts
readChn chnId
where
go :: Monad m => ChnRef -> CsdEventList M -> DepT m ()
go outId xs = mapM_ (onEvent outId) $ csdEventListNotes xs
onEvent :: Monad m => ChnRef -> CsdEvent M -> DepT m ()
onEvent outId (start, dur, x) = case x of
Snd instrId es -> onSnd instrId outId es
Eff instrId es arityIn -> onEff instrId start dur outId es arityIn
onSnd instrId outId es = forM_ (csdEventListNotes es) $ \(start, dur, args) ->
event_i $ Event instrId (double start) (double dur) (args ++ [chnRefId outId])
onEff instrId start dur outId es arityIn = do
inId <- chnRefAlloc arityIn
event_i $ Event instrId (double start) (double dur) [chnRefId inId, chnRefId outId]
go inId es
renderMixSco_ :: Monad m => CsdEventList M -> DepT m ()
renderMixSco_ evts = mapM_ onEvent $ csdEventListNotes evts
where
onEvent :: Monad m => CsdEvent M -> DepT m ()
onEvent (start, dur, x) = case x of
Snd instrId es -> onSnd instrId es
Eff instrId es _ -> onEff instrId start dur es
onSnd instrId es = forM_ (csdEventListNotes es) $ \(start, dur, args) ->
event_i $ Event instrId (double start) (double dur) args
onEff instrId start dur es = do
event_i $ Event instrId (double start) (double dur) []
renderMixSco_ es