{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleContexts #-} module Synthesizer.LLVM.Filter.Butterworth ( parameter, 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.Plain.Filter.Recursive.Butterworth as Butterworth import Synthesizer.Plain.Filter.Recursive (Passband, ) import qualified Synthesizer.LLVM.Simple.Value as Value 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 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 qualified Algebra.Field as Field -- import qualified Algebra.Module as Module -- import qualified Algebra.Ring as Ring import NumericPrelude.Numeric import NumericPrelude.Base parameter, parameterMalloc, _parameterAlloca :: (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 = parameterMalloc parameterMalloc n kind 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 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 $ (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 pv <- LLVM.load ps LLVM.free psine LLVM.free ps return (Cascade.ParameterValue pv) _parameterAlloca n kind 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 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 $ (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