{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Synthesizer.Filter.Composition where
import qualified Synthesizer.Filter.Basic as FilterBasic
import Synthesizer.Filter.Basic (Filter, apply, )
import qualified Algebra.Module as Module
import qualified Algebra.Transcendental as Trans
import qualified Algebra.RealRing as RealRing
import qualified Algebra.Field as Field
import qualified Algebra.Additive as Additive
import qualified Number.Complex as Complex
import NumericPrelude.Base
import NumericPrelude.Numeric
data T filter t a v =
Prim (filter t a v)
| Serial [T filter t a v]
| Parallel [T filter t a v]
| Feedback (T filter t a v) (T filter t a v)
data Sockets s = Sockets {output :: s, socket :: SocketSpec s}
data SocketSpec s =
Output
| Multiplier [Sockets s]
| Adder [Sockets s]
| Loop (Sockets s) (Sockets s)
instance (Filter list filter) =>
Filter (list) (T filter) where
apply f x = output (applyMulti f x)
transferFunction f w = output (transferFunctionMulti f w)
applyMulti :: (RealRing.C t, Trans.C t,
Module.C a v, Module.C a (list v), Filter list filter) =>
T filter t a v -> list v -> Sockets (list v)
applyMulti (Prim f) x =
Sockets (apply f x) Output
applyMulti (Serial fs) x =
let sq = scanl (\(Sockets y _) -> flip applyMulti y) (Sockets x Output) fs
in Sockets (output (last sq)) (Multiplier (tail sq))
applyMulti (Parallel fs) x =
let socks = map (flip applyMulti x) fs
y = foldr (Additive.+) zero (map output socks)
in Sockets y (Adder socks)
applyMulti (Feedback feed back) x =
let sockY@(Sockets y _) = applyMulti feed ((Additive.+) x z)
sockZ@(Sockets z _) = applyMulti back y
in Sockets y (Loop sockY sockZ)
transferFunctionMulti ::
(Trans.C t, Module.C a t, Filter list filter) =>
T filter t a v -> t -> Sockets (Complex.T t)
transferFunctionMulti f w = tfAbsolutize 1 (tfRelative w f)
tfRelative ::
(Trans.C t, Module.C a t, Filter list filter) =>
t -> T filter t a v -> Sockets (Complex.T t)
tfRelative w (Prim f) =
Sockets (FilterBasic.transferFunction f w) Output
tfRelative w (Serial fs) =
let sq = map (tfRelative w) fs
in Sockets (product (map output sq)) (Multiplier sq)
tfRelative w (Parallel fs) =
let sq = map (tfRelative w) fs
in Sockets (sum (map output sq)) (Adder sq)
tfRelative w (Feedback feed back) =
let sockY = tfRelative w feed
sockZ = tfRelative w back
q = output sockY / (1 - output sockZ)
in Sockets q (Loop sockY sockZ)
tfAbsolutize :: (Field.C a) => a -> Sockets a -> Sockets a
tfAbsolutize x (Sockets y spec) = Sockets (x*y)
(case spec of
(Multiplier socks) ->
let sq = scanl (\(Sockets z _) -> tfAbsolutize z)
(Sockets x Output) socks
in Multiplier (tail sq)
(Adder socks) ->
let sq = map (tfAbsolutize x) socks
in Adder sq
(Loop feed back) ->
let sockY = tfAbsolutize (x / (1 - output back)) feed
sockZ = tfAbsolutize (output sockY) back
in Loop sockY sockZ
Output -> spec)