module Synthesizer.Generic.Filter.Recursive.Comb (
karplusStrong,
run,
runMulti,
runProc,
) where
import qualified Synthesizer.Generic.Filter.NonRecursive as Filt
import qualified Synthesizer.Plain.Filter.Recursive.FirstOrder as Filt1
import qualified Synthesizer.Generic.Signal as SigG
import qualified Synthesizer.Generic.Cut as CutG
import qualified Algebra.Module as Module
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import NumericPrelude.Numeric
import NumericPrelude.Base
karplusStrong ::
(Ring.C t, Module.C t y, SigG.Write sig y) =>
Filt1.Parameter t -> sig y -> sig y
karplusStrong c wave =
SigG.delayLoop (SigG.modifyStatic Filt1.lowpassModifier c) wave
run :: (Module.C t y, SigG.Write sig y) =>
Int -> t -> sig y -> sig y
run time gain =
runProc time (Filt.amplifyVector gain)
runMulti :: (Module.C t y, SigG.Write sig y) =>
[Int] -> t -> sig y -> sig y
runMulti times gain x =
let y = foldl
(SigG.zipWith (+)) x
(map (flip Filt.delay (Filt.amplifyVector gain y)) times)
in y
runProc :: (Additive.C y, SigG.Write sig y) =>
Int -> (sig y -> sig y) -> sig y -> sig y
runProc = SigG.delayLoopOverlap
_run :: (Module.C t y, SigG.Transform sig y) => t -> Int -> sig y -> sig y
_run gain delay xs =
let (xs0,xs1) = CutG.splitAt delay $ Filt.amplifyVector (1gain) xs
ys = CutG.append xs0 $ SigG.zipWith (+) xs1 $ Filt.amplifyVector gain ys
in ys
_runInf :: (Module.C t y, SigG.Write sig y) => t -> Int -> sig y -> sig y
_runInf gain delay xs =
let (xs0,xs1) =
CutG.splitAt delay $
Filt.amplifyVector (1gain) xs `CutG.append`
SigG.repeat (SigG.LazySize delay) zero
ys = CutG.append xs0 $ SigG.zipWith (+) xs1 $ Filt.amplifyVector gain ys
in ys