{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses #-}
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
{-# INLINE karplusStrong #-}
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
{-# INLINE run #-}
run :: (Module.C t y, SigG.Write sig y) =>
Int -> t -> sig y -> sig y
run time gain =
runProc time (Filt.amplifyVector gain)
{-# INLINE runMulti #-}
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
{-# INLINE runProc #-}
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 (1-gain) 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 (1-gain) xs `CutG.append`
SigG.repeat (SigG.LazySize delay) zero
ys = CutG.append xs0 $ SigG.zipWith (+) xs1 $ Filt.amplifyVector gain ys
in ys