module Synthesizer.LLVM.Sample where
import qualified LLVM.Extra.Vector as Vector
import Foreign.Storable.Tuple ()
import qualified Synthesizer.LLVM.Frame.Stereo as Stereo
import qualified LLVM.Extra.Arithmetic as A
import qualified LLVM.Core as LLVM
import LLVM.Core
(Value, valueOf, value, undef,
Vector, insertelement, extractelement,
IsPrimitive, IsPowerOf2, IsArithmetic,
CodeGenFunction, )
import Data.TypeLevel.Num (D2, D4, )
import Data.Word (Word32, )
import Control.Monad (liftM2, )
import NumericPrelude.Numeric hiding (zero, )
import NumericPrelude.Base
stereoFromMono ::
Value a ->
CodeGenFunction r (Stereo.T (Value a))
stereoFromMono x =
return $ Stereo.cons x x
mixMonoFromStereo ::
(IsArithmetic a) =>
Stereo.T (Value a) ->
CodeGenFunction r (Value a)
mixMonoFromStereo s =
mixMono (Stereo.left s) (Stereo.right s)
zipStereo ::
Value a -> Value a ->
CodeGenFunction r (Stereo.T (Value a))
zipStereo l r =
return (Stereo.cons l r)
stereoFromVector ::
(IsPrimitive a) =>
Value (Vector D2 a) ->
CodeGenFunction r (Stereo.T (Value a))
stereoFromVector x =
liftM2 Stereo.cons
(extractelement x (valueOf 0))
(extractelement x (valueOf 1))
vectorFromStereo ::
(IsPrimitive a) =>
Stereo.T (Value a) ->
CodeGenFunction r (Value (Vector D2 a))
vectorFromStereo s = do
x <- insertelement (value undef) (Stereo.left s) (valueOf 0)
insertelement x (Stereo.right s) (valueOf 1)
quadroFromVector ::
(IsPrimitive a) =>
Value (Vector D4 a) ->
CodeGenFunction r (Stereo.T (Stereo.T (Value a)))
quadroFromVector x =
liftM2 Stereo.cons
(liftM2 Stereo.cons
(extractelement x (valueOf 0))
(extractelement x (valueOf 1)))
(liftM2 Stereo.cons
(extractelement x (valueOf 2))
(extractelement x (valueOf 3)))
vectorFromQuadro ::
(IsPrimitive a) =>
Stereo.T (Stereo.T (Value a)) ->
CodeGenFunction r (Value (Vector D4 a))
vectorFromQuadro s = do
let x0 = value undef
sl = Stereo.left s
sr = Stereo.right s
x1 <- insertelement x0 (Stereo.left sl) (valueOf 0)
x2 <- insertelement x1 (Stereo.right sl) (valueOf 1)
x3 <- insertelement x2 (Stereo.left sr) (valueOf 2)
insertelement x3 (Stereo.right sr) (valueOf 3)
mixMono ::
(IsArithmetic a) =>
Value a -> Value a ->
CodeGenFunction r (Value a)
mixMono = A.add
mixStereo ::
(IsArithmetic a) =>
Stereo.T (Value a) -> Stereo.T (Value a) ->
CodeGenFunction r (Stereo.T (Value a))
mixStereo x y =
liftM2 Stereo.cons
(A.add (Stereo.left x) (Stereo.left y))
(A.add (Stereo.right x) (Stereo.right y))
class Additive a where
zero :: a
add :: a -> a -> CodeGenFunction r a
instance (IsArithmetic a) => Additive (Value a) where
zero = LLVM.value LLVM.zero
add = A.add
instance (Additive a) => Additive (Stereo.T a) where
zero = Stereo.cons zero zero
add x y =
liftM2 Stereo.cons
(add (Stereo.left x) (Stereo.left y))
(add (Stereo.right x) (Stereo.right y))
mixStereoV ::
(IsArithmetic a, IsPrimitive a) =>
Stereo.T (Value a) -> Stereo.T (Value a) ->
CodeGenFunction r (Stereo.T (Value a))
mixStereoV x y =
do xv <- vectorFromStereo x
yv <- vectorFromStereo y
stereoFromVector =<< A.add xv yv
mixVector ::
(Vector.Arithmetic a, IsPowerOf2 n) =>
Value (Vector n a) ->
CodeGenFunction r (Value a)
mixVector = Vector.sum
mixVectorToStereo ::
(Vector.Arithmetic a, IsPowerOf2 n) =>
Value (Vector n a) ->
CodeGenFunction r (Stereo.T (Value a))
mixVectorToStereo =
fmap (uncurry Stereo.cons) .
Vector.sumInterleavedToPair
mixInterleavedVectorToStereo ::
(Vector.Arithmetic a, IsPowerOf2 n) =>
Value (Vector n a) ->
CodeGenFunction r (Stereo.T (Value a))
mixInterleavedVectorToStereo =
fmap (uncurry Stereo.cons) .
Vector.sumInterleavedToPair
amplifyMono ::
(IsArithmetic a) =>
Value a -> Value a ->
CodeGenFunction r (Value a)
amplifyMono = A.mul
amplifyStereo ::
(IsArithmetic a) =>
Value a -> Stereo.T (Value a) ->
CodeGenFunction r (Stereo.T (Value a))
amplifyStereo x y =
liftM2 Stereo.cons
(A.mul x (Stereo.left y))
(A.mul x (Stereo.right y))
subsampleVector ::
(Vector.Access n a v) =>
v -> CodeGenFunction r a
subsampleVector =
Vector.extract (LLVM.value LLVM.zero :: Value Word32)