module Synthesizer.Plain.Filter.Recursive.SecondOrderCascade (
Parameter (Parameter),
State,
step,
modifierInit,
modifier,
causal,
) where
import qualified Synthesizer.Plain.Filter.Recursive.SecondOrder as Filt2
import qualified Synthesizer.Plain.Signal as Sig
import qualified Synthesizer.Plain.Modifier as Modifier
import qualified Synthesizer.Interpolation.Class as Interpol
import qualified Synthesizer.Causal.Process as Causal
import qualified Algebra.Module as Module
import qualified Algebra.Ring as Ring
import qualified Control.Monad.Trans.State as MS
import qualified Data.StorableVector as SV
import Foreign.Storable (Storable(..))
import NumericPrelude.Numeric
import NumericPrelude.Base
newtype Parameter a =
Parameter (SV.Vector (Filt2.Parameter a))
type State a =
SV.Vector (Filt2.State a)
checkSizes :: String -> SV.Vector a -> SV.Vector b -> c -> c
checkSizes opName x y act =
if SV.length x == SV.length y
then act
else error $ opName ++ ": incompatible sizes of cascades of second order filters"
withSizeCheck ::
String ->
(SV.Vector a -> SV.Vector b -> c) ->
(SV.Vector a -> SV.Vector b -> c)
withSizeCheck opName f x y =
checkSizes opName x y (f x y)
instance (Interpol.C a v, Storable v) => Interpol.C a (Parameter v) where
scaleAndAccumulate (a, Parameter x) =
(Parameter $ SV.map (curry Interpol.scale a) x,
\ (Parameter y) ->
Parameter $ withSizeCheck "mac"
(SV.zipWith (curry Interpol.scaleAccumulate a)) x y)
step ::
(Ring.C a, Module.C a v, Storable a, Storable v) =>
Parameter a -> v -> MS.State (State v) v
step (Parameter p) =
Modifier.stackStatesStorableVaryL Filt2.step p
modifierInit ::
(Ring.C a, Module.C a v, Storable a, Storable v) =>
Modifier.Initialized (State v) (State v) (Parameter a) v v
modifierInit =
Modifier.Initialized id step
modifier ::
(Ring.C a, Module.C a v, Storable a, Storable v) =>
Int ->
Modifier.Simple (State v) (Parameter a) v v
modifier order =
Sig.modifierInitialize modifierInit
(SV.replicate order Filt2.zeroState)
causal :: (Ring.C a, Module.C a v, Storable a, Storable v) =>
Int ->
Causal.T (Parameter a, v) v
causal order =
Causal.fromSimpleModifier (modifier order)