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)