module Synthesizer.LLVM.Filter.Butterworth (
parameter, parameterCausal, Cascade.ParameterValue,
Cascade.causal, Cascade.causalPacked,
Cascade.causalP, Cascade.causalPackedP,
Cascade.fixSize,
) where
import qualified Synthesizer.LLVM.Filter.SecondOrderCascade as Cascade
import qualified Synthesizer.LLVM.Filter.SecondOrder as Filt2
import qualified Synthesizer.LLVM.Causal.ProcessPrivate as Causal
import qualified Synthesizer.LLVM.Simple.SignalPrivate as Sig
import qualified Synthesizer.LLVM.Simple.Value as Value
import qualified Synthesizer.Plain.Filter.Recursive.Butterworth as Butterworth
import Synthesizer.Plain.Filter.Recursive (Passband, )
import Synthesizer.Causal.Class (($<), )
import qualified LLVM.Extra.ScalarOrVector as SoV
import qualified LLVM.Extra.Control as U
import qualified LLVM.Extra.Arithmetic as A
import qualified LLVM.Core as LLVM
import LLVM.Core
(Value, valueOf, constOf,
IsFloating, IsSized, SizeOf,
CodeGenFunction, )
import Data.Word (Word32, )
import Foreign.Ptr (Ptr, )
import qualified Type.Data.Num.Decimal as TypeNum
import Type.Data.Num.Decimal.Number ((:*:), )
import Type.Base.Proxy (Proxy, )
import qualified Algebra.Transcendental as Trans
import NumericPrelude.Numeric
import NumericPrelude.Base
parameterCausal ::
(Causal.C process,
Trans.C a, SoV.TranscendentalConstant a, IsFloating a, IsSized a,
TypeNum.Natural n,
TypeNum.Positive (n :*: SizeOf a),
IsSized (Cascade.ParameterStruct n a)) =>
Proxy n -> Passband ->
process (Value a, Value a) (Cascade.ParameterValue n a)
parameterCausal n kind =
Causal.map
(\((psine, ps), (ratio, freq)) ->
parameterCore n kind psine ps ratio freq)
$<
Sig.zipWith (curry return) Sig.alloca Sig.alloca
parameter ::
(Trans.C a, SoV.TranscendentalConstant a, IsFloating a, IsSized a,
TypeNum.Natural n,
TypeNum.Positive (n :*: SizeOf a),
IsSized (Cascade.ParameterStruct n a)) =>
Proxy n -> Passband -> Value a -> Value a ->
CodeGenFunction r (Cascade.ParameterValue n a)
parameter n kind ratio freq = do
psine <- LLVM.malloc
ps <- LLVM.malloc
pv <- parameterCore n kind psine ps ratio freq
LLVM.free ps
LLVM.free psine
return pv
parameterCore ::
(Trans.C a, SoV.TranscendentalConstant a, IsFloating a, IsSized a,
TypeNum.Natural n,
TypeNum.Positive (n :*: SizeOf a),
IsSized (Cascade.ParameterStruct n a)) =>
Proxy n -> Passband ->
Value (Ptr (LLVM.Array n a)) ->
Value (Ptr (Cascade.ParameterStruct n a)) ->
Value a -> Value a ->
CodeGenFunction r (Cascade.ParameterValue n a)
parameterCore n kind psine ps ratio freq = do
let order = 2 * TypeNum.integralFromProxy n
partialRatio <- Value.unlift1 (Butterworth.partialRatio order) ratio
let sines =
Cascade.constArray n $
map constOf $ Butterworth.makeSines order
LLVM.store sines psine
s <- LLVM.getElementPtr0 psine (valueOf (0::Word32), ())
p <- LLVM.getElementPtr0 ps (valueOf (0::Word32), ())
let len = valueOf $ (TypeNum.integralFromProxy n :: Word32)
_ <- U.arrayLoop len p s $ \ptri si -> do
sinw <- LLVM.load si
flip LLVM.store ptri =<<
Filt2.composeParameter =<<
Value.unlift3 (Butterworth.partialParameter kind) partialRatio sinw freq
A.advanceArrayElementPtr si
fmap Cascade.ParameterValue $ LLVM.load ps