-- | Envelope / Ugen.
module Sound.Sc3.Ugen.Envelope where

import Sound.Sc3.Common.Enum
import Sound.Sc3.Common.Envelope
import Sound.Sc3.Common.Math.Operator
import Sound.Sc3.Common.Rate

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

{- | Trapezoidal envelope generator.

> import Sound.Sc3.Plot
> plotEnvelope [envTrapezoid 0.99 0.5 1 1,envTrapezoid 0.5 0.75 0.65 0.35]
-}
envTrapezoid :: OrdE t => t -> t -> t -> t -> Envelope t
envTrapezoid :: forall t. OrdE t => t -> t -> t -> t -> Envelope t
envTrapezoid = (t -> t -> t, t -> t -> t) -> t -> t -> t -> t -> Envelope t
forall t.
Num t =>
(t -> t -> t, t -> t -> t) -> t -> t -> t -> t -> Envelope t
envTrapezoid_f (t -> t -> t
forall a. OrdE a => a -> a -> a
less_than_or_equal_to, t -> t -> t
forall a. OrdE a => a -> a -> a
greater_than_or_equal_to)

-- | 'latch' 1 of 'impulse' 0.
first_zero_then_one :: Rate -> Ugen
first_zero_then_one :: Rate -> Ugen
first_zero_then_one Rate
rt = Ugen -> Ugen -> Ugen
latch Ugen
1 (Rate -> Ugen -> Ugen -> Ugen
impulse Rate
rt Ugen
0 Ugen
0)

-- | 'env_circle_z' of k-rate 'first_zero_thereafter_one'.
env_circle_u :: Ugen -> Envelope_Curve Ugen -> Envelope Ugen -> Envelope Ugen
env_circle_u :: Ugen -> Envelope_Curve Ugen -> Envelope Ugen -> Envelope Ugen
env_circle_u = Ugen
-> Ugen -> Envelope_Curve Ugen -> Envelope Ugen -> Envelope Ugen
forall a.
Fractional a =>
a -> a -> Envelope_Curve a -> Envelope a -> Envelope a
env_circle_z (Rate -> Ugen
first_zero_then_one Rate
ControlRate)

-- | Singleton fade envelope.
envGate :: Ugen -> Ugen -> Ugen -> DoneAction Ugen -> Envelope_Curve Ugen -> Ugen
envGate :: Ugen
-> Ugen -> Ugen -> DoneAction Ugen -> Envelope_Curve Ugen -> Ugen
envGate Ugen
level Ugen
gate_ Ugen
fadeTime DoneAction Ugen
doneAction Envelope_Curve Ugen
curve =
  let startVal :: Ugen
startVal = Ugen
fadeTime Ugen -> Ugen -> Ugen
forall a. OrdE a => a -> a -> a
`less_than_or_equal_to` Ugen
0
      e :: Envelope Ugen
e = [Ugen]
-> [Ugen]
-> [Envelope_Curve Ugen]
-> Maybe Int
-> Maybe Int
-> Ugen
-> Envelope Ugen
forall a.
[a]
-> [a]
-> [Envelope_Curve a]
-> Maybe Int
-> Maybe Int
-> a
-> Envelope a
Envelope [Ugen
startVal, Ugen
1, Ugen
0] [Ugen
1, Ugen
1] [Envelope_Curve Ugen
curve] (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1) Maybe Int
forall a. Maybe a
Nothing Ugen
0
  in Rate
-> Ugen
-> Ugen
-> Ugen
-> Ugen
-> DoneAction Ugen
-> Envelope Ugen
-> Ugen
envGen Rate
ControlRate Ugen
gate_ Ugen
level Ugen
0 Ugen
fadeTime DoneAction Ugen
doneAction Envelope Ugen
e

{- | Variant with default values for all inputs.  @gate@ and
@fadeTime@ are 'control's, @doneAction@ is 'RemoveSynth', @curve@
is 'EnvSin'.
-}
envGate_def :: Ugen
envGate_def :: Ugen
envGate_def =
  let level :: Ugen
level = Ugen
1
      gate_ :: Ugen
gate_ = Rate -> String -> Double -> Control_Meta_T3 Double -> Ugen
control_m Rate
ControlRate String
"gate" Double
1 (Double
0, Double
1, String
"gate")
      fadeTime :: Ugen
fadeTime = Rate -> String -> Double -> Control_Meta_T3 Double -> Ugen
control_m Rate
ControlRate String
"fadeTime" Double
0.02 (Double
0, Double
10, String
"lin")
      doneAction :: DoneAction t
doneAction = DoneAction t
forall t. DoneAction t
RemoveSynth
      curve :: Envelope_Curve a
curve = Envelope_Curve a
forall a. Envelope_Curve a
EnvSin
  in Ugen
-> Ugen -> Ugen -> DoneAction Ugen -> Envelope_Curve Ugen -> Ugen
envGate Ugen
level Ugen
gate_ Ugen
fadeTime DoneAction Ugen
forall t. DoneAction t
doneAction Envelope_Curve Ugen
forall a. Envelope_Curve a
curve