module Synthesizer.LLVM.Filter.Butterworth (
parameter, Cascade.ParameterValue,
Cascade.causalP, Cascade.causalPackedP,
Cascade.fixSize,
) where
import qualified Synthesizer.LLVM.Filter.SecondOrderCascade as Cascade
import qualified Synthesizer.Plain.Filter.Recursive.Butterworth as Butterworth
import qualified Synthesizer.Plain.Filter.Recursive.SecondOrder as Filt2
import Synthesizer.Plain.Filter.Recursive (Passband, )
import qualified LLVM.Extra.Control as U
import qualified LLVM.Extra.Representation as Rep
import qualified Synthesizer.LLVM.Simple.Value as Value
import qualified LLVM.Extra.Arithmetic as A
import qualified LLVM.Core as LLVM
import LLVM.Core
(Value, valueOf, constOf,
IsConst, IsFloating, IsSized,
CodeGenFunction, )
import Data.Word (Word32, )
import qualified Data.TypeLevel.Num as TypeNum
import qualified Data.TypeLevel.Num.Sets as TypeSet
import qualified Algebra.Transcendental as Trans
import NumericPrelude.Numeric
import NumericPrelude.Base
parameter, parameterMalloc, _parameterAlloca ::
(Trans.C a, IsConst a, IsFloating a, IsSized a as,
TypeSet.Nat n,
TypeNum.Mul n as sineSize,
TypeSet.Pos sineSize,
IsSized (Cascade.Parameter n a) paramSize) =>
n -> Passband -> Value a -> Value a ->
CodeGenFunction r (Cascade.ParameterValue n a)
parameter = parameterMalloc
parameterMalloc n kind ratio freq = do
let order = 2 * TypeNum.toInt n
partialRatio <-
Value.decons (Butterworth.partialRatio order (Value.constantValue ratio))
let sines =
(flip const :: n -> LLVM.Value (LLVM.Array n a)
-> LLVM.Value (LLVM.Array n a)) n $
LLVM.value $
LLVM.constArray $
map constOf $ Butterworth.makeSines order
psine <- LLVM.malloc
LLVM.store sines psine
s <- LLVM.getElementPtr0 psine (valueOf (0::Word32), ())
ps <- LLVM.malloc
p <- LLVM.getElementPtr0 ps (valueOf (0::Word32), ())
let len = valueOf $ (fromIntegral $ TypeNum.toInt n :: Word32)
U.arrayLoop len p s $ \ptri si -> do
sinw <- LLVM.load si
flip Rep.store ptri =<<
Value.flatten
(Filt2.adjustPassband kind
(flip
(Butterworth.partialParameter
(Value.constantValue partialRatio))
(Value.constantValue sinw))
(Value.constantValue freq))
A.advanceArrayElementPtr si
pv <- LLVM.load ps
LLVM.free psine
LLVM.free ps
return (Cascade.ParameterValue pv)
_parameterAlloca n kind ratio freq = do
let order = 2 * TypeNum.toInt n
partialRatio <-
Value.decons (Butterworth.partialRatio order (Value.constantValue ratio))
let sines =
(flip const :: n -> LLVM.Value (LLVM.Array n a)
-> LLVM.Value (LLVM.Array n a)) n $
LLVM.value $
LLVM.constArray $
map constOf $ Butterworth.makeSines order
psine <- LLVM.alloca
LLVM.store sines psine
s <- LLVM.getElementPtr0 psine (valueOf (0::Word32), ())
ps <- LLVM.alloca
p <- LLVM.getElementPtr0 ps (valueOf (0::Word32), ())
let len = valueOf $ (fromIntegral $ TypeNum.toInt n :: Word32)
U.arrayLoop len p s $ \ptri si -> do
sinw <- LLVM.load si
flip Rep.store ptri =<<
Value.flatten
(Filt2.adjustPassband kind
(flip
(Butterworth.partialParameter
(Value.constantValue partialRatio))
(Value.constantValue sinw))
(Value.constantValue freq))
A.advanceArrayElementPtr si
fmap Cascade.ParameterValue $ LLVM.load ps