module Csound.Typed.Control.SERef where import Control.DeepSeq(deepseq) import Control.Monad import Csound.Dynamic hiding (newLocalVars) import Csound.Typed.Types.Tuple import Csound.Typed.GlobalState.SE -- | It describes a reference to mutable values. newtype SERef a = SERef [Var] {- { writeSERef :: a -> SE () , readSERef :: SE a } -} writeSERef :: Tuple a => SERef a -> a -> SE () writeSERef (SERef vars) a = fromDep_ $ hideGEinDep $ do vals <- fromTuple a return $ zipWithM_ writeVar vars vals -- (zipWithM_ writeVar vars) =<< lift (fromTuple a) --writeVar :: Var -> E -> Dep () --[Var] (GE [E]) readSERef :: Tuple a => SERef a -> SE a readSERef (SERef vars) = SE $ fmap (toTuple . return) $ mapM readVar vars -- | Allocates a new local (it is visible within the instrument) mutable value and initializes it with value. -- A reference can contain a tuple of variables. newSERef :: Tuple a => a -> SE (SERef a) newSERef t = fmap SERef $ newLocalVars (tupleRates t) (fromTuple t) -- | Adds the given signal to the value that is contained in the -- reference. mixSERef :: (Num a, Tuple a) => SERef a -> a -> SE () mixSERef ref asig = modifySERef ref (+ asig) -- | Modifies the SERef value with given function. modifySERef :: Tuple a => SERef a -> (a -> a) -> SE () modifySERef ref f = do v <- readSERef ref writeSERef ref (f v) -- | An alias for the function @newSERef@. It returns not the reference -- to mutable value but a pair of reader and writer functions. sensorsSE :: Tuple a => a -> SE (SE a, a -> SE ()) sensorsSE a = do ref <- newSERef a return $ (readSERef ref, writeSERef ref) -- | Allocates a new global mutable value and initializes it with value. -- A reference can contain a tuple of variables. newGlobalSERef :: Tuple a => a -> SE (SERef a) newGlobalSERef t = fmap SERef $ newGlobalVars (tupleRates t) (fromTuple t) -- | An alias for the function @newSERef@. It returns not the reference -- to mutable value but a pair of reader and writer functions. globalSensorsSE :: Tuple a => a -> SE (SE a, a -> SE ()) globalSensorsSE a = do ref <- newSERef a return $ (readSERef ref, writeSERef ref)