module Synthesizer.Plain.Filter.Recursive.SecondOrderCascade 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 Control.Monad.Trans.State (State, )
import qualified Data.StorableVector as SV
import Foreign.Storable (Storable(..))
import qualified Prelude as P
import PreludeBase
import NumericPrelude
newtype Parameter a =
Parameter (SV.Vector (Filt2.Parameter a))
type Status a =
SV.Vector (Filt2.Status 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 -> State (Status v) v
step (Parameter p) =
Modifier.stackStatesStorableVaryL Filt2.step p
modifierInit ::
(Ring.C a, Module.C a v, Storable a, Storable v) =>
Modifier.Initialized (Status v) (Status 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 (Status v) (Parameter a) v v
modifier order =
Sig.modifierInitialize modifierInit
(SV.replicate order Filt2.zeroStatus)
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)