{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# OPTIONS_GHC -fno-warn-orphans #-} {- | Various LLVM related instances of the BM.T type. I have setup a separate module since these instances are orphan and need several language extensions. -} module Synthesizer.LLVM.MIDI.BendModulation ( BM.T(..), BM.deflt, BM.shift, multiValue, unMultiValue, ) where import qualified Synthesizer.MIDI.Value.BendModulation as BM import qualified Synthesizer.LLVM.Causal.Functional as F import qualified LLVM.DSL.Expression as Expr import qualified LLVM.Extra.Multi.Value.Storable as StorableMV import qualified LLVM.Extra.Multi.Value.Marshal as MarshalMV import qualified LLVM.Extra.Multi.Value as MultiValue import qualified LLVM.Extra.Vector as Vector import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Extra.Storable as Storable import qualified LLVM.Extra.Marshal as Marshal import qualified LLVM.Extra.Memory as Memory import qualified LLVM.Extra.Control as C import qualified LLVM.Core as LLVM import qualified Type.Data.Num.Decimal as TypeNum import qualified Data.Traversable as Trav import qualified Data.Foldable as Fold import Control.Applicative (liftA2) instance (Tuple.Zero a) => Tuple.Zero (BM.T a) where zero = Tuple.zeroPointed instance (Tuple.Undefined a) => Tuple.Undefined (BM.T a) where undef = Tuple.undefPointed instance (C.Select a) => C.Select (BM.T a) where select = C.selectTraversable instance Tuple.Value h => Tuple.Value (BM.T h) where type ValueOf (BM.T h) = BM.T (Tuple.ValueOf h) valueOf = Tuple.valueOfFunctor instance (Expr.Aggregate e mv) => Expr.Aggregate (BM.T e) (BM.T mv) where type MultiValuesOf (BM.T e) = BM.T (Expr.MultiValuesOf e) type ExpressionsOf (BM.T mv) = BM.T (Expr.ExpressionsOf mv) bundle = Trav.traverse Expr.bundle dissect = fmap Expr.dissect instance (MultiValue.C a) => MultiValue.C (BM.T a) where type Repr (BM.T a) = BM.T (MultiValue.Repr a) cons = multiValue . fmap MultiValue.cons undef = multiValue $ pure MultiValue.undef zero = multiValue $ pure MultiValue.zero phi bb = fmap multiValue . Trav.traverse (MultiValue.phi bb) . unMultiValue addPhi bb a b = Fold.sequence_ $ liftA2 (MultiValue.addPhi bb) (unMultiValue a) (unMultiValue b) instance (MarshalMV.C l) => MarshalMV.C (BM.T l) where pack (BM.Cons bend depth) = MarshalMV.pack (bend, depth) unpack = uncurry BM.Cons . MarshalMV.unpack instance (StorableMV.C l) => StorableMV.C (BM.T l) where load = StorableMV.loadApplicative store = StorableMV.storeFoldable multiValue :: BM.T (MultiValue.T a) -> MultiValue.T (BM.T a) multiValue = MultiValue.Cons . fmap (\(MultiValue.Cons a) -> a) unMultiValue :: MultiValue.T (BM.T a) -> BM.T (MultiValue.T a) unMultiValue (MultiValue.Cons x) = fmap MultiValue.Cons x type Struct a = LLVM.Struct (a, (a, ())) memory :: (Memory.C l) => Memory.Record r (Struct (Memory.Struct l)) (BM.T l) memory = liftA2 BM.Cons (Memory.element BM.bend TypeNum.d0) (Memory.element BM.depth TypeNum.d1) instance (Memory.C l) => Memory.C (BM.T l) where type Struct (BM.T l) = Struct (Memory.Struct l) load = Memory.loadRecord memory store = Memory.storeRecord memory decompose = Memory.decomposeRecord memory compose = Memory.composeRecord memory instance (Marshal.C l) => Marshal.C (BM.T l) where pack (BM.Cons bend depth) = Marshal.pack (bend, depth) unpack = uncurry BM.Cons . Marshal.unpack instance (Storable.C l) => Storable.C (BM.T l) where load = Storable.loadApplicative store = Storable.storeFoldable instance (Tuple.Phi a) => Tuple.Phi (BM.T a) where phi = Tuple.phiTraversable addPhi = Tuple.addPhiFoldable instance (Vector.Simple v) => Vector.Simple (BM.T v) where type Element (BM.T v) = BM.T (Vector.Element v) type Size (BM.T v) = Vector.Size v shuffleMatch = Vector.shuffleMatchTraversable extract = Vector.extractTraversable instance (Vector.C v) => Vector.C (BM.T v) where insert = Vector.insertTraversable type instance F.Arguments f (BM.T a) = f (BM.T a) instance F.MakeArguments (BM.T a) where makeArgs = id