module Synthesizer.LLVM.Frame.StereoInterleaved (
   T,
   Value,
   interleave,
   deinterleave,
   amplify,
   envelope,
   ) where

import qualified Synthesizer.LLVM.Frame.StereoInterleavedCode as StereoInt
import Synthesizer.LLVM.Frame.StereoInterleavedCode (T, Value)

import qualified Synthesizer.LLVM.Frame.Stereo as Stereo
import qualified Synthesizer.LLVM.Frame.SerialVector.Code as Serial

import qualified LLVM.DSL.Expression as Expr
import LLVM.DSL.Expression (Exp)

import qualified LLVM.Extra.Multi.Vector as MultiVector

import qualified Type.Data.Num.Decimal as TypeNum


interleave ::
   (TypeNum.Positive n, MultiVector.C a) =>
   Stereo.T (Exp (Serial.T n a)) -> Exp (T n a)
interleave :: forall n a. (Positive n, C a) => T (Exp (T n a)) -> Exp (T n a)
interleave = (forall r. T (Value n a) -> CodeGenFunction r (T (T n a)))
-> T (Exp (T n a)) -> Exp (T n a)
forall ae am b.
Aggregate ae am =>
(forall r. am -> CodeGenFunction r (T b)) -> ae -> Exp b
Expr.liftM T (Value n a) -> CodeGenFunction r (T (T n a))
forall r. T (Value n a) -> CodeGenFunction r (T (T n a))
forall n a r.
(Positive n, C a) =>
T (Value n a) -> CodeGenFunction r (Value n a)
StereoInt.interleave

deinterleave ::
   (TypeNum.Positive n, MultiVector.C a) =>
   Exp (T n a) -> Stereo.T (Exp (Serial.T n a))
deinterleave :: forall n a. (Positive n, C a) => Exp (T n a) -> T (Exp (T n a))
deinterleave Exp (T n a)
x =
   Exp (T n a) -> Exp (T n a) -> T (Exp (T n a))
forall a. a -> a -> T a
Stereo.cons
      ((forall r. Value n a -> CodeGenFunction r (T (T n a)))
-> Exp (T n a) -> Exp (T n a)
forall ae am b.
Aggregate ae am =>
(forall r. am -> CodeGenFunction r (T b)) -> ae -> Exp b
Expr.liftM ((T (T (T n a)) -> T (T n a))
-> CodeGenFunction r (T (T (T n a)))
-> CodeGenFunction r (T (T n a))
forall a b. (a -> b) -> CodeGenFunction r a -> CodeGenFunction r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap T (T (T n a)) -> T (T n a)
forall a. T a -> a
Stereo.left  (CodeGenFunction r (T (T (T n a)))
 -> CodeGenFunction r (T (T n a)))
-> (Value n a -> CodeGenFunction r (T (T (T n a))))
-> Value n a
-> CodeGenFunction r (T (T n a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value n a -> CodeGenFunction r (T (T (T n a)))
forall n a r.
(Positive n, C a) =>
Value n a -> CodeGenFunction r (T (Value n a))
StereoInt.deinterleave) Exp (T n a)
x)
      ((forall r. Value n a -> CodeGenFunction r (T (T n a)))
-> Exp (T n a) -> Exp (T n a)
forall ae am b.
Aggregate ae am =>
(forall r. am -> CodeGenFunction r (T b)) -> ae -> Exp b
Expr.liftM ((T (T (T n a)) -> T (T n a))
-> CodeGenFunction r (T (T (T n a)))
-> CodeGenFunction r (T (T n a))
forall a b. (a -> b) -> CodeGenFunction r a -> CodeGenFunction r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap T (T (T n a)) -> T (T n a)
forall a. T a -> a
Stereo.right (CodeGenFunction r (T (T (T n a)))
 -> CodeGenFunction r (T (T n a)))
-> (Value n a -> CodeGenFunction r (T (T (T n a))))
-> Value n a
-> CodeGenFunction r (T (T n a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value n a -> CodeGenFunction r (T (T (T n a)))
forall n a r.
(Positive n, C a) =>
Value n a -> CodeGenFunction r (T (Value n a))
StereoInt.deinterleave) Exp (T n a)
x)

amplify ::
   (TypeNum.Positive n, MultiVector.PseudoRing a) =>
   Exp a -> Exp (T n a) -> Exp (T n a)
amplify :: forall n a.
(Positive n, PseudoRing a) =>
Exp a -> Exp (T n a) -> Exp (T n a)
amplify = (forall r. T a -> Value n a -> CodeGenFunction r (Value n a))
-> Exp a -> Exp (T n a) -> Exp (T n a)
forall ae am be bm c.
(Aggregate ae am, Aggregate be bm) =>
(forall r. am -> bm -> CodeGenFunction r (T c))
-> ae -> be -> Exp c
Expr.liftM2 T a -> Value n a -> CodeGenFunction r (Value n a)
forall r. T a -> Value n a -> CodeGenFunction r (Value n a)
forall n a r.
(Positive n, PseudoRing a) =>
T a -> Value n a -> CodeGenFunction r (Value n a)
StereoInt.scale

envelope ::
   (TypeNum.Positive n, MultiVector.PseudoRing a) =>
   Exp (Serial.T n a) -> Exp (T n a) -> Exp (T n a)
envelope :: forall n a.
(Positive n, PseudoRing a) =>
Exp (T n a) -> Exp (T n a) -> Exp (T n a)
envelope = (forall r. Value n a -> Value n a -> CodeGenFunction r (Value n a))
-> Exp (T n a) -> Exp (T n a) -> Exp (T n a)
forall ae am be bm c.
(Aggregate ae am, Aggregate be bm) =>
(forall r. am -> bm -> CodeGenFunction r (T c))
-> ae -> be -> Exp c
Expr.liftM2 Value n a -> Value n a -> CodeGenFunction r (Value n a)
forall r. Value n a -> Value n a -> CodeGenFunction r (Value n a)
forall n a r.
(Positive n, PseudoRing a) =>
Value n a -> Value n a -> CodeGenFunction r (Value n a)
StereoInt.envelope