module Synthesizer.Plain.Filter.Recursive.SecondOrder where
import Synthesizer.Plain.Filter.Recursive (Passband(Lowpass,Highpass))
import qualified Synthesizer.Plain.Signal as Sig
import qualified Algebra.Module as Module
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import Algebra.Module((*>))
import Data.List (zipWith6)
import Control.Monad.State (State(..), )
import qualified Prelude as P
import PreludeBase
import NumericPrelude
data Parameter a =
Parameter {c0, c1, c2, d1, d2 :: !a}
deriving Show
adjustPassband :: (Ring.C a) =>
Passband -> Parameter a -> Parameter a
adjustPassband kind p =
case kind of
Lowpass -> p
Highpass -> Parameter (c0 p) ( c1 p) (c2 p) ( d1 p) (d2 p)
step :: (Ring.C a, Module.C a v) =>
Parameter a -> v -> State ((v,v),(v,v)) v
step c u0 = State $ \((u1,u2),(y1,y2)) ->
let y0 =
c0 c *> u0 +
c1 c *> u1 + d1 c *> y1 +
c2 c *> u2 + d2 c *> y2
in (y0, ((u0,u1),(y0,y1)))
runInit :: (Ring.C a, Module.C a v) =>
((v,v),(v,v)) -> Sig.T (Parameter a) -> Sig.T v -> Sig.T v
runInit ((u0init,u1init),(y0init,y1init)) control input =
let u0s = input
u1s = u0init:u0s
u2s = u1init:u1s
y1s = y0init:y0s
y2s = y1init:y1s
y0s = zipWith6
(\c u0 u1 u2 y1 y2 ->
c0 c *> u0 +
c1 c *> u1 + d1 c *> y1 +
c2 c *> u2 + d2 c *> y2)
control u0s u1s u2s y1s y2s
in y0s
run :: (Ring.C a, Module.C a v) =>
Sig.T (Parameter a) -> Sig.T v -> Sig.T v
run = runInit zero