module Synthesizer.Plain.Filter.Recursive.FirstOrderComplex (
Parameter,
parameter,
parameterFromPeakWidth,
parameterFromPeakToDCRatio,
step,
modifierInit,
modifier,
causal,
runInit,
run,
) where
import Synthesizer.Plain.Filter.Recursive (Pole(..))
import qualified Synthesizer.Plain.Signal as Sig
import qualified Synthesizer.Plain.Modifier as Modifier
import qualified Synthesizer.Causal.Process as Causal
import qualified Synthesizer.Interpolation.Class as Interpol
import qualified Number.Complex as Complex
import Number.Complex ((+:))
import qualified Algebra.Module as Module
import qualified Algebra.Transcendental as Trans
import qualified Algebra.Algebraic as Algebraic
import qualified Algebra.Field as Field
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import Algebra.Module((*>))
import Control.Monad.Trans.State (State, state, )
import qualified Prelude as P
import PreludeBase
import NumericPrelude
data Parameter a =
Parameter {c, amp :: !(Complex.T a)}
instance Interpol.C a v => Interpol.C a (Parameter v) where
scaleAndAccumulate = Interpol.makeMac2 Parameter c amp
parameter :: Trans.C a => Pole a -> Parameter a
parameter (Pole resonance frequency) =
let cisw = Complex.cis (2*pi*frequency)
k = 1 recip resonance
kcisw = Complex.scale k cisw
in Parameter kcisw one
parameterFromPeakWidth :: Trans.C a => a -> Pole a -> Parameter a
parameterFromPeakWidth width (Pole resonance frequency) =
let cisw = Complex.cis (2*pi*frequency)
k = solveRatio resonance (cos (2*pi*width))
kcisw = Complex.scale k cisw
amp_ = Complex.fromReal ((1k)*resonance)
in Parameter kcisw amp_
parameterFromPeakToDCRatio :: Trans.C a => Pole a -> Parameter a
parameterFromPeakToDCRatio (Pole resonance frequency) =
let cisw = Complex.cis (2*pi*frequency)
k = solveRatio resonance (Complex.real cisw)
kcisw = Complex.scale k cisw
amp_ = one kcisw
in Parameter kcisw amp_
solveRatio :: (Algebraic.C a) =>
a -> a -> a
solveRatio resonance cosine =
let r2 = resonance^2
p = (r2 cosine) / (r2 1)
in recip $ p + sqrt (p^2 1)
type Result = Complex.T
step :: (Module.C a v) =>
Parameter a -> v -> State (Complex.T v) (Result v)
step p u =
state $ \s ->
let y = scale (amp p) u + mul (c p) s
in (y, y)
scale :: (Module.C a v) =>
Complex.T a -> v -> Complex.T v
scale s x =
Complex.real s *> x +: Complex.imag s *> x
mul :: (Module.C a v) =>
Complex.T a -> Complex.T v -> Complex.T v
mul x y =
(Complex.real x *> Complex.real y Complex.imag x *> Complex.imag y)
+:
(Complex.real x *> Complex.imag y + Complex.imag x *> Complex.real y)
modifierInit :: (Ring.C a, Module.C a v) =>
Modifier.Initialized (Complex.T v) (Complex.T v) (Parameter a) v (Result v)
modifierInit =
Modifier.Initialized id step
modifier :: (Ring.C a, Module.C a v) =>
Modifier.Simple (Complex.T v) (Parameter a) v (Result v)
modifier = Sig.modifierInitialize modifierInit zero
causal ::
(Ring.C a, Module.C a v) =>
Causal.T (Parameter a, v) (Result v)
causal =
Causal.fromSimpleModifier modifier
runInit :: (Ring.C a, Module.C a v) =>
Complex.T v -> Sig.T (Parameter a) -> Sig.T v -> Sig.T (Result v)
runInit = Sig.modifyModulatedInit modifierInit
run :: (Ring.C a, Module.C a v) =>
Sig.T (Parameter a) -> Sig.T v -> Sig.T (Result v)
run = runInit zero