{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {- | Copyright : (c) Henning Thielemann 2006 License : GPL Maintainer : synthesizer@henning-thielemann.de Stability : provisional Portability : requires multi-parameter type classes -} module Synthesizer.Inference.Monad.SignalSeq.Filter( {- * Non-recursive -} {- ** Amplification -} amplify, negate, envelope, {- ** Filter operators from calculus -} differentiate, {- ** Smooth -} mean, {- ** Delay -} delay, phaseModulation, phaser, phaserStereo, {- * Recursive -} {- ** Without resonance -} firstOrderLowpass, firstOrderHighpass, butterworthLowpass, butterworthHighpass, chebyshevALowpass, chebyshevAHighpass, chebyshevBLowpass, chebyshevBHighpass, {- ** With resonance -} universal, moogLowpass, {- ** Allpass -} allpassCascade, {- ** Reverb -} comb, {- ** Filter operators from calculus -} integrate ) where import qualified Synthesizer.Inference.Monad.Signal as SigI import qualified Synthesizer.Inference.Monad.Signal.Filter as FiltI import qualified Synthesizer.Plain.Interpolation as Interpolation import qualified Synthesizer.Plain.Filter.Recursive.Universal as UniFilter import qualified Algebra.OccasionallyScalar as OccScalar import qualified Algebra.VectorSpace as VectorSpace 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.Real as Real import qualified Algebra.Additive as Additive import UniqueLogicNP.Monad(liftP, liftP2, liftP3) import NumericPrelude import PreludeBase as P {- | The amplification factor must be positive. -} amplify :: (Field.C q, Eq q) => q -> SigI.Process a q v -> SigI.Process a q v amplify volume = liftP (FiltI.amplify volume) envelope :: (Module.C y v, Field.C q, Eq q) => SigI.Process a q y {- ^ the envelope -} -> SigI.Process a q v {- ^ the signal to be enveloped -} -> SigI.Process a q v envelope = liftP2 FiltI.envelope integrate :: (Additive.C v, Field.C q, Eq q) => SigI.Process a q v -> SigI.Process a q v integrate = liftP FiltI.integrate differentiate :: (Additive.C v, Field.C q, Eq q) => SigI.Process a q v -> SigI.Process a q v differentiate = liftP FiltI.differentiate mean :: (Additive.C v, Field.C q, Eq q, RealField.C a, Module.C a v, OccScalar.C a q) => q {- ^ time length of the window -} -> SigI.Process a q v -> SigI.Process a q v mean time = liftP (FiltI.mean time) delay :: (Additive.C v, Field.C q, Eq q, RealField.C a, OccScalar.C a q) => q -> SigI.Process a q v -> SigI.Process a q v delay time = liftP (FiltI.delay time) phaseModulation :: (Additive.C v, Field.C q, Eq q, RealField.C a, OccScalar.C a q) => Interpolation.T a v -> q {- ^ minDelay, minimal delay, may be negative -} -> q {- ^ maxDelay, maximal delay, it must be @minDelay <= maxDelay@ and the modulation must always be in the range [minDelay,maxDelay]. -} -> SigI.Process a q a {- ^ delay control, positive numbers mean delay, negative numbers mean prefetch -} -> SigI.Process a q v -> SigI.Process a q v phaseModulation ip minDelay maxDelay = liftP2 (FiltI.phaseModulation ip minDelay maxDelay) {- | symmetric phaser -} phaser :: (Additive.C v, Field.C q, Eq q, RealField.C a, Module.C a v, OccScalar.C a q) => Interpolation.T a v -> q {- ^ maxDelay, must be positive -} -> SigI.Process a q a {- ^ delay control -} -> SigI.Process a q v -> SigI.Process a q v phaser ip maxDelay = liftP2 (FiltI.phaser ip maxDelay) phaserStereo :: (Additive.C v, Field.C q, Eq q, Real.C q, RealField.C a, Module.C a v, OccScalar.C a q) => Interpolation.T a v -> q {- ^ maxDelay, must be positive -} -> SigI.Process a q a {- ^ delay control -} -> SigI.Process a q v -> SigI.Process a q (v,v) phaserStereo ip maxDelay = liftP2 (FiltI.phaserStereo ip maxDelay) firstOrderLowpass, firstOrderHighpass :: (Trans.C a, Trans.C q, Eq q,Module.C a v, OccScalar.C a q) => SigI.Process a q a -> SigI.Process a q v -> SigI.Process a q v firstOrderLowpass = liftP2 FiltI.firstOrderLowpass firstOrderHighpass = liftP2 FiltI.firstOrderHighpass butterworthLowpass, butterworthHighpass, chebyshevALowpass, chebyshevAHighpass, chebyshevBLowpass, chebyshevBHighpass :: (Field.C q, Eq q, Trans.C a, VectorSpace.C a v, OccScalar.C a q) => Int -> SigI.Process a q a -> SigI.Process a q a -> SigI.Process a q v -> SigI.Process a q v butterworthLowpass order = liftP3 (FiltI.butterworthLowpass order) butterworthHighpass order = liftP3 (FiltI.butterworthHighpass order) chebyshevALowpass order = liftP3 (FiltI.chebyshevALowpass order) chebyshevAHighpass order = liftP3 (FiltI.chebyshevAHighpass order) chebyshevBLowpass order = liftP3 (FiltI.chebyshevBLowpass order) chebyshevBHighpass order = liftP3 (FiltI.chebyshevBHighpass order) universal :: (Trans.C a, Module.C a v, Field.C q, Eq q, OccScalar.C a q) => SigI.Process a q a -> SigI.Process a q a -> SigI.Process a q v -> SigI.Process a q (UniFilter.Result v) universal = liftP3 FiltI.universal moogLowpass :: (Trans.C a, Module.C a v, Field.C q, Eq q, OccScalar.C a q) => Int -> SigI.Process a q a -> SigI.Process a q a -> SigI.Process a q v -> SigI.Process a q v moogLowpass order = liftP3 (FiltI.moogLowpass order) allpassCascade :: (Trans.C a, Module.C a v, Field.C q, Eq q, OccScalar.C a q) => Int -> a -> SigI.Process a q a -> SigI.Process a q v -> SigI.Process a q v allpassCascade order phase = liftP2 (FiltI.allpassCascade order phase) {- | Infinitely many equi-delayed exponentially decaying echos. -} comb :: (RealField.C a, Field.C q, Eq q, OccScalar.C a q, Module.C a v) => q -> a -> SigI.Process a q v -> SigI.Process a q v comb time gain = liftP (FiltI.comb time gain)