synthesizer-0.0.3: src/Synthesizer/Plain/Modifier.hs
{- |
Support for stateful modifiers like controlled filters.
-}
module Synthesizer.Plain.Modifier where
import Control.Monad.State (State(..), zipWithM, evalState)
import qualified Data.List as List
import Prelude hiding (init)
-- Signal.T, re-defined here in order to avoid module cycle
type T a = [a]
data Simple s ctrl a b =
Simple {
init :: s,
step :: ctrl -> a -> State s b
}
{-|
modif is a process controlled by values of type c
with an internal state of type s,
it converts an input value of type a into an output value of type b
while turning into a new state
ToDo:
Shall finite signals be padded with zeros?
-}
static ::
Simple s ctrl a b -> ctrl -> T a -> T b
static modif control x =
evalState (mapM (step modif control) x) (init modif)
{-| Here the control may vary over the time. -}
modulated ::
Simple s ctrl a b -> T ctrl -> T a -> T b
modulated modif control x =
evalState (zipWithM (step modif) control x) (init modif)
data Initialized s init ctrl a b =
Initialized {
initInit :: init -> s,
initStep :: ctrl -> a -> State s b
}
initialize ::
Initialized s init ctrl a b -> init -> Simple s ctrl a b
initialize modif stateInit =
Simple (initInit modif stateInit) (initStep modif)
staticInit ::
Initialized s init ctrl a b -> init -> ctrl -> T a -> T b
staticInit modif state =
static (initialize modif state)
{-| Here the control may vary over the time. -}
modulatedInit ::
Initialized s init ctrl a b -> init -> T ctrl -> T a -> T b
modulatedInit modif state =
modulated (initialize modif state)
{- |
The number of stacked state monads
depends on the size of the list of state values.
This is like a dynamically nested StateT.
-}
stackStatesR :: (a -> State s a) -> (a -> State [s] a)
stackStatesR m =
State . List.mapAccumR (runState . m)
stackStatesL :: (a -> State s a) -> (a -> State [s] a)
stackStatesL m =
State . List.mapAccumL (runState . m)