synthesizer-llvm-0.2: src/Synthesizer/LLVM/ALSA/BendModulation.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{- |
Various LLVM related instances of the BendModulation type.
I have setup a separate module since these instances are orphan
and need several language extensions.
-}
module Synthesizer.LLVM.ALSA.BendModulation where
import Synthesizer.PiecewiseConstant.ALSA.MIDI
(BendModulation(BendModulation), )
import qualified LLVM.Extra.Vector as Vector
import qualified LLVM.Extra.Class as Class
import qualified LLVM.Extra.Representation as Rep
import qualified LLVM.Extra.Control as C
import qualified LLVM.Util.Loop as Loop
import qualified LLVM.Core as LLVM
import Foreign.Storable (Storable(sizeOf, alignment, peek, poke), )
import Foreign.Storable.Traversable as Store
import qualified Control.Applicative as App
import qualified Data.Foldable as Fold
import qualified Data.Traversable as Trav
import Control.Applicative (Applicative, (<*>), pure, liftA2, )
import qualified Data.TypeLevel.Num as TypeNum
-- 'fmap' is lazy which is important for the Store functions
instance Functor BendModulation where
{-# INLINE fmap #-}
fmap f ~(BendModulation b m) = BendModulation (f b) (f m)
-- useful for defining Additive instance
instance Applicative BendModulation where
{-# INLINE pure #-}
pure a = BendModulation a a
{-# INLINE (<*>) #-}
~(BendModulation fb fm) <*> ~(BendModulation b m) =
BendModulation (fb b) (fm m)
instance Fold.Foldable BendModulation where
{-# INLINE foldMap #-}
foldMap = Trav.foldMapDefault
-- this allows for kinds of generic programming
instance Trav.Traversable BendModulation where
{-# INLINE sequenceA #-}
sequenceA ~(BendModulation b m) =
liftA2 BendModulation b m
instance (Storable a) => Storable (BendModulation a) where
{-# INLINE sizeOf #-}
sizeOf = Store.sizeOf
{-# INLINE alignment #-}
alignment = Store.alignment
{-# INLINE peek #-}
peek = Store.peekApplicative
{-# INLINE poke #-}
poke = Store.poke
instance (Class.Zero a) => Class.Zero (BendModulation a) where
zeroTuple = Class.zeroTuplePointed
instance (LLVM.ValueTuple a) => LLVM.ValueTuple (BendModulation a) where
buildTuple f = Class.buildTupleTraversable (LLVM.buildTuple f)
instance LLVM.IsTuple a => LLVM.IsTuple (BendModulation a) where
tupleDesc = Class.tupleDescFoldable
instance (LLVM.Undefined a) => LLVM.Undefined (BendModulation a) where
undefTuple = Class.undefTuplePointed
instance (C.Select a) => C.Select (BendModulation a) where
select = C.selectTraversable
instance LLVM.CmpRet a b =>
LLVM.CmpRet (BendModulation a) (BendModulation b) where
instance LLVM.MakeValueTuple h l =>
LLVM.MakeValueTuple (BendModulation h) (BendModulation l) where
valueTupleOf = Class.valueTupleOfFunctor
memory ::
(Rep.Memory l s, LLVM.IsSized s ss) =>
Rep.MemoryRecord r (LLVM.Struct (s, (s, ()))) (BendModulation l)
memory =
liftA2 BendModulation
(Rep.memoryElement (\(BendModulation b _) -> b) TypeNum.d0)
(Rep.memoryElement (\(BendModulation _ m) -> m) TypeNum.d1)
instance
(Rep.Memory l s, LLVM.IsSized s ss) =>
Rep.Memory (BendModulation l) (LLVM.Struct (s, (s, ()))) where
load = Rep.loadRecord memory
store = Rep.storeRecord memory
decompose = Rep.decomposeRecord memory
compose = Rep.composeRecord memory
instance (Loop.Phi a) => Loop.Phi (BendModulation a) where
phis = Class.phisTraversable
addPhis = Class.addPhisFoldable
instance (Vector.ShuffleMatch n v) =>
Vector.ShuffleMatch n (BendModulation v) where
shuffleMatch = Vector.shuffleMatchTraversable
instance (Vector.Access n a v) =>
Vector.Access n (BendModulation a) (BendModulation v) where
insert = Vector.insertTraversable
extract = Vector.extractTraversable