{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {- | This is like "Synthesizer.LLVM.CausalParameterized.Controlled" but for vectorised signals. -} module Synthesizer.LLVM.CausalParameterized.ControlledPacked ( C(process), processCtrlRate, ) where import qualified Synthesizer.LLVM.Filter.Allpass as Allpass import qualified Synthesizer.LLVM.Filter.FirstOrder as Filt1 import qualified Synthesizer.LLVM.Filter.SecondOrder as Filt2 import qualified Synthesizer.LLVM.Filter.SecondOrderCascade as Cascade import qualified Synthesizer.LLVM.Filter.Moog as Moog import qualified Synthesizer.LLVM.Filter.Universal as UniFilter import qualified Synthesizer.LLVM.CausalParameterized.ProcessPacked as CausalPS import qualified Synthesizer.LLVM.CausalParameterized.Process as CausalP import qualified Synthesizer.LLVM.Parameterized.Signal as SigP import qualified LLVM.Extra.Representation as Rep import qualified LLVM.Extra.Vector as Vector import qualified Synthesizer.LLVM.Parameter as Param import qualified LLVM.Core as LLVM import LLVM.Core (Value, Vector, IsArithmetic, IsFloating, IsConst, IsSized, IsFirstClass, IsPrimitive, IsPowerOf2, ) import qualified Data.TypeLevel.Num as TypeNum import qualified Data.TypeLevel.Num.Sets as TypeSet import Foreign.Storable (Storable, ) import Control.Arrow ((<<<), first, ) import qualified Algebra.Field as Field import qualified Algebra.Module as Module import qualified Algebra.Ring as Ring import NumericPrelude.Numeric import NumericPrelude.Base {- | A filter parameter type uniquely selects a filter function. However it does not uniquely determine the input and output type, since the same filter can run on mono and stereo signals. -} class C parameter a b | parameter a -> b, parameter b -> a where process :: CausalP.T p (parameter, a) b processCtrlRate :: (C parameter av bv, Vector.Access n a av, Vector.Access n b bv, Rep.Memory parameter struct, IsSized struct ss, Field.C r, IsFloating r, Storable r, IsConst r, LLVM.MakeValueTuple r (Value r), LLVM.CmpRet r Bool, IsSized r rs) => Param.T p r -> (Param.T p r -> SigP.T p parameter) -> CausalP.T p av bv processCtrlRate reduct ctrlGen = withSize $ \n -> CausalP.applyFst process (SigP.interpolateConstant (fmap (/ fromIntegral (TypeNum.toInt n)) reduct) (ctrlGen reduct)) withSize :: (Vector.Access n a av, Vector.Access n b bv) => (n -> CausalP.T p av bv) -> CausalP.T p av bv withSize f = f undefined {- Instances for the particular filters shall be defined here in order to avoid orphan instances. -} instance (Ring.C a, IsArithmetic a, IsPrimitive a, IsFirstClass a, IsConst a, IsSized a as, IsPowerOf2 n) => C (Filt1.Parameter (Value a)) (Value (Vector n a)) (Filt1.Result (Value (Vector n a))) where process = Filt1.causalPackedP instance (Ring.C a, IsFirstClass a, IsArithmetic a, IsConst a, IsPowerOf2 n, IsPrimitive a, IsSized a as, TypeNum.Mul n as vas, TypeNum.Pos vas) => C (Filt2.Parameter (Value a)) (Value (Vector n a)) (Value (Vector n a)) where process = Filt2.causalPackedP instance (Ring.C a, IsPrimitive a, IsSized a as, IsConst a, IsArithmetic a, TypeSet.Nat n, TypeNum.Mul n LLVM.UnknownSize paramSize, TypeSet.Pos paramSize, IsPowerOf2 d, TypeNum.Mul d as vas, TypeSet.Pos vas) => C (Cascade.ParameterValue n a) (Value (Vector d a)) (Value (Vector d a)) where process = Cascade.causalPackedP instance (Ring.C a, IsFirstClass a, IsArithmetic a, IsConst a, IsPowerOf2 n, IsPrimitive a, IsSized a as) => C (Allpass.Parameter (Value a)) (Value (Vector n a)) (Value (Vector n a)) where process = Allpass.causalPackedP instance (Field.C a, IsFirstClass a, IsArithmetic a, IsConst a, IsPowerOf2 d, IsPrimitive a, IsSized a as, TypeNum.Nat n) => C (Allpass.CascadeParameter n (Value a)) (Value (Vector d a)) (Value (Vector d a)) where process = Allpass.cascadePackedP instance (Module.C a a, IsFirstClass a, IsArithmetic a, IsConst a, LLVM.MakeValueTuple a (Value a), Storable a, IsPowerOf2 d, IsPrimitive a, IsSized a as, TypeNum.Nat n) => C (Moog.Parameter n (Value a)) (Value (Vector d a)) (Value (Vector d a)) where process = CausalPS.pack Moog.causalP <<< first (CausalP.mapSimple Vector.replicate) instance (Field.C a, IsFirstClass a, IsArithmetic a, IsConst a, IsPowerOf2 d, IsPrimitive a, IsSized a as) => C (UniFilter.Parameter (Value a)) (Value (Vector d a)) (UniFilter.Result (Value (Vector d a))) where process = CausalPS.pack UniFilter.causalP <<< first (CausalP.mapSimple Vector.replicate)