{-# LANGUAGE NoImplicitPrelude #-}
module Synthesizer.Physical.Filter where

import qualified Synthesizer.SampleRateContext.Filter as FiltC
import qualified Synthesizer.Physical.Signal as SigP

import qualified Algebra.OccasionallyScalar as OccScalar
import qualified Algebra.Module         as Module
-- import qualified Algebra.Transcendental as Trans
import qualified Algebra.RealField      as RealField
import qualified Algebra.Field          as Field
import qualified Algebra.Ring           as Ring
import qualified Algebra.Additive       as Additive

import PreludeBase
-- import NumericPrelude


{- * Amplification -}

amplify :: (Ring.C y') =>
      y'
   -> SigP.T t t' y y' yv
   -> SigP.T t t' y y' yv
amplify volume = SigP.lift1 (FiltC.amplify volume)

envelope :: (Eq t', Module.C y0 yv, Ring.C y') =>
      SigP.T t t' y y' y0  {-^ the envelope -}
   -> SigP.T t t' y y' yv  {-^ the signal to be enveloped -}
   -> SigP.T t t' y y' yv
envelope = SigP.lift2 FiltC.envelope



{- * Filter operators from calculus -}

differentiate :: (Additive.C yv, Ring.C a')
   => SigP.T t a' y a' yv -> SigP.T t a' y a' yv
differentiate = SigP.lift1 FiltC.differentiate

integrate :: (Additive.C yv, Field.C a')
   => SigP.T t a' y a' yv -> SigP.T t a' y a' yv
integrate = SigP.lift1 FiltC.integrate


{- * Echo -}

{- | Infinitely many equi-delayed exponentially decaying echos. -}
comb :: (RealField.C t, Ring.C t', OccScalar.C t t', Module.C y yv) =>
   t' -> y -> SigP.T t t' y y' yv -> SigP.T t t' y y' yv
comb time gain = SigP.lift1 (FiltC.comb time gain)