{-# LANGUAGE NoImplicitPrelude #-}
{-|
Control curve generation
-}

module Synthesizer.Physical.Control where

import qualified Synthesizer.SampleRateContext.Control as CtrlC
import qualified Synthesizer.Plain.Control as Ctrl
import qualified Synthesizer.Physical.Signal as SigP
import Synthesizer.Physical.Signal(toTimeScalar)

import qualified Algebra.OccasionallyScalar as OccScalar
import qualified Algebra.Module         as Module
import qualified Algebra.Transcendental as Trans
import qualified Algebra.Real           as Real
import qualified Algebra.Ring           as Ring

-- import PreludeBase
-- import NumericPrelude


exponential :: (Trans.C a, Ring.C a', Real.C a', OccScalar.C a a') =>
      a' {-^ sample rate -}
   -> a' {-^ time where the function reaches 1\/e of the initial value -}
   -> a' {-^ initial value -}
   -> SigP.T a a' a a' a
         {-^ exponential decay -}
exponential sampleRate time y0 =
   SigP.lift0 (CtrlC.exponential time y0) sampleRate


exponential2 :: (Trans.C a, Ring.C a', Real.C a', OccScalar.C a a') =>
      a' {-^ sample rate -}
   -> a' {-^ half life -}
   -> a' {-^ initial value -}
   -> SigP.T a a' a a' a
         {-^ exponential decay -}
exponential2 sampleRate halfLife y0 =
   SigP.lift0 (CtrlC.exponential2 halfLife y0) sampleRate


vectorExponential ::
   (Trans.C t, Ring.C t',
    OccScalar.C t t', Module.C t yv) =>
      t' {-^ sample rate -}
   -> t' {-^ time where the function reaches 1\/e of the initial value -}
   -> y' {-^ amplitude unit -}
   -> yv {-^ initial value -}
   -> SigP.T t t' y y' yv
         {-^ exponential decay -}
vectorExponential sampleRate time amplitude y0 =
   let z = SigP.cons sampleRate amplitude
              (Ctrl.vectorExponential
                 (toTimeScalar z time) y0)
   in  z


vectorExponential2 ::
   (Trans.C t, Ring.C t',
    OccScalar.C t t', Module.C t yv) =>
      t' {-^ sample rate -}
   -> t' {-^ half life -}
   -> y' {-^ amplitude unit -}
   -> yv {-^ initial value -}
   -> SigP.T t t' y y' yv
         {-^ exponential decay -}
vectorExponential2 sampleRate halfLife amplitude y0 =
   let z = SigP.cons sampleRate amplitude
              (Ctrl.vectorExponential2
                 (toTimeScalar z halfLife) y0)
   in  z