-- | Non-primitve math Ugens.
module Sound.Sc3.Ugen.Math.Composite where

import Sound.Sc3.Common.Math.Operator

import Sound.Sc3.Ugen.Ugen
import Sound.Sc3.Ugen.Util

-- | Select /q/ or /r/ by /p/, ie. @if p == 1 then q else if p == 0 then r@.
ugen_if :: Num a => a -> a -> a -> a
ugen_if :: forall a. Num a => a -> a -> a -> a
ugen_if a
p a
q a
r = (a
p forall a. Num a => a -> a -> a
* a
q) forall a. Num a => a -> a -> a
+ ((a
1 forall a. Num a => a -> a -> a
- a
p) forall a. Num a => a -> a -> a
* a
r)

-- | Separate input into integral and fractional parts.
--
-- > ugen_integral_and_fractional_parts 1.5 == mce2 1 0.5
ugen_integral_and_fractional_parts :: Ugen -> Ugen
ugen_integral_and_fractional_parts :: Ugen -> Ugen
ugen_integral_and_fractional_parts Ugen
n =
    let gt_eq_0 :: Ugen
gt_eq_0 = let n' :: Ugen
n' = forall a. RealFracE a => a -> a
floorE Ugen
n in Ugen -> Ugen -> Ugen
mce2 Ugen
n' (Ugen
n forall a. Num a => a -> a -> a
- Ugen
n')
        lt_0 :: Ugen
lt_0 = let n' :: Ugen
n' = forall a. RealFracE a => a -> a
ceilingE Ugen
n in Ugen -> Ugen -> Ugen
mce2 Ugen
n' (Ugen
n forall a. Num a => a -> a -> a
- Ugen
n')
    in forall a. Num a => a -> a -> a -> a
ugen_if (Ugen
n forall a. OrdE a => a -> a -> a
`greater_than_or_equal_to` Ugen
0) Ugen
gt_eq_0 Ugen
lt_0

-- | Fractional midi into integral midi and cents detune.
--
-- > ugen_fmidi_to_midi_detune 60.5 == mce2 60 50
ugen_fmidi_to_midi_detune :: Ugen -> Ugen
ugen_fmidi_to_midi_detune :: Ugen -> Ugen
ugen_fmidi_to_midi_detune Ugen
mnn =
    let (Ugen
n,Ugen
c) = Ugen -> (Ugen, Ugen)
unmce2 (Ugen -> Ugen
ugen_integral_and_fractional_parts Ugen
mnn)
    in Ugen -> Ugen -> Ugen
mce2 Ugen
n (Ugen
c forall a. Num a => a -> a -> a
* Ugen
100)