{- | Copyright : (c) Henning Thielemann 2008 License : GPL Maintainer : synthesizer@henning-thielemann.de Stability : provisional Portability : requires multi-parameter type classes -} module Synthesizer.Dimensional.Amplitude.Filter ( {- * Non-recursive -} {- ** Amplification -} amplify, amplifyDimension, negate, envelope, envelopeVector, envelopeVectorDimension, ) where import qualified Synthesizer.Dimensional.Abstraction.RateIndependent as Ind import qualified Synthesizer.Dimensional.Abstraction.Homogeneous as Hom import qualified Synthesizer.Dimensional.Abstraction.Flat as Flat import qualified Synthesizer.Dimensional.RatePhantom as RP -- import qualified Synthesizer.Dimensional.Straight.Signal as SigS import qualified Synthesizer.Dimensional.Amplitude.Signal as SigA -- import Synthesizer.Dimensional.Amplitude.Signal (toAmplitudeScalar) import qualified Number.DimensionTerm as DN import qualified Algebra.DimensionTerm as Dim import Number.DimensionTerm ((&*&)) -- import qualified Synthesizer.State.Signal as Sig import qualified Synthesizer.State.Filter.NonRecursive as FiltNR -- import qualified Algebra.Transcendental as Trans -- import qualified Algebra.Field as Field import qualified Algebra.Ring as Ring import qualified Algebra.Additive as Additive import qualified Algebra.Module as Module -- import NumericPrelude hiding (negate) -- import PreludeBase as P import Prelude (($)) {- | The amplification factor must be positive. -} {-# INLINE amplify #-} amplify :: (Ind.C w, Ring.C y, Dim.C u) => y -> w (SigA.S u y) yv -> w (SigA.S u y) yv amplify volume x = SigA.replaceAmplitude (DN.scale volume $ SigA.amplitude x) x {-# INLINE amplifyDimension #-} amplifyDimension :: (Ind.C w, Ring.C y, Dim.C u, Dim.C v) => DN.T v y -> w (SigA.S u y) yv -> w (SigA.S (Dim.Mul v u) y) yv amplifyDimension volume x = SigA.replaceAmplitude (volume &*& SigA.amplitude x) x -- FIXME: move to Dimensional.Straight {-# INLINE negate #-} negate :: (Ind.C w, Hom.C sig, Additive.C yv) => w sig yv -> w sig yv negate = Ind.processSignal (Hom.unwrappedProcessSamples Additive.negate) -- FIXME: move to Dimensional.Straight {-# INLINE envelope #-} envelope :: (Hom.C sig, Flat.C flat y0, Ring.C y0) => RP.T s flat y0 {- ^ the envelope -} -> RP.T s sig y0 {- ^ the signal to be enveloped -} -> RP.T s sig y0 envelope y = Hom.processSamples (FiltNR.envelope (Flat.toSamples y)) -- FIXME: move to Dimensional.Straight {-# INLINE envelopeVector #-} envelopeVector :: (Hom.C sig, Flat.C flat y0, Module.C y0 yv) => RP.T s flat y0 {- ^ the envelope -} -> RP.T s sig yv {- ^ the signal to be enveloped -} -> RP.T s sig yv envelopeVector y = Hom.processSamples (FiltNR.envelopeVector (Flat.toSamples y)) {-# INLINE envelopeVectorDimension #-} envelopeVectorDimension :: (Module.C y0 yv, Ring.C y, Dim.C u, Dim.C v) => SigA.R s v y y0 {- ^ the envelope -} -> SigA.R s u y yv {- ^ the signal to be enveloped -} -> SigA.R s (Dim.Mul v u) y yv envelopeVectorDimension y x = SigA.fromSamples (SigA.amplitude y &*& SigA.amplitude x) (FiltNR.envelopeVector (SigA.samples y) (SigA.samples x))