-- | Ugen math
module Sound.Sc3.Ugen.Math where

import qualified Sound.Sc3.Common.Math as Math
import qualified Sound.Sc3.Common.Math.Operator as Operator
import qualified Sound.Sc3.Common.Uid as Uid

import qualified Sound.Sc3.Ugen.Bindings.Db as Bindings
import qualified Sound.Sc3.Ugen.Ugen as Ugen

-- | Pseudo-infinite constant Ugen.
dinf :: Ugen.Ugen
dinf :: Ugen
dinf = Sample -> Ugen
forall n. Real n => n -> Ugen
Ugen.constant (Sample
9e8 :: Ugen.Sample)

-- | 'Ugen' form of 'ceilingE'.
ceil :: Ugen.Ugen -> Ugen.Ugen
ceil :: Ugen -> Ugen
ceil = Ugen -> Ugen
forall a. RealFracE a => a -> a
Operator.ceilingE

-- | Midi note number and velocity data is in (0, 127).  This maps (0,1) to (0,100), i.e. is it (* 100).
unitMidi :: Num t => t -> t
unitMidi :: forall t. Num t => t -> t
unitMidi = t -> t -> t
forall a. Num a => a -> a -> a
(*) t
100

{- | midiCps of (0,1) scaled to (0,100).
     To make control signal data uniform, all control signals are in (0, 1).
-}
unitCps :: Operator.UnaryOp t => t -> t
unitCps :: forall t. UnaryOp t => t -> t
unitCps = t -> t
forall t. UnaryOp t => t -> t
Operator.midiCps (t -> t) -> (t -> t) -> t -> t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t -> t -> t
forall a. Num a => a -> a -> a
* t
100)

-- | Optimised Ugen sum function.
sum_opt :: [Ugen.Ugen] -> Ugen.Ugen
sum_opt :: [Ugen] -> Ugen
sum_opt = (Ugen -> Ugen -> Ugen -> Ugen)
-> (Ugen -> Ugen -> Ugen -> Ugen -> Ugen) -> [Ugen] -> Ugen
forall t.
Num t =>
(t -> t -> t -> t) -> (t -> t -> t -> t -> t) -> [t] -> t
Math.sum_opt_f Ugen -> Ugen -> Ugen -> Ugen
Bindings.sum3 Ugen -> Ugen -> Ugen -> Ugen -> Ugen
Bindings.sum4

-- | Apply the Ugen processor /f/ /k/ times in sequence to /i/, ie. for k=4 /f (f (f (f i)))/.
useqId :: (Uid.ID z, Enum z) => z -> Int -> (z -> Ugen.Ugen -> Ugen.Ugen) -> Ugen.Ugen -> Ugen.Ugen
useqId :: forall z.
(ID z, Enum z) =>
z -> Int -> (z -> Ugen -> Ugen) -> Ugen -> Ugen
useqId z
z Int
k z -> Ugen -> Ugen
f Ugen
i = if Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 then Ugen
i else z -> Int -> (z -> Ugen -> Ugen) -> Ugen -> Ugen
forall z.
(ID z, Enum z) =>
z -> Int -> (z -> Ugen -> Ugen) -> Ugen -> Ugen
useqId (z -> z
forall a. Enum a => a -> a
succ z
z) (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) z -> Ugen -> Ugen
f (z -> Ugen -> Ugen
f z
z Ugen
i)