{- | Copyright : (c) Henning Thielemann 2008 License : GPL Maintainer : synthesizer@henning-thielemann.de Stability : provisional Portability : requires multi-parameter type classes Control curves which can be used as envelopes, for controlling filter parameters and so on. -} module Synthesizer.Dimensional.Rate.Control ({- * Primitives -} constant, linear, exponential, exponential2, ) where import qualified Synthesizer.Dimensional.Straight.Signal as SigS import qualified Synthesizer.State.Control as Ctrl -- import qualified Synthesizer.State.Signal as Sig import qualified Synthesizer.Dimensional.Process as Proc -- import Synthesizer.Dimensional.Process (($#), ) import qualified Number.DimensionTerm as DN import qualified Algebra.DimensionTerm as Dim -- import Number.DimensionTerm ((&*&)) import qualified Algebra.Transcendental as Trans import qualified Algebra.Field as Field -- import qualified Algebra.Real as Real import qualified Algebra.Ring as Ring -- import qualified Algebra.Additive as Additive import NumericPrelude import PreludeBase import Prelude () {-# INLINE constant #-} constant :: (Ring.C y, Dim.C u) => Proc.T s u t (SigS.R s y) constant = Proc.pure $ SigS.fromSamples $ Ctrl.constant one {- | Caution: This control curve can contain samples with an absolute value greater than 1. The linear curve starts with zero. -} {-# INLINE linear #-} linear :: (Field.C q, Dim.C u) => DN.T u q {-^ distance until curve reaches one -} -> Proc.T s u q (SigS.R s q) linear dist = fmap (SigS.fromSamples . Ctrl.linearMultiscaleNeutral . recip) (Proc.toTimeScalar dist) {-# INLINE exponential #-} exponential :: (Trans.C q, Dim.C u) => DN.T u q {-^ time where the function reaches 1\/e of the initial value -} -> Proc.T s u q (SigS.R s q) exponential time = fmap (SigS.fromSamples . Ctrl.exponentialMultiscaleNeutral) (Proc.toTimeScalar time) {- take 1000 $ show (run (fixSampleRate 100 (exponential 0.1 1)) :: SigDouble) -} {-# INLINE exponential2 #-} exponential2 :: (Trans.C q, Dim.C u) => DN.T u q {-^ half life, time where the function reaches 1\/2 of the initial value -} -> Proc.T s u q (SigS.R s q) exponential2 time = fmap (SigS.fromSamples . Ctrl.exponential2MultiscaleNeutral) (Proc.toTimeScalar time)