module Csound.Typed.Types.MonoArg(
    MonoArg(..), MonoAdsr, adsrMonoSynt, monoAdsr
) where

import Csound.Typed.Types.Prim
import Csound.Typed.Types.Tuple
import Csound.Typed.Plugins.Adsr140

-- | Input argument for monophonic synthesizer.
-- It includes signals for amplitude, frequency (Cycles Per second), gate, trigger.
-- The gate equals to 1 when any note is pressed or zero when nothing is pressed.
-- The trigger equals to 1 at the moment when new note is pressed otherwise it's 0.
data MonoArg = MonoArg
    { MonoArg -> Sig
monoAmp  :: Sig
    , MonoArg -> Sig
monoCps  :: Sig
    , MonoArg -> Sig
monoGate :: Sig
    , MonoArg -> Sig
monoTrig :: Sig }

instance Tuple MonoArg where
    tupleMethods :: TupleMethods MonoArg
tupleMethods = (Sig4 -> MonoArg) -> (MonoArg -> Sig4) -> TupleMethods MonoArg
forall a b. Tuple a => (a -> b) -> (b -> a) -> TupleMethods b
makeTupleMethods Sig4 -> MonoArg
to MonoArg -> Sig4
from
        where
            to :: Sig4 -> MonoArg
            to :: Sig4 -> MonoArg
to (Sig
amp, Sig
cps, Sig
gate, Sig
trig) = Sig -> Sig -> Sig -> Sig -> MonoArg
MonoArg Sig
amp Sig
cps Sig
gate Sig
trig

            from :: MonoArg -> Sig4
            from :: MonoArg -> Sig4
from (MonoArg Sig
amp Sig
cps Sig
gate Sig
trig) = (Sig
amp, Sig
cps, Sig
gate, Sig
trig)

-- | ADSR that's used in monophonic instruments.
type MonoAdsr = Sig -> Sig -> Sig -> Sig -> Sig

-- | Turns the function that expects ADSR-function and amplitude and frequency to the
-- function on monophonic argument.
adsrMonoSynt :: (MonoAdsr -> (Sig, Sig) -> a) -> (MonoArg -> a)
adsrMonoSynt :: forall a. (MonoAdsr -> (Sig, Sig) -> a) -> MonoArg -> a
adsrMonoSynt MonoAdsr -> (Sig, Sig) -> a
f MonoArg
argument = MonoAdsr -> (Sig, Sig) -> a
f MonoAdsr
env (MonoArg -> Sig
monoAmp MonoArg
argument, MonoArg -> Sig
monoCps MonoArg
argument)
    where env :: MonoAdsr
env = MonoArg -> MonoAdsr
monoAdsr MonoArg
argument

monoAdsr :: MonoArg -> MonoAdsr
monoAdsr :: MonoArg -> MonoAdsr
monoAdsr MonoArg
argument = Sig -> Sig -> MonoAdsr
adsr140 (MonoArg -> Sig
monoGate MonoArg
argument) (MonoArg -> Sig
monoTrig MonoArg
argument)