module Synthesizer.LLVM.Filter.Chebyshev (
parameterA, parameterB, Cascade.ParameterValue,
Cascade.causalP, Cascade.causalPackedP,
Cascade.fixSize,
) where
import qualified Synthesizer.LLVM.Filter.SecondOrderCascade as Cascade
import qualified Synthesizer.Plain.Filter.Recursive.Chebyshev as Chebyshev
import qualified Synthesizer.Plain.Filter.Recursive.SecondOrder as Filt2
import Synthesizer.Plain.Filter.Recursive (Passband, )
import qualified Synthesizer.LLVM.Simple.Value as Value
import qualified LLVM.Extra.Representation as Rep
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, ConstValue,
Struct, IsSized, IsConst, IsFloating,
CodeGenFunction, )
import Data.Word (Word32, )
import qualified Data.TypeLevel.Num as TypeNum
import qualified Data.TypeLevel.Num.Sets as TypeSet
import qualified Number.Complex as Complex
import qualified Algebra.Transcendental as Trans
import qualified Algebra.Ring as Ring
import NumericPrelude.Numeric
import NumericPrelude.Base
constComplexOf :: IsConst a =>
Complex.T a -> ConstValue (Struct (a, (a, ())))
constComplexOf x =
LLVM.constStruct
(LLVM.constOf $ Complex.real x,
(LLVM.constOf $ Complex.imag x,
()))
valueComplex ::
Value (Struct (a, (a, ()))) -> Complex.T (Value.T a)
valueComplex x =
Value.Cons (LLVM.extractvalue x TypeNum.d0)
Complex.+:
Value.Cons (LLVM.extractvalue x TypeNum.d1)
parameterA, parameterB ::
(Trans.C a, IsConst a, IsFloating a, IsSized a as,
TypeSet.Pos n,
TypeNum.Mul n as sineSize,
TypeSet.Pos sineSize,
IsSized (Cascade.Parameter n a) paramSize,
TypeNum.Mul n LLVM.UnknownSize paramSize, TypeSet.Pos paramSize) =>
n -> Passband -> Value a -> Value a ->
CodeGenFunction r (Cascade.ParameterValue n a)
parameterA n kind ratio freq = do
pv <- parameter Chebyshev.partialParameterA n kind ratio freq
filt0 <-
Rep.decompose =<<
LLVM.extractvalue pv (0::Word32)
fmap Cascade.ParameterValue $
flip (LLVM.insertvalue pv) (0::Word32) =<<
Rep.compose =<<
Value.flatten
(Filt2.amplify (Value.constantValue ratio) (Value.unfold filt0))
parameterB n kind ratio freq =
fmap Cascade.ParameterValue $
parameter Chebyshev.partialParameterB n kind ratio freq
parameter ::
(Trans.C a, IsConst a, IsFloating a, IsSized a as,
TypeSet.Pos n,
TypeNum.Mul n as sineSize,
TypeSet.Pos sineSize,
IsSized (Cascade.Parameter n a) paramSize,
TypeNum.Mul n LLVM.UnknownSize paramSize, TypeSet.Pos paramSize) =>
(Int -> Value.T a -> Value.T a ->
Complex.T (Value.T a) -> Filt2.Parameter (Value.T a)) ->
n -> Passband -> Value a -> Value a ->
CodeGenFunction r (Value (Cascade.Parameter n a))
parameter partialParameter n kind ratio freq = do
let order = 2 * TypeNum.toInt n
let sines =
(flip const :: n -> LLVM.Value (LLVM.Array n a)
-> LLVM.Value (LLVM.Array n a)) n $
LLVM.value $
LLVM.constArray $
map constComplexOf $
Chebyshev.makeCirclePoints 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
c <- LLVM.load si
flip Rep.store ptri =<<
Value.flatten
(Filt2.adjustPassband kind
(flip
(partialParameter order
(Value.constantValue ratio))
(valueComplex c))
(Value.constantValue freq))
A.advanceArrayElementPtr si
pv <- LLVM.load ps
LLVM.free psine
LLVM.free ps
return pv