module Synthesizer.Dimensional.RateAmplitude.Control (
constant, constantVector,
linear, line,
exponential, exponential2, exponentialFromTo,
cubicHermite,
) where
import qualified Synthesizer.Dimensional.Amplitude.Control as CtrlA
import qualified Synthesizer.State.Control as Ctrl
import qualified Synthesizer.Dimensional.Signal.Private as SigA
import qualified Synthesizer.Dimensional.Process as Proc
import Synthesizer.Dimensional.Process
(toTimeScalar, toGradientScalar, DimensionGradient, )
import Synthesizer.Dimensional.Signal.Private
(toAmplitudeScalar, )
import qualified Synthesizer.State.Signal as Sig
import qualified Number.DimensionTerm as DN
import qualified Algebra.DimensionTerm as Dim
import qualified Algebra.Transcendental as Trans
import qualified Algebra.RealField as RealField
import qualified Algebra.Field as Field
import qualified Algebra.RealRing as RealRing
import qualified Algebra.Absolute as Absolute
import NumericPrelude.Numeric
import NumericPrelude.Base
import Prelude ()
constant :: (Absolute.C y, Dim.C u, Dim.C v) =>
DN.T v y
-> Proc.T s u t (SigA.R s v y y)
constant y = Proc.pure $ CtrlA.constant y
constantVector ::
DN.T v y
-> yv
-> Proc.T s u t (SigA.R s v y yv)
constantVector y yv = Proc.pure $ CtrlA.constantVector y yv
linear ::
(Field.C q, Absolute.C q, Dim.C u, Dim.C v) =>
DN.T (DimensionGradient u v) q
-> DN.T v q
-> Proc.T s u q (SigA.R s v q q)
linear slope y0 =
let (amp,sgn) = DN.absSignum y0
in do steep <- toGradientScalar amp slope
return (SigA.fromBody amp (Ctrl.linearMultiscale steep sgn))
line ::
(RealField.C q, Dim.C u, Dim.C v) =>
DN.T u q
-> (DN.T v q, DN.T v q)
-> Proc.T s u q (SigA.R s v q q)
line dur' (y0',y1') =
(toTimeScalar dur') >>= \dur -> return $
let amp = max (DN.abs y0') (DN.abs y1')
y0 = toAmplitudeScalar z y0'
y1 = toAmplitudeScalar z y1'
z = SigA.fromBody amp
(Sig.take (floor dur)
(Ctrl.linearMultiscale ((y1y0)/dur) y0))
in z
exponential :: (Trans.C q, Absolute.C q, Dim.C u, Dim.C v) =>
DN.T u q
-> DN.T v q
-> Proc.T s u q (SigA.R s v q q)
exponential time y0 =
(toTimeScalar time) >>= \t -> return $
let (amp,sgn) = DN.absSignum y0
in SigA.fromBody amp (Ctrl.exponentialMultiscale t sgn)
exponential2 :: (Trans.C q, Absolute.C q, Dim.C u, Dim.C v) =>
DN.T u q
-> DN.T v q
-> Proc.T s u q (SigA.R s v q q)
exponential2 time y0 =
(toTimeScalar time) >>= \t -> return $
let (amp,sgn) = DN.absSignum y0
in SigA.fromBody amp (Ctrl.exponential2Multiscale t sgn)
exponentialFromTo ::
(Trans.C q, RealRing.C q, Dim.C u, Dim.C v) =>
DN.T u q
-> (DN.T v q, DN.T v q)
-> Proc.T s u q (SigA.R s v q q)
exponentialFromTo dur' (y0',y1') =
(toTimeScalar dur') >>= \dur -> return $
let amp = max (DN.abs y0') (DN.abs y1')
y0 = toAmplitudeScalar z y0'
y1 = toAmplitudeScalar z y1'
z = SigA.fromBody amp
(Sig.take (floor dur)
(Ctrl.exponentialFromTo dur y0 y1))
in z
cubicHermite ::
(RealField.C q, Dim.C u, Dim.C v) =>
(DN.T u q, (DN.T v q, DN.T (DimensionGradient u v) q))
-> (DN.T u q, (DN.T v q, DN.T (DimensionGradient u v) q))
-> Proc.T s u q (SigA.R s v q q)
cubicHermite (t0', (y0',dy0')) (t1', (y1',dy1')) =
let amp = max (DN.abs y0') (DN.abs y1')
in do t0 <- toTimeScalar t0'
t1 <- toTimeScalar t1'
dy0 <- toGradientScalar amp dy0'
dy1 <- toGradientScalar amp dy1'
return $
let y0 = toAmplitudeScalar z y0'
y1 = toAmplitudeScalar z y1'
z = SigA.fromBody amp (Ctrl.cubicHermite (t0, (y0,dy0)) (t1, (y1,dy1)))
in z