{-# Language ScopedTypeVariables, TypeSynonymInstances, FlexibleInstances, LambdaCase #-}
-- | Patches.
module Csound.Air.Patch(

  CsdNote, Instr, MonoInstr, Fx, Fx1, Fx2, FxSpec(..), DryWetRatio,
  Patch1, Patch2, Patch(..), PolySyntSpec(..), MonoSyntSpec(..),
    SyntSkin, GenInstr, GenMonoInstr, GenFxSpec,
    polySynt, monoSynt, adsrMono, adsrMonoFilter, fxSpec, polySyntFilter, monoSyntFilter, fxSpecFilter,

    mapPatchInstr, mapMonoPolyInstr, transPatch, dryPatch, getPatchFx,
    setFxMix, setFxMixes,
    setMidiChn,

  -- * Midi
  atMidi,

  -- * Events
  atSched, atSchedUntil, atSchedHarp,

  -- * Sco
  atSco,

  -- * Single note
  atNote,

  -- * Fx
    addInstrFx, addPreFx, addPostFx,

    -- ** Specific fx
    fxSig, fxSigMix, fxSig2, fxSigMix2,
    mapFx, mapFx', bindFx, bindFx',
    mapPreFx, mapPreFx', bindPreFx, bindPreFx',

  -- * Pads
  harmonPatch, deepPad,

  -- * Misc
  patchWhen,

    mixInstr,

  -- * Rever
  withSmallRoom, withSmallRoom',
  withSmallHall, withSmallHall',
  withLargeHall, withLargeHall',
  withMagicCave, withMagicCave',

  -- * Sound font patches
  sfPatch, sfPatchHall,

    -- * Monosynt params
    onMonoSyntSpec, setMonoSlide, setMonoSharp,

    -- * Csound API
    patchByNameMidi,

  -- * Custom temperament
  -- ** Midi
  atMidiTemp,
  -- ** Csound API
    patchByNameMidiTemp
) where

import Data.Boolean hiding (cond)
import Data.Default
import Control.Monad
import Control.Applicative
import Control.Arrow(second)

import Control.Monad.Trans.Reader
import Csound.Typed hiding (arg)
import Csound.Control.Midi
import Csound.Control.Instr
import Csound.Control.Evt(impulse)
import Csound.Control.Sf
import Csound.Air.Fx
import Csound.Air.Filter(ResonFilter, mlp)
import Csound.Typed.Opcode(cpsmidinn)
import Csound.Tuning
import Csound.Types

import Temporal.Media hiding (rest)
import Csound.IO

-- | Common parameters for patches. We use this type to parametrize the patch with some tpyes of arguments
-- that we'd like to be able to change after patch is already constructed. For instance the filter type can greatly
-- change the character of the patch. So by making patches depend on filter type we can let the user to change
-- the filter type and  leave the algorithm the same. It's like changing between trademarks. Moog sound vs Korg sound.
--
-- The instruments in the patches depend on the @SyntSkin@ through the @Reader@ data type.
--
-- If user doesn't supply any syntSkin value the default is used (`mlp` -- moog low pass filter). Right now
-- the data type is just a synonym for filter but it can become a data type with more parameters in the future releases.
type SyntSkin = ResonFilter

-- | Generic polyphonic instrument. It depends on @SyntSkin@.
type GenInstr a b = Reader SyntSkin (Instr a b)

-- | Generic FX. It depends on @SyntSkin@.
type GenFxSpec a = Reader SyntSkin (FxSpec a)

-- | Generic monophonic instrument. It depends on @SyntSkin@.
type GenMonoInstr a = Reader SyntSkin (MonoInstr a)

-- | Data type for monophonic instruments.
type MonoInstr a = MonoArg -> SE a

-- | A simple csound note (good for playing with midi-keyboard).
-- It's a pair of amplitude (0 to 1) and freuqncy (Hz).
type CsdNote a = (a, a)

-- | An instrument transforms a note to a signal.
type Instr a b = CsdNote a -> SE b

-- | An effect processes the input signal.
type Fx a = a  -> SE a
type DryWetRatio = Sig

-- | Mono effect.
type Fx1 = Fx Sig

-- | Stereo effect.
type Fx2 = Fx Sig2

-- | Fx specification. It;s a pair of dryWet ratio and a transformation function.
data FxSpec a = FxSpec
  { FxSpec a -> DryWetRatio
fxMix :: DryWetRatio
  , FxSpec a -> Fx a
fxFun :: Fx a
  }

-- | Mono-output patch.
type Patch1 = Patch Sig

-- | Stereo-output patch.
type Patch2 = Patch Sig2

-- | Specification for monophonic synthesizer.
--
-- * Chn -- midi channel to listen on
--
-- * SlideTime -- time of transition between notes
data MonoSyntSpec = MonoSyntSpec
    { MonoSyntSpec -> MidiChn
monoSyntChn       :: MidiChn
    , MonoSyntSpec -> Maybe D
monoSyntSlideTime :: Maybe D }

instance Default MonoSyntSpec where
    def :: MonoSyntSpec
def = MonoSyntSpec :: MidiChn -> Maybe D -> MonoSyntSpec
MonoSyntSpec
        { monoSyntChn :: MidiChn
monoSyntChn = MidiChn
ChnAll
        , monoSyntSlideTime :: Maybe D
monoSyntSlideTime = D -> Maybe D
forall a. a -> Maybe a
Just D
0.008 }

data PolySyntSpec = PolySyntSpec
    { PolySyntSpec -> MidiChn
polySyntChn :: MidiChn }

instance Default PolySyntSpec where
    def :: PolySyntSpec
def = PolySyntSpec :: MidiChn -> PolySyntSpec
PolySyntSpec { polySyntChn :: MidiChn
polySyntChn = MidiChn
ChnAll }

-- | The patch can be:
--
-- *  a monophonic synt
--
-- * polyphonic synt
--
-- * set of common parameters (@SyntSkin@)
--
-- * patch with chain of effects,
--
-- * split on keyboard with certain frequency
--
-- * layer of patches. That is a several patches that sound at the same time.
--  the layer is a patch and the weight of volume for a given patch.
data Patch a
    = MonoSynt MonoSyntSpec (GenMonoInstr a) -- (GenInstr Sig a)
    | PolySynt PolySyntSpec (GenInstr D   a)
    | SetSkin SyntSkin (Patch a)
    | FxChain [GenFxSpec a] (Patch a)
    | SplitPatch (Patch a) D (Patch a)
    | LayerPatch [(Sig, Patch a)]

smoothMonoSpec :: MonoSyntSpec -> MonoArg -> MonoArg
smoothMonoSpec :: MonoSyntSpec -> MonoArg -> MonoArg
smoothMonoSpec MonoSyntSpec
spec = (MonoArg -> MonoArg)
-> (D -> MonoArg -> MonoArg) -> Maybe D -> MonoArg -> MonoArg
forall b a. b -> (a -> b) -> Maybe a -> b
maybe MonoArg -> MonoArg
forall a. a -> a
id D -> MonoArg -> MonoArg
smoothMonoArg (MonoSyntSpec -> Maybe D
monoSyntSlideTime MonoSyntSpec
spec)

-- | Constructor for polyphonic synthesizer. It expects a function from notes to signals.
polySynt :: (Instr D a) -> Patch a
polySynt :: Instr D a -> Patch a
polySynt = PolySyntSpec -> GenInstr D a -> Patch a
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt PolySyntSpec
forall a. Default a => a
def (GenInstr D a -> Patch a)
-> (Instr D a -> GenInstr D a) -> Instr D a -> Patch a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Instr D a -> GenInstr D a
forall (m :: * -> *) a. Monad m => a -> m a
return

-- | Constructor for polyphonic synthesizer with flexible choice of the low-pass filter.
-- If we use the filter from the first argument user lately can change it to some another filter. It defaults to mlp.
polySyntFilter :: (ResonFilter -> Instr D a) -> Patch a
polySyntFilter :: (ResonFilter -> Instr D a) -> Patch a
polySyntFilter ResonFilter -> Instr D a
instr = PolySyntSpec -> GenInstr D a -> Patch a
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt PolySyntSpec
forall a. Default a => a
def (GenInstr D a -> Patch a) -> GenInstr D a -> Patch a
forall a b. (a -> b) -> a -> b
$ (ResonFilter -> Instr D a) -> GenInstr D a
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
reader ResonFilter -> Instr D a
instr

-- | Constructor for monophonic synth with envelope generator. The envelope generator is synced with note triggering.
-- So it restarts itself when the note is retriggered. The envelope generator is a simple ADSR gennerator see the type @MonoAdsr@.
adsrMono :: (MonoAdsr -> Instr Sig a) -> Patch a
adsrMono :: (MonoAdsr -> Instr DryWetRatio a) -> Patch a
adsrMono MonoAdsr -> Instr DryWetRatio a
f = MonoInstr a -> Patch a
forall a. MonoInstr a -> Patch a
monoSynt ((MonoAdsr -> Instr DryWetRatio a) -> MonoInstr a
forall a.
(MonoAdsr -> (DryWetRatio, DryWetRatio) -> a) -> MonoArg -> a
adsrMonoSynt MonoAdsr -> Instr DryWetRatio a
f)

-- | Constructor for monophonic synth with envelope generator and flexible choice of filter. It's just like @adsrMono@
-- but the user lately can change filter provided in the first argument to some another filter.
adsrMonoFilter :: (ResonFilter -> MonoAdsr -> Instr Sig a) -> Patch a
adsrMonoFilter :: (ResonFilter -> MonoAdsr -> Instr DryWetRatio a) -> Patch a
adsrMonoFilter ResonFilter -> MonoAdsr -> Instr DryWetRatio a
f = (ResonFilter -> MonoInstr a) -> Patch a
forall a. (ResonFilter -> MonoInstr a) -> Patch a
monoSyntFilter (\ResonFilter
fltr -> (MonoAdsr -> Instr DryWetRatio a) -> MonoInstr a
forall a.
(MonoAdsr -> (DryWetRatio, DryWetRatio) -> a) -> MonoArg -> a
adsrMonoSynt (ResonFilter -> MonoAdsr -> Instr DryWetRatio a
f ResonFilter
fltr))

-- | Constructor for monophonic synthesizer. The instrument is defned on the raw monophonic aruments (see @MonoArg@).
monoSynt :: (MonoInstr a) -> Patch a
monoSynt :: MonoInstr a -> Patch a
monoSynt = MonoSyntSpec -> GenMonoInstr a -> Patch a
forall a. MonoSyntSpec -> GenMonoInstr a -> Patch a
MonoSynt MonoSyntSpec
forall a. Default a => a
def (GenMonoInstr a -> Patch a)
-> (MonoInstr a -> GenMonoInstr a) -> MonoInstr a -> Patch a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MonoInstr a -> GenMonoInstr a
forall (m :: * -> *) a. Monad m => a -> m a
return

-- | Constructor for monophonic synthesizer with flexible filter choice.
monoSyntFilter :: (ResonFilter -> MonoInstr a) -> Patch a
monoSyntFilter :: (ResonFilter -> MonoInstr a) -> Patch a
monoSyntFilter ResonFilter -> MonoInstr a
instr = MonoSyntSpec -> GenMonoInstr a -> Patch a
forall a. MonoSyntSpec -> GenMonoInstr a -> Patch a
MonoSynt MonoSyntSpec
forall a. Default a => a
def (GenMonoInstr a -> Patch a) -> GenMonoInstr a -> Patch a
forall a b. (a -> b) -> a -> b
$ (ResonFilter -> MonoInstr a) -> GenMonoInstr a
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
reader ResonFilter -> MonoInstr a
instr

-- | Constructor for FX-specification.
--
-- > fxSpec dryWetRatio fxFun
fxSpec :: Sig -> Fx a -> GenFxSpec a
fxSpec :: DryWetRatio -> Fx a -> GenFxSpec a
fxSpec DryWetRatio
ratio Fx a
fx = FxSpec a -> GenFxSpec a
forall (m :: * -> *) a. Monad m => a -> m a
return (FxSpec a -> GenFxSpec a) -> FxSpec a -> GenFxSpec a
forall a b. (a -> b) -> a -> b
$ DryWetRatio -> Fx a -> FxSpec a
forall a. DryWetRatio -> Fx a -> FxSpec a
FxSpec DryWetRatio
ratio Fx a
fx

-- | Constructor for FX-specification with flexible filter choice.
--
-- > fxSpec dryWetRatio fxFun
fxSpecFilter :: Sig -> (ResonFilter -> Fx a) -> GenFxSpec a
fxSpecFilter :: DryWetRatio -> (ResonFilter -> Fx a) -> GenFxSpec a
fxSpecFilter DryWetRatio
ratio ResonFilter -> Fx a
fx = (ResonFilter -> FxSpec a) -> GenFxSpec a
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
reader ((ResonFilter -> FxSpec a) -> GenFxSpec a)
-> (ResonFilter -> FxSpec a) -> GenFxSpec a
forall a b. (a -> b) -> a -> b
$ \ResonFilter
resonFilter -> DryWetRatio -> Fx a -> FxSpec a
forall a. DryWetRatio -> Fx a -> FxSpec a
FxSpec DryWetRatio
ratio (ResonFilter -> Fx a
fx ResonFilter
resonFilter)

-- Maps all monophonic and polyphonic patches within the given patch.
mapMonoPolyInstr :: (MonoInstr a -> MonoInstr a) -> (Instr D a -> Instr D a) -> Patch a -> Patch a
mapMonoPolyInstr :: (MonoInstr a -> MonoInstr a)
-> (Instr D a -> Instr D a) -> Patch a -> Patch a
mapMonoPolyInstr MonoInstr a -> MonoInstr a
mono Instr D a -> Instr D a
poly Patch a
x = case Patch a
x of
    MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> MonoSyntSpec -> GenMonoInstr a -> Patch a
forall a. MonoSyntSpec -> GenMonoInstr a -> Patch a
MonoSynt MonoSyntSpec
spec ((MonoInstr a -> MonoInstr a) -> GenMonoInstr a -> GenMonoInstr a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MonoInstr a -> MonoInstr a
mono GenMonoInstr a
instr)
    PolySynt PolySyntSpec
spec GenInstr D a
instr -> PolySyntSpec -> GenInstr D a -> Patch a
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt PolySyntSpec
spec ((Instr D a -> Instr D a) -> GenInstr D a -> GenInstr D a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Instr D a -> Instr D a
poly GenInstr D a
instr)
    SetSkin ResonFilter
skin Patch a
p      -> ResonFilter -> Patch a -> Patch a
forall a. ResonFilter -> Patch a -> Patch a
SetSkin ResonFilter
skin (Patch a -> Patch a
rec Patch a
p)
    FxChain  [GenFxSpec a]
fxs Patch a
p      -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain [GenFxSpec a]
fxs (Patch a -> Patch a
rec Patch a
p)
    LayerPatch [(DryWetRatio, Patch a)]
xs       -> [(DryWetRatio, Patch a)] -> Patch a
forall a. [(DryWetRatio, Patch a)] -> Patch a
LayerPatch ((Patch a -> Patch a)
-> [(DryWetRatio, Patch a)] -> [(DryWetRatio, Patch a)]
forall a b c. (a -> b) -> [(c, a)] -> [(c, b)]
mapSnd Patch a -> Patch a
rec [(DryWetRatio, Patch a)]
xs)
    SplitPatch Patch a
a D
dt Patch a
b   -> Patch a -> D -> Patch a -> Patch a
forall a. Patch a -> D -> Patch a -> Patch a
SplitPatch (Patch a -> Patch a
rec Patch a
a) D
dt (Patch a -> Patch a
rec Patch a
b)
    where
        rec :: Patch a -> Patch a
rec = (MonoInstr a -> MonoInstr a)
-> (Instr D a -> Instr D a) -> Patch a -> Patch a
forall a.
(MonoInstr a -> MonoInstr a)
-> (Instr D a -> Instr D a) -> Patch a -> Patch a
mapMonoPolyInstr MonoInstr a -> MonoInstr a
mono Instr D a -> Instr D a
poly

-- Maps all polyphonic patches within the given patch.
mapPatchInstr :: (Instr D a -> Instr D a) -> Patch a -> Patch a
mapPatchInstr :: (Instr D a -> Instr D a) -> Patch a -> Patch a
mapPatchInstr Instr D a -> Instr D a
f Patch a
x = case Patch a
x of
    MonoSynt MonoSyntSpec
_ GenMonoInstr a
_ -> Patch a
x
    PolySynt PolySyntSpec
spec GenInstr D a
instr -> PolySyntSpec -> GenInstr D a -> Patch a
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt PolySyntSpec
spec (GenInstr D a -> Patch a) -> GenInstr D a -> Patch a
forall a b. (a -> b) -> a -> b
$ (Instr D a -> Instr D a) -> GenInstr D a -> GenInstr D a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Instr D a -> Instr D a
f GenInstr D a
instr
    SetSkin ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> Patch a
forall a. ResonFilter -> Patch a -> Patch a
SetSkin ResonFilter
skin (Patch a -> Patch a
rec Patch a
p)
    FxChain [GenFxSpec a]
fxs Patch a
p -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain [GenFxSpec a]
fxs (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ Patch a -> Patch a
rec Patch a
p
    LayerPatch [(DryWetRatio, Patch a)]
xs -> [(DryWetRatio, Patch a)] -> Patch a
forall a. [(DryWetRatio, Patch a)] -> Patch a
LayerPatch ((Patch a -> Patch a)
-> [(DryWetRatio, Patch a)] -> [(DryWetRatio, Patch a)]
forall a b c. (a -> b) -> [(c, a)] -> [(c, b)]
mapSnd Patch a -> Patch a
rec [(DryWetRatio, Patch a)]
xs)
    SplitPatch Patch a
a D
dt Patch a
b -> Patch a -> D -> Patch a -> Patch a
forall a. Patch a -> D -> Patch a -> Patch a
SplitPatch (Patch a -> Patch a
rec Patch a
a) D
dt (Patch a -> Patch a
rec Patch a
b)
    where
        rec :: Patch a -> Patch a
rec = (Instr D a -> Instr D a) -> Patch a -> Patch a
forall a. (Instr D a -> Instr D a) -> Patch a -> Patch a
mapPatchInstr Instr D a -> Instr D a
f

-- | Removes all effects from the patch.
dryPatch :: Patch a -> Patch a
dryPatch :: Patch a -> Patch a
dryPatch Patch a
patch = case Patch a
patch of
    MonoSynt MonoSyntSpec
_ GenMonoInstr a
_ -> Patch a
patch
    PolySynt PolySyntSpec
_ GenInstr D a
_ -> Patch a
patch
    SetSkin ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> Patch a
forall a. ResonFilter -> Patch a -> Patch a
SetSkin ResonFilter
skin (Patch a -> Patch a
forall a. Patch a -> Patch a
dryPatch Patch a
p)
    FxChain [GenFxSpec a]
_ Patch a
p         -> Patch a -> Patch a
forall a. Patch a -> Patch a
dryPatch Patch a
p
    SplitPatch Patch a
a D
dt Patch a
b   -> Patch a -> D -> Patch a -> Patch a
forall a. Patch a -> D -> Patch a -> Patch a
SplitPatch (Patch a -> Patch a
forall a. Patch a -> Patch a
dryPatch Patch a
a) D
dt (Patch a -> Patch a
forall a. Patch a -> Patch a
dryPatch Patch a
b)
    LayerPatch [(DryWetRatio, Patch a)]
xs       -> [(DryWetRatio, Patch a)] -> Patch a
forall a. [(DryWetRatio, Patch a)] -> Patch a
LayerPatch ([(DryWetRatio, Patch a)] -> Patch a)
-> [(DryWetRatio, Patch a)] -> Patch a
forall a b. (a -> b) -> a -> b
$ (Patch a -> Patch a)
-> [(DryWetRatio, Patch a)] -> [(DryWetRatio, Patch a)]
forall a b c. (a -> b) -> [(c, a)] -> [(c, b)]
mapSnd Patch a -> Patch a
forall a. Patch a -> Patch a
dryPatch [(DryWetRatio, Patch a)]
xs

-- | Sets the dryWet ratio of the effects wwithin the patch.
setFxMix :: Sig -> Patch a -> Patch a
setFxMix :: DryWetRatio -> Patch a -> Patch a
setFxMix DryWetRatio
a = [DryWetRatio] -> Patch a -> Patch a
forall a. [DryWetRatio] -> Patch a -> Patch a
setFxMixes [DryWetRatio
a]

-- | Sets the dryWet ratios for the chain of the effects wwithin the patch.
setFxMixes :: [Sig] -> Patch a -> Patch a
setFxMixes :: [DryWetRatio] -> Patch a -> Patch a
setFxMixes [DryWetRatio]
ks = \case
    FxChain [GenFxSpec a]
fxs Patch a
x -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain ((DryWetRatio -> GenFxSpec a -> GenFxSpec a)
-> [DryWetRatio] -> [GenFxSpec a] -> [GenFxSpec a]
forall t t. (t -> t -> t) -> [t] -> [t] -> [t]
zipFirst (\DryWetRatio
k GenFxSpec a
q -> (FxSpec a -> FxSpec a) -> GenFxSpec a -> GenFxSpec a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\FxSpec a
t -> FxSpec a
t { fxMix :: DryWetRatio
fxMix = DryWetRatio
k }) GenFxSpec a
q) [DryWetRatio]
ks [GenFxSpec a]
fxs) Patch a
x
    Patch a
other -> Patch a
other
    where
        zipFirst :: (t -> t -> t) -> [t] -> [t] -> [t]
zipFirst t -> t -> t
f [t]
xs [t]
ys = case ([t]
xs, [t]
ys) of
            ([t]
_,    [])   -> []
            ([],   [t]
bs)   -> [t]
bs
            (t
a:[t]
as, t
b:[t]
bs) -> t -> t -> t
f t
a t
b t -> [t] -> [t]
forall a. a -> [a] -> [a]
: (t -> t -> t) -> [t] -> [t] -> [t]
zipFirst t -> t -> t
f [t]
as [t]
bs

--------------------------------------------------------------

instance SigSpace a => SigSpace (Patch a) where
  mapSig :: (DryWetRatio -> DryWetRatio) -> Patch a -> Patch a
mapSig DryWetRatio -> DryWetRatio
f Patch a
x =
            case Patch a
x of
                MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> MonoSyntSpec -> GenMonoInstr a -> Patch a
forall a. MonoSyntSpec -> GenMonoInstr a -> Patch a
MonoSynt MonoSyntSpec
spec (GenMonoInstr a -> Patch a) -> GenMonoInstr a -> Patch a
forall a b. (a -> b) -> a -> b
$ ((MonoArg -> SE a) -> MonoArg -> SE a)
-> GenMonoInstr a -> GenMonoInstr a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> a) -> SE a -> SE a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((DryWetRatio -> DryWetRatio) -> a -> a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f) (SE a -> SE a) -> (MonoArg -> SE a) -> MonoArg -> SE a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ) (GenMonoInstr a -> GenMonoInstr a)
-> GenMonoInstr a -> GenMonoInstr a
forall a b. (a -> b) -> a -> b
$ GenMonoInstr a
instr
                PolySynt PolySyntSpec
spec GenInstr D a
instr -> PolySyntSpec -> GenInstr D a -> Patch a
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt PolySyntSpec
spec (GenInstr D a -> Patch a) -> GenInstr D a -> Patch a
forall a b. (a -> b) -> a -> b
$ ((CsdNote D -> SE a) -> CsdNote D -> SE a)
-> GenInstr D a -> GenInstr D a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> a) -> SE a -> SE a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((DryWetRatio -> DryWetRatio) -> a -> a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f) (SE a -> SE a) -> (CsdNote D -> SE a) -> CsdNote D -> SE a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ) (GenInstr D a -> GenInstr D a) -> GenInstr D a -> GenInstr D a
forall a b. (a -> b) -> a -> b
$ GenInstr D a
instr
                SetSkin ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> Patch a
forall a. ResonFilter -> Patch a -> Patch a
SetSkin ResonFilter
skin (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ (DryWetRatio -> DryWetRatio) -> Patch a -> Patch a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f Patch a
p
                FxChain [GenFxSpec a]
fxs Patch a
p  -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain [GenFxSpec a]
fxs (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ (DryWetRatio -> DryWetRatio) -> Patch a -> Patch a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f Patch a
p
                SplitPatch Patch a
a D
dt Patch a
b -> Patch a -> D -> Patch a -> Patch a
forall a. Patch a -> D -> Patch a -> Patch a
SplitPatch ((DryWetRatio -> DryWetRatio) -> Patch a -> Patch a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f Patch a
a) D
dt ((DryWetRatio -> DryWetRatio) -> Patch a -> Patch a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f Patch a
b)
                LayerPatch [(DryWetRatio, Patch a)]
xs  -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain [FxSpec a -> GenFxSpec a
forall (m :: * -> *) a. Monad m => a -> m a
return (FxSpec a -> GenFxSpec a) -> FxSpec a -> GenFxSpec a
forall a b. (a -> b) -> a -> b
$ DryWetRatio -> Fx a -> FxSpec a
forall a. DryWetRatio -> Fx a -> FxSpec a
FxSpec DryWetRatio
1 (Fx a
forall (m :: * -> *) a. Monad m => a -> m a
return Fx a -> (a -> a) -> Fx a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DryWetRatio -> DryWetRatio) -> a -> a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f)] (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ [(DryWetRatio, Patch a)] -> Patch a
forall a. [(DryWetRatio, Patch a)] -> Patch a
LayerPatch [(DryWetRatio, Patch a)]
xs

mapSnd :: (a -> b) -> [(c, a)] -> [(c, b)]
mapSnd :: (a -> b) -> [(c, a)] -> [(c, b)]
mapSnd a -> b
f = ((c, a) -> (c, b)) -> [(c, a)] -> [(c, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> (c, a) -> (c, b)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second a -> b
f)

wet :: (SigSpace a, Sigs a) => FxSpec a -> Fx a
wet :: FxSpec a -> Fx a
wet (FxSpec DryWetRatio
k Fx a
fx) a
asig = (a -> a) -> SE a -> SE a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((DryWetRatio -> a -> a
forall a. SigSpace a => DryWetRatio -> a -> a
mul (DryWetRatio
1 DryWetRatio -> DryWetRatio -> DryWetRatio
forall a. Num a => a -> a -> a
- DryWetRatio
k) a
asig a -> a -> a
forall a. Num a => a -> a -> a
+ ) (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DryWetRatio -> a -> a
forall a. SigSpace a => DryWetRatio -> a -> a
mul DryWetRatio
k) (SE a -> SE a) -> SE a -> SE a
forall a b. (a -> b) -> a -> b
$ Fx a
fx a
asig

-- | Renders the effect chain to a single function.
getPatchFx :: (SigSpace a, Sigs a) => Maybe SyntSkin -> [GenFxSpec a] -> Fx a
getPatchFx :: Maybe ResonFilter -> [GenFxSpec a] -> Fx a
getPatchFx Maybe ResonFilter
maybeSkin [GenFxSpec a]
xs = (Fx a -> Fx a -> Fx a) -> Fx a -> [Fx a] -> Fx a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Fx a -> Fx a -> Fx a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
(<=<) Fx a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Fx a] -> Fx a) -> [Fx a] -> Fx a
forall a b. (a -> b) -> a -> b
$ (GenFxSpec a -> Fx a) -> [GenFxSpec a] -> [Fx a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FxSpec a -> Fx a
forall a. (SigSpace a, Sigs a) => FxSpec a -> Fx a
wet (FxSpec a -> Fx a)
-> (GenFxSpec a -> FxSpec a) -> GenFxSpec a -> Fx a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenFxSpec a -> Maybe ResonFilter -> FxSpec a)
-> Maybe ResonFilter -> GenFxSpec a -> FxSpec a
forall a b c. (a -> b -> c) -> b -> a -> c
flip GenFxSpec a -> Maybe ResonFilter -> FxSpec a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin Maybe ResonFilter
maybeSkin) [GenFxSpec a]
xs

-- | Plays a patch with a single infinite note.
atNote :: (SigSpace a, Sigs a) => Patch a -> CsdNote D -> SE a
atNote :: Patch a -> CsdNote D -> SE a
atNote = Maybe ResonFilter -> Patch a -> CsdNote D -> SE a
forall a.
Sigs a =>
Maybe ResonFilter -> Patch a -> CsdNote D -> SE a
go Maybe ResonFilter
forall a. Maybe a
Nothing
    where
        go :: Maybe ResonFilter -> Patch a -> CsdNote D -> SE a
go Maybe ResonFilter
maybeSkin Patch a
q note :: CsdNote D
note@(D
amp, D
cps) = case Patch a
q of
            MonoSynt MonoSyntSpec
_spec GenMonoInstr a
instr -> (GenMonoInstr a -> Maybe ResonFilter -> MonoInstr a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenMonoInstr a
instr Maybe ResonFilter
maybeSkin) (DryWetRatio -> DryWetRatio -> DryWetRatio -> DryWetRatio -> MonoArg
MonoArg (D -> DryWetRatio
sig D
amp) (D -> DryWetRatio
sig D
cps) DryWetRatio
1 (D -> DryWetRatio
impulse D
0))
            PolySynt PolySyntSpec
_spec GenInstr D a
instr -> (GenInstr D a -> Maybe ResonFilter -> CsdNote D -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenInstr D a
instr Maybe ResonFilter
maybeSkin) CsdNote D
note
            SetSkin  ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
p
            FxChain [GenFxSpec a]
fxs Patch a
p -> Maybe ResonFilter -> [GenFxSpec a] -> Fx a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter -> [GenFxSpec a] -> Fx a
getPatchFx Maybe ResonFilter
maybeSkin [GenFxSpec a]
fxs Fx a -> SE a -> SE a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Patch a -> SE a
rec Patch a
p
            LayerPatch [(DryWetRatio, Patch a)]
xs -> [(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
forall a.
(SigSpace a, Sigs a) =>
[(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
onLayered [(DryWetRatio, Patch a)]
xs Patch a -> SE a
rec
            SplitPatch Patch a
a D
t Patch a
b -> BoolD -> SE a -> SE a -> SE a
forall a. (Num a, Tuple a) => BoolD -> SE a -> SE a -> SE a
getSplit (D
cps D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`lessThan` D
t) (Patch a -> SE a
rec Patch a
a) (Patch a -> SE a
rec Patch a
b)
            where
                rec :: Patch a -> SE a
rec Patch a
x = Maybe ResonFilter -> Patch a -> CsdNote D -> SE a
go Maybe ResonFilter
maybeSkin Patch a
x CsdNote D
note
                newSkin :: ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
x = Maybe ResonFilter -> Patch a -> CsdNote D -> SE a
go (ResonFilter -> Maybe ResonFilter
forall a. a -> Maybe a
Just ResonFilter
skin) Patch a
x CsdNote D
note

runSkin :: Reader SyntSkin a -> Maybe SyntSkin -> a
runSkin :: Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin Reader ResonFilter a
instr Maybe ResonFilter
maybeSkin = Reader ResonFilter a -> ResonFilter -> a
forall r a. Reader r a -> r -> a
runReader Reader ResonFilter a
instr (ResonFilter -> a) -> ResonFilter -> a
forall a b. (a -> b) -> a -> b
$ ResonFilter
-> (ResonFilter -> ResonFilter) -> Maybe ResonFilter -> ResonFilter
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ResonFilter
mlp ResonFilter -> ResonFilter
forall a. a -> a
id Maybe ResonFilter
maybeSkin

getSplit :: (Num a, Tuple a) => BoolD -> SE a -> SE a -> SE a
getSplit :: BoolD -> SE a -> SE a -> SE a
getSplit BoolD
cond SE a
a SE a
b = do
    Ref a
ref <- a -> SE (Ref a)
forall a. Tuple a => a -> SE (Ref a)
newRef a
0
    BoolD -> SE () -> SE () -> SE ()
whenElseD BoolD
cond
        (Ref a -> a -> SE ()
forall a. (Num a, Tuple a) => Ref a -> a -> SE ()
mixRef Ref a
ref (a -> SE ()) -> SE a -> SE ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SE a
a)
        (Ref a -> a -> SE ()
forall a. (Num a, Tuple a) => Ref a -> a -> SE ()
mixRef Ref a
ref (a -> SE ()) -> SE a -> SE ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SE a
b)
    Ref a -> SE a
forall a. Tuple a => Ref a -> SE a
readRef Ref a
ref

--------------------------------------------------------------
-- midi

midiChn :: Sigs a => MidiChn -> (Msg -> SE a) -> SE a
midiChn :: MidiChn -> (Msg -> SE a) -> SE a
midiChn = \case
    MidiChn
ChnAll -> (Msg -> SE a) -> SE a
forall a. (Num a, Sigs a) => (Msg -> SE a) -> SE a
midi
    Chn Int
n  -> Int -> (Msg -> SE a) -> SE a
forall a. (Num a, Sigs a) => Int -> (Msg -> SE a) -> SE a
midin Int
n
    Pgm Maybe Int
pgm Int
chn -> Maybe Int -> Int -> (Msg -> SE a) -> SE a
forall a.
(Num a, Sigs a) =>
Maybe Int -> Int -> (Msg -> SE a) -> SE a
pgmidi Maybe Int
pgm Int
chn

-- | Plays a patch with midi.
atMidi :: (SigSpace a, Sigs a) => Patch a -> SE a
atMidi :: Patch a -> SE a
atMidi = Maybe ResonFilter -> Patch a -> SE a
forall a. Sigs a => Maybe ResonFilter -> Patch a -> SE a
go Maybe ResonFilter
forall a. Maybe a
Nothing
    where
        go :: Maybe ResonFilter -> Patch a -> SE a
go Maybe ResonFilter
maybeSkin = \case
            MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> MonoSyntSpec -> (MonoArg -> SE a) -> SE a
forall b. MonoSyntSpec -> (MonoArg -> SE b) -> SE b
monoSyntProc MonoSyntSpec
spec (GenMonoInstr a -> Maybe ResonFilter -> MonoArg -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenMonoInstr a
instr Maybe ResonFilter
maybeSkin)
            PolySynt PolySyntSpec
spec GenInstr D a
instr -> MidiChn -> (Msg -> SE a) -> SE a
forall a. Sigs a => MidiChn -> (Msg -> SE a) -> SE a
midiChn (PolySyntSpec -> MidiChn
polySyntChn PolySyntSpec
spec) ((GenInstr D a -> Maybe ResonFilter -> Instr D a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenInstr D a
instr Maybe ResonFilter
maybeSkin) Instr D a -> (Msg -> CsdNote D) -> Msg -> SE a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Msg -> CsdNote D
ampCps)
            SetSkin ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
p
            FxChain [GenFxSpec a]
fxs Patch a
p -> Maybe ResonFilter -> [GenFxSpec a] -> Fx a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter -> [GenFxSpec a] -> Fx a
getPatchFx Maybe ResonFilter
maybeSkin [GenFxSpec a]
fxs Fx a -> SE a -> SE a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Patch a -> SE a
rec Patch a
p
            LayerPatch [(DryWetRatio, Patch a)]
xs -> [(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
forall a.
(SigSpace a, Sigs a) =>
[(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
onLayered [(DryWetRatio, Patch a)]
xs Patch a -> SE a
rec
            SplitPatch Patch a
a D
dt Patch a
b -> Maybe ResonFilter
-> (Msg -> CsdNote D) -> Patch a -> D -> Patch a -> SE a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter
-> (Msg -> CsdNote D) -> Patch a -> D -> Patch a -> SE a
genMidiSplitPatch Maybe ResonFilter
maybeSkin Msg -> CsdNote D
ampCps Patch a
a D
dt Patch a
b
            where
                newSkin :: ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
p = Maybe ResonFilter -> Patch a -> SE a
go (ResonFilter -> Maybe ResonFilter
forall a. a -> Maybe a
Just ResonFilter
skin) Patch a
p
                rec :: Patch a -> SE a
rec = Maybe ResonFilter -> Patch a -> SE a
go Maybe ResonFilter
maybeSkin

                monoSyntProc :: MonoSyntSpec -> (MonoArg -> SE b) -> SE b
monoSyntProc MonoSyntSpec
spec MonoArg -> SE b
instr = MonoArg -> SE b
instr (MonoArg -> SE b) -> SE MonoArg -> SE b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SE MonoArg
getArg
                    where
                        getArg :: SE MonoArg
getArg = (MonoArg -> MonoArg) -> SE MonoArg -> SE MonoArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (MonoSyntSpec -> MonoArg -> MonoArg
smoothMonoSpec MonoSyntSpec
spec) (SE MonoArg -> SE MonoArg) -> SE MonoArg -> SE MonoArg
forall a b. (a -> b) -> a -> b
$ MidiChn -> SE MonoArg
genMonoMsg MidiChn
chn
                        chn :: MidiChn
chn  = MonoSyntSpec -> MidiChn
monoSyntChn MonoSyntSpec
spec

-- | Plays a patch with midi with given temperament (see @Csound.Tuning@).
atMidiTemp :: (SigSpace a, Sigs a) => Temp -> Patch a -> SE a
atMidiTemp :: Temp -> Patch a -> SE a
atMidiTemp Temp
tm = Maybe ResonFilter -> Patch a -> SE a
forall a. Sigs a => Maybe ResonFilter -> Patch a -> SE a
go Maybe ResonFilter
forall a. Maybe a
Nothing
    where
        go :: Maybe ResonFilter -> Patch a -> SE a
go Maybe ResonFilter
maybeSkin = \case
            MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> MonoSyntSpec -> (MonoArg -> SE a) -> SE a
forall b. MonoSyntSpec -> (MonoArg -> SE b) -> SE b
monoSyntProc MonoSyntSpec
spec (GenMonoInstr a -> Maybe ResonFilter -> MonoArg -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenMonoInstr a
instr Maybe ResonFilter
maybeSkin)
            PolySynt PolySyntSpec
spec GenInstr D a
instr -> MidiChn -> (Msg -> SE a) -> SE a
forall a. Sigs a => MidiChn -> (Msg -> SE a) -> SE a
midiChn (PolySyntSpec -> MidiChn
polySyntChn PolySyntSpec
spec) ((GenInstr D a -> Maybe ResonFilter -> Instr D a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenInstr D a
instr Maybe ResonFilter
maybeSkin) Instr D a -> (Msg -> CsdNote D) -> Msg -> SE a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Temp -> Msg -> CsdNote D
ampCps' Temp
tm)
            SetSkin ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
p
            FxChain [GenFxSpec a]
fxs Patch a
p -> Maybe ResonFilter -> [GenFxSpec a] -> Fx a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter -> [GenFxSpec a] -> Fx a
getPatchFx Maybe ResonFilter
maybeSkin [GenFxSpec a]
fxs Fx a -> SE a -> SE a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Patch a -> SE a
rec Patch a
p
            LayerPatch [(DryWetRatio, Patch a)]
xs -> [(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
forall a.
(SigSpace a, Sigs a) =>
[(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
onLayered [(DryWetRatio, Patch a)]
xs Patch a -> SE a
rec
            SplitPatch Patch a
a D
cps Patch a
b -> Maybe ResonFilter
-> (Msg -> CsdNote D) -> Patch a -> D -> Patch a -> SE a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter
-> (Msg -> CsdNote D) -> Patch a -> D -> Patch a -> SE a
genMidiSplitPatch Maybe ResonFilter
maybeSkin (Temp -> Msg -> CsdNote D
ampCps' Temp
tm) Patch a
a D
cps Patch a
b
            where
                newSkin :: ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
p = Maybe ResonFilter -> Patch a -> SE a
go (ResonFilter -> Maybe ResonFilter
forall a. a -> Maybe a
Just ResonFilter
skin) Patch a
p
                rec :: Patch a -> SE a
rec = Maybe ResonFilter -> Patch a -> SE a
go Maybe ResonFilter
maybeSkin

                monoSyntProc :: MonoSyntSpec -> (MonoArg -> SE b) -> SE b
monoSyntProc MonoSyntSpec
spec MonoArg -> SE b
instr = MonoArg -> SE b
instr (MonoArg -> SE b) -> SE MonoArg -> SE b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SE MonoArg
getArg
                    where
                        getArg :: SE MonoArg
getArg = (MonoArg -> MonoArg) -> SE MonoArg -> SE MonoArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (MonoSyntSpec -> MonoArg -> MonoArg
smoothMonoSpec MonoSyntSpec
spec) (SE MonoArg -> SE MonoArg) -> SE MonoArg -> SE MonoArg
forall a b. (a -> b) -> a -> b
$ Temp -> MidiChn -> SE MonoArg
genMonoMsgTemp Temp
tm MidiChn
chn
                        chn :: MidiChn
chn  = MonoSyntSpec -> MidiChn
monoSyntChn MonoSyntSpec
spec


genMidiSplitPatch :: (SigSpace a, Sigs a) => Maybe SyntSkin -> (Msg -> (D, D)) -> Patch a -> D -> Patch a -> SE a
genMidiSplitPatch :: Maybe ResonFilter
-> (Msg -> CsdNote D) -> Patch a -> D -> Patch a -> SE a
genMidiSplitPatch Maybe ResonFilter
maybeSkin Msg -> CsdNote D
midiArg = Maybe ResonFilter
-> (MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a)
-> (MidiChn -> (CsdNote D -> SE a) -> SE a)
-> Patch a
-> D
-> Patch a
-> SE a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter
-> (MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a)
-> (MidiChn -> (CsdNote D -> SE a) -> SE a)
-> Patch a
-> D
-> Patch a
-> SE a
genSplitPatch Maybe ResonFilter
maybeSkin MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a
forall b. MidiChn -> (D -> BoolD) -> (MonoArg -> SE b) -> SE b
playMonoInstr MidiChn -> (CsdNote D -> SE a) -> SE a
forall a. Sigs a => MidiChn -> (CsdNote D -> SE a) -> SE a
playInstr
    where
        playMonoInstr :: MidiChn -> (D -> BoolD) -> (MonoArg -> SE b) -> SE b
playMonoInstr MidiChn
chn D -> BoolD
cond MonoArg -> SE b
instr = MonoArg -> SE b
instr (MonoArg -> SE b) -> SE MonoArg -> SE b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MidiChn -> (D -> BoolD) -> SE MonoArg
genFilteredMonoMsg MidiChn
chn D -> BoolD
cond
        playInstr :: MidiChn -> (CsdNote D -> SE a) -> SE a
playInstr MidiChn
chn CsdNote D -> SE a
instr = MidiChn -> (Msg -> SE a) -> SE a
forall a. Sigs a => MidiChn -> (Msg -> SE a) -> SE a
midiChn MidiChn
chn (CsdNote D -> SE a
instr (CsdNote D -> SE a) -> (Msg -> CsdNote D) -> Msg -> SE a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Msg -> CsdNote D
midiArg)

genSplitPatch :: (SigSpace a, Sigs a) => Maybe SyntSkin -> (MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a)  -> (MidiChn -> (CsdNote D -> SE a) -> SE a) -> Patch a -> D -> Patch a -> SE a
genSplitPatch :: Maybe ResonFilter
-> (MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a)
-> (MidiChn -> (CsdNote D -> SE a) -> SE a)
-> Patch a
-> D
-> Patch a
-> SE a
genSplitPatch Maybe ResonFilter
maybeSkin' MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a
playMonoInstr MidiChn -> (CsdNote D -> SE a) -> SE a
playInstr Patch a
a' D
dt' Patch a
b' = (a -> a -> a) -> SE a -> SE a -> SE a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(+) (Maybe ResonFilter -> D -> Patch a -> SE a
leftSplit Maybe ResonFilter
maybeSkin' D
dt' Patch a
a') (Maybe ResonFilter -> D -> Patch a -> SE a
rightSplit Maybe ResonFilter
maybeSkin' D
dt' Patch a
b')
    where
        leftSplit :: Maybe ResonFilter -> D -> Patch a -> SE a
leftSplit  Maybe ResonFilter
maybeSkin D
dt Patch a
a = Maybe ResonFilter
-> (D -> BoolD) -> (DryWetRatio -> BoolSig) -> Patch a -> SE a
onCondPlay Maybe ResonFilter
maybeSkin ( D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`lessThan` D
dt)          ( DryWetRatio -> DryWetRatio -> BooleanOf DryWetRatio
forall a. OrdB a => a -> a -> BooleanOf a
`lessThan` (D -> DryWetRatio
sig D
dt))           Patch a
a
        rightSplit :: Maybe ResonFilter -> D -> Patch a -> SE a
rightSplit Maybe ResonFilter
maybeSkin D
dt Patch a
a = Maybe ResonFilter
-> (D -> BoolD) -> (DryWetRatio -> BoolSig) -> Patch a -> SE a
onCondPlay Maybe ResonFilter
maybeSkin ( D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`greaterThanEquals` D
dt) ( DryWetRatio -> DryWetRatio -> BooleanOf DryWetRatio
forall a. OrdB a => a -> a -> BooleanOf a
`greaterThanEquals` (D -> DryWetRatio
sig D
dt))  Patch a
a

        onCondPlay :: Maybe ResonFilter
-> (D -> BoolD) -> (DryWetRatio -> BoolSig) -> Patch a -> SE a
onCondPlay Maybe ResonFilter
maybeSkin D -> BoolD
cond DryWetRatio -> BoolSig
condSig = \case
            MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a
playMonoInstr  (MonoSyntSpec -> MidiChn
monoSyntChn MonoSyntSpec
spec) D -> BoolD
cond  ((DryWetRatio -> BoolSig) -> MonoInstr a -> MonoInstr a
forall a.
Sigs a =>
(DryWetRatio -> BoolSig) -> MonoInstr a -> MonoInstr a
restrictMonoInstr DryWetRatio -> BoolSig
condSig (MonoInstr a -> MonoInstr a) -> MonoInstr a -> MonoInstr a
forall a b. (a -> b) -> a -> b
$ GenMonoInstr a -> Maybe ResonFilter -> MonoInstr a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenMonoInstr a
instr Maybe ResonFilter
maybeSkin)
            PolySynt PolySyntSpec
spec GenInstr D a
instr -> MidiChn -> (CsdNote D -> SE a) -> SE a
playInstr (PolySyntSpec -> MidiChn
polySyntChn PolySyntSpec
spec) ((D -> BoolD) -> (CsdNote D -> SE a) -> CsdNote D -> SE a
forall a.
Sigs a =>
(D -> BoolD) -> (CsdNote D -> SE a) -> CsdNote D -> SE a
restrictPolyInstr D -> BoolD
cond (GenInstr D a -> Maybe ResonFilter -> CsdNote D -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenInstr D a
instr Maybe ResonFilter
maybeSkin))
            SetSkin  ResonFilter
skin Patch a
p -> Maybe ResonFilter
-> (D -> BoolD) -> (DryWetRatio -> BoolSig) -> Patch a -> SE a
onCondPlay (ResonFilter -> Maybe ResonFilter
forall a. a -> Maybe a
Just ResonFilter
skin) D -> BoolD
cond DryWetRatio -> BoolSig
condSig Patch a
p
            FxChain [GenFxSpec a]
fxs Patch a
p -> Maybe ResonFilter -> [GenFxSpec a] -> Fx a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter -> [GenFxSpec a] -> Fx a
getPatchFx Maybe ResonFilter
maybeSkin [GenFxSpec a]
fxs Fx a -> SE a -> SE a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe ResonFilter
-> (D -> BoolD) -> (DryWetRatio -> BoolSig) -> Patch a -> SE a
onCondPlay Maybe ResonFilter
maybeSkin D -> BoolD
cond DryWetRatio -> BoolSig
condSig Patch a
p
            LayerPatch [(DryWetRatio, Patch a)]
xs -> [(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
forall a.
(SigSpace a, Sigs a) =>
[(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
onLayered [(DryWetRatio, Patch a)]
xs (Maybe ResonFilter
-> (D -> BoolD) -> (DryWetRatio -> BoolSig) -> Patch a -> SE a
onCondPlay Maybe ResonFilter
maybeSkin D -> BoolD
cond DryWetRatio -> BoolSig
condSig)
            SplitPatch Patch a
a D
dt Patch a
b -> (a -> a -> a) -> SE a -> SE a -> SE a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(+)
                        (Maybe ResonFilter
-> (D -> BoolD) -> (DryWetRatio -> BoolSig) -> Patch a -> SE a
onCondPlay Maybe ResonFilter
maybeSkin (\D
x -> D -> BoolD
cond D
x BoolD -> BoolD -> BoolD
forall b. Boolean b => b -> b -> b
&&* (D
x D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`lessThan` D
dt))           (\DryWetRatio
x -> DryWetRatio -> BoolSig
condSig DryWetRatio
x BoolSig -> BoolSig -> BoolSig
forall b. Boolean b => b -> b -> b
&&* (DryWetRatio
x DryWetRatio -> DryWetRatio -> BooleanOf DryWetRatio
forall a. OrdB a => a -> a -> BooleanOf a
`lessThan` (D -> DryWetRatio
sig D
dt))) Patch a
a)
                        (Maybe ResonFilter
-> (D -> BoolD) -> (DryWetRatio -> BoolSig) -> Patch a -> SE a
onCondPlay Maybe ResonFilter
maybeSkin (\D
x -> D -> BoolD
cond D
x BoolD -> BoolD -> BoolD
forall b. Boolean b => b -> b -> b
&&* (D
x D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`greaterThanEquals` D
dt))  (\DryWetRatio
x -> DryWetRatio -> BoolSig
condSig DryWetRatio
x BoolSig -> BoolSig -> BoolSig
forall b. Boolean b => b -> b -> b
&&* (DryWetRatio
x DryWetRatio -> DryWetRatio -> BooleanOf DryWetRatio
forall a. OrdB a => a -> a -> BooleanOf a
`greaterThanEquals` (D -> DryWetRatio
sig D
dt) ))  Patch a
b)

restrictPolyInstr :: (Sigs a) => (D -> BoolD) -> (CsdNote D -> SE a) -> CsdNote D -> SE a
restrictPolyInstr :: (D -> BoolD) -> (CsdNote D -> SE a) -> CsdNote D -> SE a
restrictPolyInstr D -> BoolD
cond CsdNote D -> SE a
instr note :: CsdNote D
note@(D
_amp, D
cps) = do
    Ref a
ref <- a -> SE (Ref a)
forall a. Tuple a => a -> SE (Ref a)
newRef a
0
    BoolD -> SE () -> SE () -> SE ()
whenElseD (D -> BoolD
cond D
cps)
        (Ref a -> a -> SE ()
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref a
ref (a -> SE ()) -> SE a -> SE ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< CsdNote D -> SE a
instr CsdNote D
note)
        (Ref a -> a -> SE ()
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref a
ref a
0)
    Ref a -> SE a
forall a. Tuple a => Ref a -> SE a
readRef Ref a
ref

restrictMonoInstr :: (Sigs a) => (Sig -> BoolSig) -> MonoInstr a -> MonoInstr a
restrictMonoInstr :: (DryWetRatio -> BoolSig) -> MonoInstr a -> MonoInstr a
restrictMonoInstr DryWetRatio -> BoolSig
cond MonoInstr a
instr MonoArg
arg = MonoInstr a
instr MonoInstr a -> MonoInstr a
forall a b. (a -> b) -> a -> b
$ MonoArg
arg { monoGate :: DryWetRatio
monoGate = MonoArg -> DryWetRatio
monoGate MonoArg
arg DryWetRatio -> DryWetRatio -> DryWetRatio
forall a. Num a => a -> a -> a
* DryWetRatio
gate2 }
    where
        cps :: DryWetRatio
cps = MonoArg -> DryWetRatio
monoCps MonoArg
arg
        gate2 :: DryWetRatio
gate2 = BoolSig -> DryWetRatio -> DryWetRatio -> DryWetRatio
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (DryWetRatio -> BoolSig
cond DryWetRatio
cps) DryWetRatio
1 DryWetRatio
0

--------------------------------------------------------------
-- sched

-- | Plays a patch with event stream.
atSched :: (SigSpace a, Sigs a) => Patch a -> Evt (Sco (CsdNote D)) -> SE a
atSched :: Patch a -> Evt (Sco (CsdNote D)) -> SE a
atSched = Maybe ResonFilter -> Patch a -> Evt (Sco (CsdNote D)) -> SE a
forall a.
Sigs a =>
Maybe ResonFilter -> Patch a -> Evt (Sco (CsdNote D)) -> SE a
go Maybe ResonFilter
forall a. Maybe a
Nothing
    where
        go :: Maybe ResonFilter -> Patch a -> Evt (Sco (CsdNote D)) -> SE a
go Maybe ResonFilter
maybeSkin Patch a
x Evt (Sco (CsdNote D))
evt = case Patch a
x of
            MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> (GenMonoInstr a -> Maybe ResonFilter -> MonoInstr a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenMonoInstr a
instr Maybe ResonFilter
maybeSkin) MonoInstr a -> SE MonoArg -> SE a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ((MonoArg -> MonoArg) -> SE MonoArg -> SE MonoArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (MonoSyntSpec -> MonoArg -> MonoArg
smoothMonoSpec MonoSyntSpec
spec) (SE MonoArg -> SE MonoArg) -> SE MonoArg -> SE MonoArg
forall a b. (a -> b) -> a -> b
$ Evt (Sco (CsdNote D)) -> SE MonoArg
monoSched Evt (Sco (CsdNote D))
evt)
            PolySynt PolySyntSpec
_ GenInstr D a
instr -> (CsdNote D -> SE a) -> SE a
forall (m :: * -> *) a.
(Monad m, Sigs a) =>
(CsdNote D -> SE a) -> m a
playInstr (GenInstr D a -> Maybe ResonFilter -> CsdNote D -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenInstr D a
instr Maybe ResonFilter
maybeSkin)
            SetSkin ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
p
            FxChain [GenFxSpec a]
fxs Patch a
p  -> Maybe ResonFilter -> [GenFxSpec a] -> Fx a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter -> [GenFxSpec a] -> Fx a
getPatchFx Maybe ResonFilter
maybeSkin [GenFxSpec a]
fxs Fx a -> SE a -> SE a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Patch a -> SE a
rec Patch a
p
            LayerPatch [(DryWetRatio, Patch a)]
xs -> [(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
forall a.
(SigSpace a, Sigs a) =>
[(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
onLayered [(DryWetRatio, Patch a)]
xs Patch a -> SE a
rec
            SplitPatch Patch a
a D
t Patch a
b -> Maybe ResonFilter
-> (MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a)
-> (MidiChn -> (CsdNote D -> SE a) -> SE a)
-> Patch a
-> D
-> Patch a
-> SE a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter
-> (MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a)
-> (MidiChn -> (CsdNote D -> SE a) -> SE a)
-> Patch a
-> D
-> Patch a
-> SE a
genSplitPatch Maybe ResonFilter
maybeSkin (((D -> BoolD) -> MonoInstr a -> SE a)
-> MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a
forall a b. a -> b -> a
const (((D -> BoolD) -> MonoInstr a -> SE a)
 -> MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a)
-> ((D -> BoolD) -> MonoInstr a -> SE a)
-> MidiChn
-> (D -> BoolD)
-> MonoInstr a
-> SE a
forall a b. (a -> b) -> a -> b
$ (MonoInstr a -> SE a) -> (D -> BoolD) -> MonoInstr a -> SE a
forall a b. a -> b -> a
const MonoInstr a -> SE a
forall b. (MonoArg -> SE b) -> SE b
playMonoInstr) (((CsdNote D -> SE a) -> SE a)
-> MidiChn -> (CsdNote D -> SE a) -> SE a
forall a b. a -> b -> a
const (CsdNote D -> SE a) -> SE a
forall (m :: * -> *) a.
(Monad m, Sigs a) =>
(CsdNote D -> SE a) -> m a
playInstr) Patch a
a D
t Patch a
b
            where
                rec :: Patch a -> SE a
rec Patch a
a = Maybe ResonFilter -> Patch a -> Evt (Sco (CsdNote D)) -> SE a
go Maybe ResonFilter
maybeSkin Patch a
a Evt (Sco (CsdNote D))
evt
                newSkin :: ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
a = Maybe ResonFilter -> Patch a -> Evt (Sco (CsdNote D)) -> SE a
go (ResonFilter -> Maybe ResonFilter
forall a. a -> Maybe a
Just ResonFilter
skin) Patch a
a Evt (Sco (CsdNote D))
evt
                playInstr :: (CsdNote D -> SE a) -> m a
playInstr CsdNote D -> SE a
instr = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ (CsdNote D -> SE a) -> Evt (Sco (CsdNote D)) -> a
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Evt (Sco a) -> b
sched CsdNote D -> SE a
instr Evt (Sco (CsdNote D))
evt
                playMonoInstr :: (MonoArg -> SE b) -> SE b
playMonoInstr MonoArg -> SE b
instr = MonoArg -> SE b
instr (MonoArg -> SE b) -> SE MonoArg -> SE b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Evt (Sco (CsdNote D)) -> SE MonoArg
monoSched Evt (Sco (CsdNote D))
evt

-- | Plays a patch with event stream with stop-note event stream.
atSchedUntil :: (SigSpace a, Sigs a) => Patch a -> Evt (CsdNote D) -> Evt b -> SE a
atSchedUntil :: Patch a -> Evt (CsdNote D) -> Evt b -> SE a
atSchedUntil = Maybe ResonFilter -> Patch a -> Evt (CsdNote D) -> Evt b -> SE a
forall a c.
Sigs a =>
Maybe ResonFilter -> Patch a -> Evt (CsdNote D) -> Evt c -> SE a
go Maybe ResonFilter
forall a. Maybe a
Nothing
    where
        go :: Maybe ResonFilter -> Patch a -> Evt (CsdNote D) -> Evt c -> SE a
go Maybe ResonFilter
maybeSkin Patch a
x Evt (CsdNote D)
evt Evt c
stop = case Patch a
x of
            MonoSynt MonoSyntSpec
_ GenMonoInstr a
instr -> (MonoArg -> SE a) -> SE a
forall b. (MonoArg -> SE b) -> SE b
playMonoInstr (GenMonoInstr a -> Maybe ResonFilter -> MonoArg -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenMonoInstr a
instr Maybe ResonFilter
maybeSkin)
            PolySynt PolySyntSpec
_ GenInstr D a
instr -> (CsdNote D -> SE a) -> SE a
forall (m :: * -> *) a.
(Monad m, Sigs a) =>
(CsdNote D -> SE a) -> m a
playInstr (GenInstr D a -> Maybe ResonFilter -> CsdNote D -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenInstr D a
instr Maybe ResonFilter
maybeSkin)
            SetSkin ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
p
            FxChain [GenFxSpec a]
fxs Patch a
p  -> Maybe ResonFilter -> [GenFxSpec a] -> Fx a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter -> [GenFxSpec a] -> Fx a
getPatchFx Maybe ResonFilter
maybeSkin [GenFxSpec a]
fxs Fx a -> SE a -> SE a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Patch a -> SE a
rec Patch a
p
            LayerPatch [(DryWetRatio, Patch a)]
xs -> [(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
forall a.
(SigSpace a, Sigs a) =>
[(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
onLayered [(DryWetRatio, Patch a)]
xs Patch a -> SE a
rec
            SplitPatch Patch a
a D
cps Patch a
b -> Maybe ResonFilter
-> (MidiChn -> (D -> BoolD) -> (MonoArg -> SE a) -> SE a)
-> (MidiChn -> (CsdNote D -> SE a) -> SE a)
-> Patch a
-> D
-> Patch a
-> SE a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter
-> (MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a)
-> (MidiChn -> (CsdNote D -> SE a) -> SE a)
-> Patch a
-> D
-> Patch a
-> SE a
genSplitPatch Maybe ResonFilter
maybeSkin (((D -> BoolD) -> (MonoArg -> SE a) -> SE a)
-> MidiChn -> (D -> BoolD) -> (MonoArg -> SE a) -> SE a
forall a b. a -> b -> a
const (((D -> BoolD) -> (MonoArg -> SE a) -> SE a)
 -> MidiChn -> (D -> BoolD) -> (MonoArg -> SE a) -> SE a)
-> ((D -> BoolD) -> (MonoArg -> SE a) -> SE a)
-> MidiChn
-> (D -> BoolD)
-> (MonoArg -> SE a)
-> SE a
forall a b. (a -> b) -> a -> b
$ ((MonoArg -> SE a) -> SE a)
-> (D -> BoolD) -> (MonoArg -> SE a) -> SE a
forall a b. a -> b -> a
const (MonoArg -> SE a) -> SE a
forall b. (MonoArg -> SE b) -> SE b
playMonoInstr) (((CsdNote D -> SE a) -> SE a)
-> MidiChn -> (CsdNote D -> SE a) -> SE a
forall a b. a -> b -> a
const (CsdNote D -> SE a) -> SE a
forall (m :: * -> *) a.
(Monad m, Sigs a) =>
(CsdNote D -> SE a) -> m a
playInstr) Patch a
a D
cps Patch a
b
            where
                rec :: Patch a -> SE a
rec Patch a
a = Maybe ResonFilter -> Patch a -> Evt (CsdNote D) -> Evt c -> SE a
go Maybe ResonFilter
maybeSkin Patch a
a Evt (CsdNote D)
evt Evt c
stop
                newSkin :: ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
a = Maybe ResonFilter -> Patch a -> Evt (CsdNote D) -> Evt c -> SE a
go (ResonFilter -> Maybe ResonFilter
forall a. a -> Maybe a
Just ResonFilter
skin) Patch a
a Evt (CsdNote D)
evt Evt c
stop
                playInstr :: (CsdNote D -> SE a) -> m a
playInstr CsdNote D -> SE a
instr = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ (CsdNote D -> SE a) -> Evt (CsdNote D) -> Evt c -> a
forall a b c. (Arg a, Sigs b) => (a -> SE b) -> Evt a -> Evt c -> b
schedUntil CsdNote D -> SE a
instr Evt (CsdNote D)
evt Evt c
stop
                playMonoInstr :: (MonoArg -> SE b) -> SE b
playMonoInstr MonoArg -> SE b
instr = MonoArg -> SE b
instr (MonoArg -> SE b) -> SE MonoArg -> SE b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Evt (CsdNote D) -> Evt c -> SE MonoArg
forall a. Evt (CsdNote D) -> Evt a -> SE MonoArg
monoSchedUntil Evt (CsdNote D)
evt Evt c
stop

-- | Plays notes indefinetely (it's more useful for monophonic synthesizers).
atSchedHarp :: (SigSpace a, Sigs a) => Patch a -> Evt (CsdNote D) -> SE a
atSchedHarp :: Patch a -> Evt (CsdNote D) -> SE a
atSchedHarp Patch a
x Evt (CsdNote D)
evt = Patch a -> Evt (CsdNote D) -> Evt Any -> SE a
forall a b.
(SigSpace a, Sigs a) =>
Patch a -> Evt (CsdNote D) -> Evt b -> SE a
atSchedUntil  Patch a
x Evt (CsdNote D)
evt Evt Any
forall a. Monoid a => a
mempty

--------------------------------------------------------------
-- sco

-- | Plays a patch with scores.
atSco :: forall a . (SigSpace a, Sigs a) => Patch a -> Sco (CsdNote D) -> Sco (Mix a)
atSco :: Patch a -> Sco (CsdNote D) -> Sco (Mix a)
atSco = Maybe ResonFilter -> Patch a -> Sco (CsdNote D) -> Sco (Mix a)
go Maybe ResonFilter
forall a. Maybe a
Nothing
    where
        go :: Maybe ResonFilter -> Patch a -> Sco (CsdNote D) -> Sco (Mix a)
go Maybe ResonFilter
skin Patch a
x Sco (CsdNote D)
sc = case Patch a
x of
            MonoSynt MonoSyntSpec
_ GenMonoInstr a
instr -> (MonoArg -> SE a) -> Sco (CsdNote D) -> Sco (Mix a)
forall a.
Sigs a =>
(MonoArg -> SE a) -> Sco (CsdNote D) -> Sco (Mix a)
monoSco (GenMonoInstr a -> Maybe ResonFilter -> MonoArg -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenMonoInstr a
instr Maybe ResonFilter
skin) Sco (CsdNote D)
sc
            PolySynt PolySyntSpec
_ GenInstr D a
instr -> (CsdNote D -> SE a) -> Sco (CsdNote D) -> Sco (Mix a)
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Sco a -> Sco (Mix b)
sco (GenInstr D a -> Maybe ResonFilter -> CsdNote D -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenInstr D a
instr Maybe ResonFilter
skin) Sco (CsdNote D)
sc
            SetSkin ResonFilter
sk Patch a
p -> ResonFilter -> Patch a -> Sco (Mix a)
newSkin ResonFilter
sk Patch a
p
            FxChain [GenFxSpec a]
fxs Patch a
p  -> (a -> SE a) -> Sco (Mix a) -> Sco (Mix a)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Maybe ResonFilter -> [GenFxSpec a] -> a -> SE a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter -> [GenFxSpec a] -> Fx a
getPatchFx Maybe ResonFilter
skin [GenFxSpec a]
fxs) (Sco (Mix a) -> Sco (Mix a)) -> Sco (Mix a) -> Sco (Mix a)
forall a b. (a -> b) -> a -> b
$ Patch a -> Sco (Mix a)
rec Patch a
p
            LayerPatch [(DryWetRatio, Patch a)]
xs -> [Sco (Mix a)] -> Sco (Mix a)
forall a. Harmony a => [a] -> a
har ([Sco (Mix a)] -> Sco (Mix a)) -> [Sco (Mix a)] -> Sco (Mix a)
forall a b. (a -> b) -> a -> b
$ ((DryWetRatio, Patch a) -> Sco (Mix a))
-> [(DryWetRatio, Patch a)] -> [Sco (Mix a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(DryWetRatio
vol, Patch a
p) -> Patch a -> Sco (Mix a)
rec (DryWetRatio -> Patch a -> Patch a
forall a. SigSpace a => DryWetRatio -> a -> a
mul DryWetRatio
vol Patch a
p)) [(DryWetRatio, Patch a)]
xs
            SplitPatch Patch a
a D
cps Patch a
b -> Maybe ResonFilter -> Patch a -> D -> Patch a -> Sco (Mix a)
scoSplitPatch Maybe ResonFilter
skin Patch a
a D
cps Patch a
b
            where
                rec :: Patch a -> Sco (Mix a)
rec Patch a
a = Maybe ResonFilter -> Patch a -> Sco (CsdNote D) -> Sco (Mix a)
go Maybe ResonFilter
skin Patch a
a Sco (CsdNote D)
sc
                newSkin :: ResonFilter -> Patch a -> Sco (Mix a)
newSkin ResonFilter
sk Patch a
a = Maybe ResonFilter -> Patch a -> Sco (CsdNote D) -> Sco (Mix a)
go (ResonFilter -> Maybe ResonFilter
forall a. a -> Maybe a
Just ResonFilter
sk) Patch a
a Sco (CsdNote D)
sc

                scoSplitPatch :: Maybe SyntSkin -> Patch a -> D -> Patch a -> Sco (Mix a)
                scoSplitPatch :: Maybe ResonFilter -> Patch a -> D -> Patch a -> Sco (Mix a)
scoSplitPatch Maybe ResonFilter
maybeSkin Patch a
a D
dt Patch a
b = [Sco (Mix a)] -> Sco (Mix a)
forall a. Harmony a => [a] -> a
har [Maybe ResonFilter -> D -> Patch a -> Sco (Mix a)
leftSplit Maybe ResonFilter
maybeSkin D
dt Patch a
a, Maybe ResonFilter -> D -> Patch a -> Sco (Mix a)
rightSplit Maybe ResonFilter
maybeSkin D
dt Patch a
b]
                    where
                        leftSplit :: Maybe ResonFilter -> D -> Patch a -> Sco (Mix a)
leftSplit  Maybe ResonFilter
mSkin D
t = Maybe ResonFilter -> (D -> BoolD) -> Patch a -> Sco (Mix a)
onCondPlay Maybe ResonFilter
mSkin ( D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`lessThan` D
t)
                        rightSplit :: Maybe ResonFilter -> D -> Patch a -> Sco (Mix a)
rightSplit Maybe ResonFilter
mSkin D
t = Maybe ResonFilter -> (D -> BoolD) -> Patch a -> Sco (Mix a)
onCondPlay Maybe ResonFilter
mSkin ( D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`greaterThanEquals` D
t)

                        onCondPlay :: Maybe ResonFilter -> (D -> BoolD) -> Patch a -> Sco (Mix a)
onCondPlay Maybe ResonFilter
mSkin D -> BoolD
cond = \case
                            MonoSynt MonoSyntSpec
_spec GenMonoInstr a
_instr -> [Char] -> Sco (Mix a)
forall a. HasCallStack => [Char] -> a
error [Char]
"Split doesn't work for monophonic synths with Scores. Please use only polyphonic synths in this case."
                            PolySynt PolySyntSpec
_spec GenInstr D a
instr -> (CsdNote D -> SE a) -> Sco (CsdNote D) -> Sco (Mix a)
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Sco a -> Sco (Mix b)
sco ((D -> BoolD) -> (CsdNote D -> SE a) -> CsdNote D -> SE a
forall a.
Sigs a =>
(D -> BoolD) -> (CsdNote D -> SE a) -> CsdNote D -> SE a
restrictPolyInstr D -> BoolD
cond (GenInstr D a -> Maybe ResonFilter -> CsdNote D -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenInstr D a
instr Maybe ResonFilter
mSkin)) Sco (CsdNote D)
sc
                            SetSkin ResonFilter
sk Patch a
p -> Maybe ResonFilter -> (D -> BoolD) -> Patch a -> Sco (Mix a)
onCondPlay (ResonFilter -> Maybe ResonFilter
forall a. a -> Maybe a
Just ResonFilter
sk) D -> BoolD
cond Patch a
p
                            FxChain [GenFxSpec a]
fxs Patch a
p -> (a -> SE a) -> Sco (Mix a) -> Sco (Mix a)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Maybe ResonFilter -> [GenFxSpec a] -> a -> SE a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter -> [GenFxSpec a] -> Fx a
getPatchFx Maybe ResonFilter
mSkin [GenFxSpec a]
fxs) (Sco (Mix a) -> Sco (Mix a)) -> Sco (Mix a) -> Sco (Mix a)
forall a b. (a -> b) -> a -> b
$ Maybe ResonFilter -> Patch a -> Sco (CsdNote D) -> Sco (Mix a)
go Maybe ResonFilter
mSkin Patch a
p Sco (CsdNote D)
sc
                            LayerPatch [(DryWetRatio, Patch a)]
xs -> [Sco (Mix a)] -> Sco (Mix a)
forall a. Harmony a => [a] -> a
har ([Sco (Mix a)] -> Sco (Mix a)) -> [Sco (Mix a)] -> Sco (Mix a)
forall a b. (a -> b) -> a -> b
$ ((DryWetRatio, Patch a) -> Sco (Mix a))
-> [(DryWetRatio, Patch a)] -> [Sco (Mix a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(DryWetRatio
vol, Patch a
p) -> Maybe ResonFilter -> Patch a -> Sco (CsdNote D) -> Sco (Mix a)
go Maybe ResonFilter
mSkin (DryWetRatio -> Patch a -> Patch a
forall a. SigSpace a => DryWetRatio -> a -> a
mul DryWetRatio
vol Patch a
p) Sco (CsdNote D)
sc) [(DryWetRatio, Patch a)]
xs
                            SplitPatch Patch a
m D
t Patch a
n -> [Sco (Mix a)] -> Sco (Mix a)
forall a. Harmony a => [a] -> a
har
                                        [ Maybe ResonFilter -> (D -> BoolD) -> Patch a -> Sco (Mix a)
onCondPlay Maybe ResonFilter
mSkin (\D
q -> D -> BoolD
cond D
q BoolD -> BoolD -> BoolD
forall b. Boolean b => b -> b -> b
&&* (D
q D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`lessThan` D
t)) Patch a
m
                                        , Maybe ResonFilter -> (D -> BoolD) -> Patch a -> Sco (Mix a)
onCondPlay Maybe ResonFilter
mSkin (\D
q -> D -> BoolD
cond D
q BoolD -> BoolD -> BoolD
forall b. Boolean b => b -> b -> b
&&* (D
q D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`greaterThanEquals` D
t)) Patch a
n ]

onLayered :: (SigSpace a, Sigs a) => [(Sig, Patch a)] -> (Patch a -> SE a) -> SE a
onLayered :: [(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
onLayered [(DryWetRatio, Patch a)]
xs Patch a -> SE a
f = ([a] -> a) -> SE [a] -> SE a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (SE [a] -> SE a) -> SE [a] -> SE a
forall a b. (a -> b) -> a -> b
$ ((DryWetRatio, Patch a) -> SE a)
-> [(DryWetRatio, Patch a)] -> SE [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(DryWetRatio
vol, Patch a
p) -> (a -> a) -> SE a -> SE a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (DryWetRatio -> a -> a
forall a. SigSpace a => DryWetRatio -> a -> a
mul DryWetRatio
vol) (SE a -> SE a) -> SE a -> SE a
forall a b. (a -> b) -> a -> b
$ Patch a -> SE a
f Patch a
p) [(DryWetRatio, Patch a)]
xs

--    getPatchFx a =<< midi (patchInstr a . ampCps)

-- | Transform  the spec for monophonic patch.
onMonoSyntSpec :: (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
onMonoSyntSpec :: (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
onMonoSyntSpec MonoSyntSpec -> MonoSyntSpec
f Patch a
x = case Patch a
x of
    MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> MonoSyntSpec -> GenMonoInstr a -> Patch a
forall a. MonoSyntSpec -> GenMonoInstr a -> Patch a
MonoSynt (MonoSyntSpec -> MonoSyntSpec
f MonoSyntSpec
spec) GenMonoInstr a
instr
    PolySynt PolySyntSpec
spec GenInstr D a
instr -> PolySyntSpec -> GenInstr D a -> Patch a
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt PolySyntSpec
spec GenInstr D a
instr
    SetSkin ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> Patch a
forall a. ResonFilter -> Patch a -> Patch a
SetSkin ResonFilter
skin  (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
forall a. (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
onMonoSyntSpec MonoSyntSpec -> MonoSyntSpec
f Patch a
p
    FxChain [GenFxSpec a]
fxs Patch a
p -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain [GenFxSpec a]
fxs (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
forall a. (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
onMonoSyntSpec MonoSyntSpec -> MonoSyntSpec
f Patch a
p
    LayerPatch [(DryWetRatio, Patch a)]
xs -> [(DryWetRatio, Patch a)] -> Patch a
forall a. [(DryWetRatio, Patch a)] -> Patch a
LayerPatch ([(DryWetRatio, Patch a)] -> Patch a)
-> [(DryWetRatio, Patch a)] -> Patch a
forall a b. (a -> b) -> a -> b
$ (Patch a -> Patch a)
-> [(DryWetRatio, Patch a)] -> [(DryWetRatio, Patch a)]
forall a b c. (a -> b) -> [(c, a)] -> [(c, b)]
mapSnd ((MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
forall a. (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
onMonoSyntSpec MonoSyntSpec -> MonoSyntSpec
f) [(DryWetRatio, Patch a)]
xs
    SplitPatch Patch a
a D
cps Patch a
b -> Patch a -> D -> Patch a -> Patch a
forall a. Patch a -> D -> Patch a -> Patch a
SplitPatch ((MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
forall a. (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
onMonoSyntSpec MonoSyntSpec -> MonoSyntSpec
f Patch a
a) D
cps ((MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
forall a. (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
onMonoSyntSpec MonoSyntSpec -> MonoSyntSpec
f Patch a
b)

-- | Sets the midi channel for all instruments in the patch.
setMidiChn :: MidiChn -> Patch a -> Patch a
setMidiChn :: MidiChn -> Patch a -> Patch a
setMidiChn MidiChn
chn Patch a
x = case Patch a
x of
    MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> MonoSyntSpec -> GenMonoInstr a -> Patch a
forall a. MonoSyntSpec -> GenMonoInstr a -> Patch a
MonoSynt (MonoSyntSpec
spec { monoSyntChn :: MidiChn
monoSyntChn = MidiChn
chn }) GenMonoInstr a
instr
    PolySynt PolySyntSpec
spec GenInstr D a
instr -> PolySyntSpec -> GenInstr D a -> Patch a
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt (PolySyntSpec
spec { polySyntChn :: MidiChn
polySyntChn = MidiChn
chn }) GenInstr D a
instr
    SetSkin ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> Patch a
forall a. ResonFilter -> Patch a -> Patch a
SetSkin ResonFilter
skin (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ Patch a -> Patch a
forall a. Patch a -> Patch a
go Patch a
p
    FxChain [GenFxSpec a]
fxs Patch a
p -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain [GenFxSpec a]
fxs (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ Patch a -> Patch a
forall a. Patch a -> Patch a
go Patch a
p
    LayerPatch [(DryWetRatio, Patch a)]
xs -> [(DryWetRatio, Patch a)] -> Patch a
forall a. [(DryWetRatio, Patch a)] -> Patch a
LayerPatch ([(DryWetRatio, Patch a)] -> Patch a)
-> [(DryWetRatio, Patch a)] -> Patch a
forall a b. (a -> b) -> a -> b
$ (Patch a -> Patch a)
-> [(DryWetRatio, Patch a)] -> [(DryWetRatio, Patch a)]
forall a b c. (a -> b) -> [(c, a)] -> [(c, b)]
mapSnd Patch a -> Patch a
forall a. Patch a -> Patch a
go [(DryWetRatio, Patch a)]
xs
    SplitPatch Patch a
a D
cps Patch a
b -> Patch a -> D -> Patch a -> Patch a
forall a. Patch a -> D -> Patch a -> Patch a
SplitPatch (Patch a -> Patch a
forall a. Patch a -> Patch a
go Patch a
a) D
cps (Patch a -> Patch a
forall a. Patch a -> Patch a
go Patch a
b)
    where go :: Patch a -> Patch a
go = MidiChn -> Patch a -> Patch a
forall a. MidiChn -> Patch a -> Patch a
setMidiChn MidiChn
chn


-- | Sets the monophonic to sharp transition and quick release.
setMonoSharp :: Patch a -> Patch a
setMonoSharp :: Patch a -> Patch a
setMonoSharp = D -> Patch a -> Patch a
forall a. D -> Patch a -> Patch a
setMonoSlide D
0.004

-- | Sets the slide time for pitch and amplitude of monophomic synthesizers.
setMonoSlide :: D -> Patch a -> Patch a
setMonoSlide :: D -> Patch a -> Patch a
setMonoSlide D
slideTime = (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
forall a. (MonoSyntSpec -> MonoSyntSpec) -> Patch a -> Patch a
onMonoSyntSpec (\MonoSyntSpec
x -> MonoSyntSpec
x { monoSyntSlideTime :: Maybe D
monoSyntSlideTime = D -> Maybe D
forall a. a -> Maybe a
Just D
slideTime })

-- | Transpose the patch by a given ratio. We can use the functions semitone, cent to calculate the ratio.
transPatch :: D -> Patch a -> Patch a
transPatch :: D -> Patch a -> Patch a
transPatch D
k = (MonoInstr a -> MonoInstr a)
-> (Instr D a -> Instr D a) -> Patch a -> Patch a
forall a.
(MonoInstr a -> MonoInstr a)
-> (Instr D a -> Instr D a) -> Patch a -> Patch a
mapMonoPolyInstr (D -> MonoInstr a -> MonoInstr a
forall a. D -> MonoInstr a -> MonoInstr a
transMonoInstr D
k) (D -> Instr D a -> Instr D a
forall a. D -> Instr D a -> Instr D a
transPolyInstr D
k)

transMonoInstr :: D -> MonoInstr a -> MonoInstr a
transMonoInstr :: D -> MonoInstr a -> MonoInstr a
transMonoInstr D
k MonoInstr a
instr = \MonoArg
arg -> MonoInstr a
instr (MonoArg
arg { monoCps :: DryWetRatio
monoCps = D -> DryWetRatio
sig D
k DryWetRatio -> DryWetRatio -> DryWetRatio
forall a. Num a => a -> a -> a
* MonoArg -> DryWetRatio
monoCps MonoArg
arg })

transPolyInstr :: D -> Instr D a -> Instr D a
transPolyInstr :: D -> Instr D a -> Instr D a
transPolyInstr D
k Instr D a
instr = \(D
amp, D
cps) -> Instr D a
instr (D
amp, D
k D -> D -> D
forall a. Num a => a -> a -> a
* D
cps)

-- | Adds an effect to the patch's instrument.
addInstrFx :: Fx a -> Patch a -> Patch a
addInstrFx :: Fx a -> Patch a -> Patch a
addInstrFx Fx a
f Patch a
p = (Instr D a -> Instr D a) -> Patch a -> Patch a
forall a. (Instr D a -> Instr D a) -> Patch a -> Patch a
mapPatchInstr (\Instr D a
instr -> Fx a
f Fx a -> Instr D a -> Instr D a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Instr D a
instr) Patch a
p

-- | Appends an effect before patch's effect.
addPreFx :: DryWetRatio -> Fx a -> Patch a -> Patch a
addPreFx :: DryWetRatio -> Fx a -> Patch a -> Patch a
addPreFx DryWetRatio
dw Fx a
f Patch a
p = case Patch a
p of
    FxChain [GenFxSpec a]
fxs (PolySynt PolySyntSpec
spec GenInstr D a
instr) -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain ([GenFxSpec a] -> [GenFxSpec a]
addFx [GenFxSpec a]
fxs) (PolySyntSpec -> GenInstr D a -> Patch a
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt PolySyntSpec
spec GenInstr D a
instr)
    FxChain [GenFxSpec a]
fxs (MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr) -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain ([GenFxSpec a] -> [GenFxSpec a]
addFx [GenFxSpec a]
fxs) (MonoSyntSpec -> GenMonoInstr a -> Patch a
forall a. MonoSyntSpec -> GenMonoInstr a -> Patch a
MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr)
    SetSkin ResonFilter
skin Patch a
q -> ResonFilter -> Patch a -> Patch a
forall a. ResonFilter -> Patch a -> Patch a
SetSkin ResonFilter
skin (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPreFx DryWetRatio
dw Fx a
f Patch a
q
    PolySynt PolySyntSpec
spec GenInstr D a
instr -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain [GenFxSpec a]
fxSpec' (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ PolySyntSpec -> GenInstr D a -> Patch a
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt PolySyntSpec
spec GenInstr D a
instr
    MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain [GenFxSpec a]
fxSpec' (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ MonoSyntSpec -> GenMonoInstr a -> Patch a
forall a. MonoSyntSpec -> GenMonoInstr a -> Patch a
MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr
    LayerPatch [(DryWetRatio, Patch a)]
xs -> [(DryWetRatio, Patch a)] -> Patch a
forall a. [(DryWetRatio, Patch a)] -> Patch a
LayerPatch ([(DryWetRatio, Patch a)] -> Patch a)
-> [(DryWetRatio, Patch a)] -> Patch a
forall a b. (a -> b) -> a -> b
$ (Patch a -> Patch a)
-> [(DryWetRatio, Patch a)] -> [(DryWetRatio, Patch a)]
forall a b c. (a -> b) -> [(c, a)] -> [(c, b)]
mapSnd (DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPreFx DryWetRatio
dw Fx a
f) [(DryWetRatio, Patch a)]
xs
    SplitPatch Patch a
a D
cps Patch a
b -> Patch a -> D -> Patch a -> Patch a
forall a. Patch a -> D -> Patch a -> Patch a
SplitPatch (DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPreFx DryWetRatio
dw Fx a
f Patch a
a) D
cps (DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPreFx DryWetRatio
dw Fx a
f Patch a
b)
    Patch a
_ -> Patch a
forall a. HasCallStack => a
undefined
    where
        addFx :: [GenFxSpec a] -> [GenFxSpec a]
addFx [GenFxSpec a]
xs = [GenFxSpec a]
xs [GenFxSpec a] -> [GenFxSpec a] -> [GenFxSpec a]
forall a. [a] -> [a] -> [a]
++ [GenFxSpec a]
fxSpec'
        fxSpec' :: [GenFxSpec a]
fxSpec' = [FxSpec a -> GenFxSpec a
forall (m :: * -> *) a. Monad m => a -> m a
return (FxSpec a -> GenFxSpec a) -> FxSpec a -> GenFxSpec a
forall a b. (a -> b) -> a -> b
$ DryWetRatio -> Fx a -> FxSpec a
forall a. DryWetRatio -> Fx a -> FxSpec a
FxSpec DryWetRatio
dw Fx a
f]

-- | Appends an effect after patch's effect.
addPostFx :: DryWetRatio -> Fx a -> Patch a -> Patch a
addPostFx :: DryWetRatio -> Fx a -> Patch a -> Patch a
addPostFx DryWetRatio
dw Fx a
f Patch a
p = case Patch a
p of
    FxChain [GenFxSpec a]
fxs Patch a
rest -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain (FxSpec a -> GenFxSpec a
forall (m :: * -> *) a. Monad m => a -> m a
return FxSpec a
fxSpec' GenFxSpec a -> [GenFxSpec a] -> [GenFxSpec a]
forall a. a -> [a] -> [a]
: [GenFxSpec a]
fxs) Patch a
rest
    Patch a
_                -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain [FxSpec a -> GenFxSpec a
forall (m :: * -> *) a. Monad m => a -> m a
return FxSpec a
fxSpec'] Patch a
p
    where fxSpec' :: FxSpec a
fxSpec' = DryWetRatio -> Fx a -> FxSpec a
forall a. DryWetRatio -> Fx a -> FxSpec a
FxSpec DryWetRatio
dw Fx a
f

--------------------------------------------------------------

-- | Plays a patch when the condition signal is satisfied. Can be useful for switches.
patchWhen :: (Sigs a) => BoolSig -> Patch a -> Patch a
patchWhen :: BoolSig -> Patch a -> Patch a
patchWhen BoolSig
cond Patch a
x = case Patch a
x of
    MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> MonoSyntSpec -> GenMonoInstr a -> Patch a
forall a. MonoSyntSpec -> GenMonoInstr a -> Patch a
MonoSynt MonoSyntSpec
spec (((MonoArg -> SE a) -> MonoArg -> SE a)
-> GenMonoInstr a -> GenMonoInstr a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (BoolSig -> (MonoArg -> SE a) -> MonoArg -> SE a
forall a b. Sigs a => BoolSig -> (b -> SE a) -> b -> SE a
playWhen BoolSig
cond) GenMonoInstr a
instr)
    PolySynt PolySyntSpec
spec GenInstr D a
instr -> PolySyntSpec -> GenInstr D a -> Patch a
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt PolySyntSpec
spec (((CsdNote D -> SE a) -> CsdNote D -> SE a)
-> GenInstr D a -> GenInstr D a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (BoolSig -> (CsdNote D -> SE a) -> CsdNote D -> SE a
forall a b. Sigs a => BoolSig -> (b -> SE a) -> b -> SE a
playWhen BoolSig
cond) GenInstr D a
instr)
    SetSkin ResonFilter
skin Patch a
p -> ResonFilter -> Patch a -> Patch a
forall a. ResonFilter -> Patch a -> Patch a
SetSkin ResonFilter
skin (Patch a -> Patch a) -> Patch a -> Patch a
forall a b. (a -> b) -> a -> b
$ Patch a -> Patch a
rec Patch a
p
    FxChain  [GenFxSpec a]
fxs Patch a
p      -> [GenFxSpec a] -> Patch a -> Patch a
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain ((GenFxSpec a -> GenFxSpec a) -> [GenFxSpec a] -> [GenFxSpec a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((FxSpec a -> FxSpec a) -> GenFxSpec a -> GenFxSpec a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((FxSpec a -> FxSpec a) -> GenFxSpec a -> GenFxSpec a)
-> (FxSpec a -> FxSpec a) -> GenFxSpec a -> GenFxSpec a
forall a b. (a -> b) -> a -> b
$ (Fx a -> Fx a) -> FxSpec a -> FxSpec a
forall a a. (Fx a -> Fx a) -> FxSpec a -> FxSpec a
mapFun (BoolSig -> Fx a -> Fx a
forall a b. Sigs a => BoolSig -> (b -> SE a) -> b -> SE a
playWhen BoolSig
cond)) [GenFxSpec a]
fxs) (Patch a -> Patch a
rec Patch a
p)
    LayerPatch [(DryWetRatio, Patch a)]
xs       -> [(DryWetRatio, Patch a)] -> Patch a
forall a. [(DryWetRatio, Patch a)] -> Patch a
LayerPatch ([(DryWetRatio, Patch a)] -> Patch a)
-> [(DryWetRatio, Patch a)] -> Patch a
forall a b. (a -> b) -> a -> b
$ (Patch a -> Patch a)
-> [(DryWetRatio, Patch a)] -> [(DryWetRatio, Patch a)]
forall a b c. (a -> b) -> [(c, a)] -> [(c, b)]
mapSnd Patch a -> Patch a
rec [(DryWetRatio, Patch a)]
xs
    SplitPatch Patch a
a D
cps Patch a
b  -> Patch a -> D -> Patch a -> Patch a
forall a. Patch a -> D -> Patch a -> Patch a
SplitPatch (Patch a -> Patch a
rec Patch a
a) D
cps (Patch a -> Patch a
rec Patch a
b)
    where
        rec :: Patch a -> Patch a
rec = BoolSig -> Patch a -> Patch a
forall a. Sigs a => BoolSig -> Patch a -> Patch a
patchWhen BoolSig
cond
        mapFun :: (Fx a -> Fx a) -> FxSpec a -> FxSpec a
mapFun Fx a -> Fx a
f FxSpec a
a = FxSpec a
a { fxFun :: Fx a
fxFun = Fx a -> Fx a
f (Fx a -> Fx a) -> Fx a -> Fx a
forall a b. (a -> b) -> a -> b
$ FxSpec a -> Fx a
forall a. FxSpec a -> Fx a
fxFun FxSpec a
a }

-- | Mix two patches together.
mixInstr :: (SigSpace b, Num b) => Sig -> Patch b -> Patch b -> Patch b
mixInstr :: DryWetRatio -> Patch b -> Patch b -> Patch b
mixInstr DryWetRatio
k Patch b
f Patch b
p = [(DryWetRatio, Patch b)] -> Patch b
forall a. [(DryWetRatio, Patch a)] -> Patch a
LayerPatch [(DryWetRatio
k, Patch b
f), (DryWetRatio
1, Patch b
p)]

------------------------------------------------
-- pads

-- | Harmnoic series of patches.
harmonPatch :: (SigSpace b, Sigs b) => [Sig] -> [D] -> Patch b -> Patch b
harmonPatch :: [DryWetRatio] -> [D] -> Patch b -> Patch b
harmonPatch [DryWetRatio]
amps [D]
freqs = (MonoInstr b -> MonoInstr b)
-> ((CsdNote D -> SE b) -> CsdNote D -> SE b) -> Patch b -> Patch b
forall a.
(MonoInstr a -> MonoInstr a)
-> (Instr D a -> Instr D a) -> Patch a -> Patch a
tfmInstr MonoInstr b -> MonoInstr b
forall b. (Num b, SigSpace b) => MonoInstr b -> MonoInstr b
monoTfm (CsdNote D -> SE b) -> CsdNote D -> SE b
forall b. (Num b, SigSpace b) => Instr D b -> Instr D b
polyTfm
    where
        monoTfm :: MonoInstr b -> MonoInstr b
monoTfm MonoInstr b
instr = \MonoArg
arg -> ([b] -> b) -> SE [b] -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [b] -> b
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (SE [b] -> SE b) -> SE [b] -> SE b
forall a b. (a -> b) -> a -> b
$ (DryWetRatio -> D -> SE b) -> [DryWetRatio] -> [D] -> SE [b]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (\DryWetRatio
a D
f -> (b -> b) -> SE b -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (DryWetRatio -> b -> b
forall a. SigSpace a => DryWetRatio -> a -> a
mul DryWetRatio
a) (SE b -> SE b) -> SE b -> SE b
forall a b. (a -> b) -> a -> b
$ D -> MonoInstr b -> MonoInstr b
forall a. D -> MonoInstr a -> MonoInstr a
transMonoInstr D
f MonoInstr b
instr MonoArg
arg) [DryWetRatio]
amps [D]
freqs
        polyTfm :: Instr D b -> Instr D b
polyTfm Instr D b
instr = \CsdNote D
arg -> ([b] -> b) -> SE [b] -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [b] -> b
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (SE [b] -> SE b) -> SE [b] -> SE b
forall a b. (a -> b) -> a -> b
$ (DryWetRatio -> D -> SE b) -> [DryWetRatio] -> [D] -> SE [b]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (\DryWetRatio
a D
f -> (b -> b) -> SE b -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (DryWetRatio -> b -> b
forall a. SigSpace a => DryWetRatio -> a -> a
mul DryWetRatio
a) (SE b -> SE b) -> SE b -> SE b
forall a b. (a -> b) -> a -> b
$ D -> Instr D b -> Instr D b
forall a. D -> Instr D a -> Instr D a
transPolyInstr D
f Instr D b
instr CsdNote D
arg) [DryWetRatio]
amps [D]
freqs

-- | Adds an octave below note for a given patch to make the sound deeper.
deepPad :: (SigSpace b, Sigs b) => Patch b -> Patch b
deepPad :: Patch b -> Patch b
deepPad = [DryWetRatio] -> [D] -> Patch b -> Patch b
forall b.
(SigSpace b, Sigs b) =>
[DryWetRatio] -> [D] -> Patch b -> Patch b
harmonPatch ((DryWetRatio -> DryWetRatio) -> [DryWetRatio] -> [DryWetRatio]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (DryWetRatio -> DryWetRatio -> DryWetRatio
forall a. Num a => a -> a -> a
* DryWetRatio
0.75) [DryWetRatio
1, DryWetRatio
0.5]) [D
1, D
0.5]

-- | Transforms instrument functions for polyphonic and monophonic patches.
tfmInstr :: (MonoInstr b -> MonoInstr b) -> ((CsdNote D -> SE b) -> (CsdNote D -> SE b)) -> Patch b -> Patch b
tfmInstr :: (MonoInstr b -> MonoInstr b)
-> ((CsdNote D -> SE b) -> CsdNote D -> SE b) -> Patch b -> Patch b
tfmInstr MonoInstr b -> MonoInstr b
monoTfm (CsdNote D -> SE b) -> CsdNote D -> SE b
polyTfm Patch b
x = case Patch b
x of
    MonoSynt MonoSyntSpec
spec GenMonoInstr b
instr -> MonoSyntSpec -> GenMonoInstr b -> Patch b
forall a. MonoSyntSpec -> GenMonoInstr a -> Patch a
MonoSynt MonoSyntSpec
spec (GenMonoInstr b -> Patch b) -> GenMonoInstr b -> Patch b
forall a b. (a -> b) -> a -> b
$ (MonoInstr b -> MonoInstr b) -> GenMonoInstr b -> GenMonoInstr b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MonoInstr b -> MonoInstr b
monoTfm GenMonoInstr b
instr
    PolySynt PolySyntSpec
spec GenInstr D b
instr -> PolySyntSpec -> GenInstr D b -> Patch b
forall a. PolySyntSpec -> GenInstr D a -> Patch a
PolySynt PolySyntSpec
spec (GenInstr D b -> Patch b) -> GenInstr D b -> Patch b
forall a b. (a -> b) -> a -> b
$ ((CsdNote D -> SE b) -> CsdNote D -> SE b)
-> GenInstr D b -> GenInstr D b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (CsdNote D -> SE b) -> CsdNote D -> SE b
polyTfm GenInstr D b
instr
    SetSkin  ResonFilter
skin Patch b
p -> ResonFilter -> Patch b -> Patch b
forall a. ResonFilter -> Patch a -> Patch a
SetSkin ResonFilter
skin (Patch b -> Patch b) -> Patch b -> Patch b
forall a b. (a -> b) -> a -> b
$ Patch b -> Patch b
rec Patch b
p
    FxChain [GenFxSpec b]
fxs Patch b
p -> [GenFxSpec b] -> Patch b -> Patch b
forall a. [GenFxSpec a] -> Patch a -> Patch a
FxChain [GenFxSpec b]
fxs (Patch b -> Patch b) -> Patch b -> Patch b
forall a b. (a -> b) -> a -> b
$ Patch b -> Patch b
rec Patch b
p
    SplitPatch Patch b
a D
cps Patch b
b -> Patch b -> D -> Patch b -> Patch b
forall a. Patch a -> D -> Patch a -> Patch a
SplitPatch (Patch b -> Patch b
rec Patch b
a) D
cps (Patch b -> Patch b
rec Patch b
b)
    LayerPatch [(DryWetRatio, Patch b)]
xs -> [(DryWetRatio, Patch b)] -> Patch b
forall a. [(DryWetRatio, Patch a)] -> Patch a
LayerPatch ([(DryWetRatio, Patch b)] -> Patch b)
-> [(DryWetRatio, Patch b)] -> Patch b
forall a b. (a -> b) -> a -> b
$ ((DryWetRatio, Patch b) -> (DryWetRatio, Patch b))
-> [(DryWetRatio, Patch b)] -> [(DryWetRatio, Patch b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Patch b -> Patch b)
-> (DryWetRatio, Patch b) -> (DryWetRatio, Patch b)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Patch b -> Patch b
rec) [(DryWetRatio, Patch b)]
xs
    where
        rec :: Patch b -> Patch b
rec = (MonoInstr b -> MonoInstr b)
-> ((CsdNote D -> SE b) -> CsdNote D -> SE b) -> Patch b -> Patch b
forall a.
(MonoInstr a -> MonoInstr a)
-> (Instr D a -> Instr D a) -> Patch a -> Patch a
tfmInstr MonoInstr b -> MonoInstr b
monoTfm (CsdNote D -> SE b) -> CsdNote D -> SE b
polyTfm

------------------------------------------------
-- revers

withSmallRoom :: Patch2 -> Patch2
withSmallRoom :: Patch2 -> Patch2
withSmallRoom = DryWetRatio -> Patch2 -> Patch2
withSmallRoom' DryWetRatio
0.25

withSmallRoom' :: DryWetRatio -> Patch2 -> Patch2
withSmallRoom' :: DryWetRatio -> Patch2 -> Patch2
withSmallRoom' = ((DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio))
-> DryWetRatio -> Patch2 -> Patch2
withRever (DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio)
smallRoom2

withSmallHall :: Patch2 -> Patch2
withSmallHall :: Patch2 -> Patch2
withSmallHall = DryWetRatio -> Patch2 -> Patch2
withSmallHall' DryWetRatio
0.25

withSmallHall' :: DryWetRatio -> Patch2 -> Patch2
withSmallHall' :: DryWetRatio -> Patch2 -> Patch2
withSmallHall' = ((DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio))
-> DryWetRatio -> Patch2 -> Patch2
withRever (DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio)
smallHall2

withLargeHall :: Patch2 -> Patch2
withLargeHall :: Patch2 -> Patch2
withLargeHall = DryWetRatio -> Patch2 -> Patch2
withLargeHall' DryWetRatio
0.25

withLargeHall' :: DryWetRatio -> Patch2 -> Patch2
withLargeHall' :: DryWetRatio -> Patch2 -> Patch2
withLargeHall' = ((DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio))
-> DryWetRatio -> Patch2 -> Patch2
withRever (DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio)
largeHall2

withMagicCave :: Patch2 -> Patch2
withMagicCave :: Patch2 -> Patch2
withMagicCave = DryWetRatio -> Patch2 -> Patch2
withMagicCave' DryWetRatio
0.25

withMagicCave' :: DryWetRatio -> Patch2 -> Patch2
withMagicCave' :: DryWetRatio -> Patch2 -> Patch2
withMagicCave' = ((DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio))
-> DryWetRatio -> Patch2 -> Patch2
withRever (DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio)
magicCave2

withRever :: (Sig2 -> Sig2) -> DryWetRatio -> Patch2 -> Patch2
withRever :: ((DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio))
-> DryWetRatio -> Patch2 -> Patch2
withRever (DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio)
fx DryWetRatio
ratio Patch2
p = DryWetRatio -> Fx (DryWetRatio, DryWetRatio) -> Patch2 -> Patch2
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPostFx DryWetRatio
ratio (Fx (DryWetRatio, DryWetRatio)
forall (m :: * -> *) a. Monad m => a -> m a
return Fx (DryWetRatio, DryWetRatio)
-> ((DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio))
-> Fx (DryWetRatio, DryWetRatio)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio)
fx) Patch2
p

------------------------------------------------
-- sound font patch

-- | Sound font patch with a bit of reverb.
sfPatchHall :: Sf -> Patch2
sfPatchHall :: Sf -> Patch2
sfPatchHall = Patch2 -> Patch2
withSmallHall (Patch2 -> Patch2) -> (Sf -> Patch2) -> Sf -> Patch2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sf -> Patch2
sfPatch

-- | Sound font patch.
sfPatch :: Sf -> Patch2
sfPatch :: Sf -> Patch2
sfPatch Sf
sf = Instr D (DryWetRatio, DryWetRatio) -> Patch2
forall a. Instr D a -> Patch a
polySynt (Instr D (DryWetRatio, DryWetRatio) -> Patch2)
-> Instr D (DryWetRatio, DryWetRatio) -> Patch2
forall a b. (a -> b) -> a -> b
$ \(D
amp, D
cps) -> Fx (DryWetRatio, DryWetRatio)
forall (m :: * -> *) a. Monad m => a -> m a
return Fx (DryWetRatio, DryWetRatio) -> Fx (DryWetRatio, DryWetRatio)
forall a b. (a -> b) -> a -> b
$ Sf -> D -> D -> D -> (DryWetRatio, DryWetRatio)
sfCps Sf
sf D
0.5 D
amp D
cps

------------------------------------------------
-- Csound API


-- | Triggers patch with Csound API.
-- It creates a named instruement with given name (first argument).
--
-- It simulates the midi-like instrument. Notes are encoded with messages:
--
-- > i "givenName" 1 pitchKey volumeKey     -- note on
-- > i "givenName" 0 pitchKey volumeKey     -- note off
patchByNameMidi :: (SigSpace a, Sigs a) => String -> Patch a -> SE a
patchByNameMidi :: [Char] -> Patch a -> SE a
patchByNameMidi = (DryWetRatio -> DryWetRatio)
-> (D -> D) -> [Char] -> Patch a -> SE a
forall a.
(SigSpace a, Sigs a) =>
(DryWetRatio -> DryWetRatio)
-> (D -> D) -> [Char] -> Patch a -> SE a
genPatchByNameMidi DryWetRatio -> DryWetRatio
forall a. SigOrD a => a -> a
cpsmidinn D -> D
forall a. SigOrD a => a -> a
cpsmidinn

-- | Triggers patch with Csound API.
-- It creates a named instruement with given name (second argument).
-- It behaves like the function @patchByNameMidi@ but we can specify custom temperament.
patchByNameMidiTemp :: (SigSpace a, Sigs a) => Temp -> String -> Patch a -> SE a
patchByNameMidiTemp :: Temp -> [Char] -> Patch a -> SE a
patchByNameMidiTemp Temp
tm = (DryWetRatio -> DryWetRatio)
-> (D -> D) -> [Char] -> Patch a -> SE a
forall a.
(SigSpace a, Sigs a) =>
(DryWetRatio -> DryWetRatio)
-> (D -> D) -> [Char] -> Patch a -> SE a
genPatchByNameMidi (Temp -> DryWetRatio -> DryWetRatio
cpsmidi'Sig Temp
tm) (Temp -> D -> D
cpsmidi'D Temp
tm)

genPatchByNameMidi :: forall a . (SigSpace a, Sigs a) => (Sig -> Sig) -> (D -> D) -> String -> Patch a -> SE a
genPatchByNameMidi :: (DryWetRatio -> DryWetRatio)
-> (D -> D) -> [Char] -> Patch a -> SE a
genPatchByNameMidi DryWetRatio -> DryWetRatio
monoKey2cps D -> D
polyKey2cps [Char]
name Patch a
x = Maybe ResonFilter -> Patch a -> SE a
go Maybe ResonFilter
forall a. Maybe a
Nothing Patch a
x
    where
        go :: Maybe ResonFilter -> Patch a -> SE a
go Maybe ResonFilter
maybeSkin = \case
            MonoSynt MonoSyntSpec
spec GenMonoInstr a
instr -> MonoSyntSpec -> (MonoArg -> SE a) -> SE a
forall b. MonoSyntSpec -> (MonoArg -> SE b) -> SE b
monoSyntProc MonoSyntSpec
spec (GenMonoInstr a -> Maybe ResonFilter -> MonoArg -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenMonoInstr a
instr Maybe ResonFilter
maybeSkin)
            PolySynt PolySyntSpec
spec GenInstr D a
instr -> PolySyntSpec -> (CsdNote D -> SE a) -> SE a
forall p. p -> (CsdNote D -> SE a) -> SE a
polySyntProc PolySyntSpec
spec (GenInstr D a -> Maybe ResonFilter -> CsdNote D -> SE a
forall a. Reader ResonFilter a -> Maybe ResonFilter -> a
runSkin GenInstr D a
instr Maybe ResonFilter
maybeSkin)
            SetSkin ResonFilter
skin Patch a
p      -> ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin Patch a
p
            FxChain [GenFxSpec a]
fxs Patch a
p       -> Maybe ResonFilter -> [GenFxSpec a] -> Fx a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter -> [GenFxSpec a] -> Fx a
getPatchFx Maybe ResonFilter
maybeSkin [GenFxSpec a]
fxs Fx a -> SE a -> SE a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Patch a -> SE a
rec Patch a
p
            LayerPatch [(DryWetRatio, Patch a)]
xs       -> [(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
forall a.
(SigSpace a, Sigs a) =>
[(DryWetRatio, Patch a)] -> (Patch a -> SE a) -> SE a
onLayered [(DryWetRatio, Patch a)]
xs Patch a -> SE a
rec
            SplitPatch Patch a
a D
cps Patch a
b  -> Patch a -> D -> Patch a -> SE a
splitPatch Patch a
a D
cps Patch a
b
            where
                rec :: Patch a -> SE a
rec = Maybe ResonFilter -> Patch a -> SE a
go Maybe ResonFilter
maybeSkin
                newSkin :: ResonFilter -> Patch a -> SE a
newSkin ResonFilter
skin = Maybe ResonFilter -> Patch a -> SE a
go (ResonFilter -> Maybe ResonFilter
forall a. a -> Maybe a
Just ResonFilter
skin)

                monoSyntProc :: MonoSyntSpec -> (MonoArg -> SE b) -> SE b
monoSyntProc MonoSyntSpec
spec MonoArg -> SE b
instr = MonoArg -> SE b
instr (MonoArg -> SE b) -> SE MonoArg -> SE b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ((MonoArg -> MonoArg) -> SE MonoArg -> SE MonoArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (MonoSyntSpec -> MonoArg -> MonoArg
smoothMonoSpec MonoSyntSpec
spec (MonoArg -> MonoArg) -> (MonoArg -> MonoArg) -> MonoArg -> MonoArg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MonoArg -> MonoArg
convert) (SE MonoArg -> SE MonoArg) -> SE MonoArg -> SE MonoArg
forall a b. (a -> b) -> a -> b
$ [Char] -> SE MonoArg
trigNamedMono [Char]
name)
                    where
                        convert :: MonoArg -> MonoArg
convert MonoArg
a = MonoArg
a { monoAmp :: DryWetRatio
monoAmp = DryWetRatio -> DryWetRatio
vel2ampSig (MonoArg -> DryWetRatio
monoAmp MonoArg
a), monoCps :: DryWetRatio
monoCps = DryWetRatio -> DryWetRatio
monoKey2cps (MonoArg -> DryWetRatio
monoCps MonoArg
a) }

                polySyntProc :: p -> (CsdNote D -> SE a) -> SE a
polySyntProc p
_spec CsdNote D -> SE a
instr = [Char] -> ((D, D, Unit) -> SE a) -> SE a
forall a b.
(Arg a, Sigs b) =>
[Char] -> ((D, D, a) -> SE b) -> SE b
trigByNameMidi [Char]
name (D, D, Unit) -> SE a
proc
                    where
                        proc :: (D, D, Unit) -> SE a
                        proc :: (D, D, Unit) -> SE a
proc (D
pitch, D
vol, Unit
_) = CsdNote D -> SE a
instr (D -> D
vel2amp D
vol, D -> D
polyKey2cps D
pitch)

                splitPatch :: Patch a -> D -> Patch a -> SE a
splitPatch Patch a
a D
cps Patch a
b = Maybe ResonFilter
-> (MidiChn -> (D -> BoolD) -> (MonoArg -> SE a) -> SE a)
-> (MidiChn -> (CsdNote D -> SE a) -> SE a)
-> Patch a
-> D
-> Patch a
-> SE a
forall a.
(SigSpace a, Sigs a) =>
Maybe ResonFilter
-> (MidiChn -> (D -> BoolD) -> MonoInstr a -> SE a)
-> (MidiChn -> (CsdNote D -> SE a) -> SE a)
-> Patch a
-> D
-> Patch a
-> SE a
genSplitPatch Maybe ResonFilter
maybeSkin MidiChn -> (D -> BoolD) -> (MonoArg -> SE a) -> SE a
forall p b. MidiChn -> p -> (MonoArg -> SE b) -> SE b
playMonoInstr MidiChn -> (CsdNote D -> SE a) -> SE a
playInstr Patch a
a D
cps Patch a
b

                playMonoInstr :: MidiChn -> p -> (MonoArg -> SE b) -> SE b
playMonoInstr MidiChn
chn p
_cond MonoArg -> SE b
instr = MonoSyntSpec -> (MonoArg -> SE b) -> SE b
forall b. MonoSyntSpec -> (MonoArg -> SE b) -> SE b
monoSyntProc (MonoSyntSpec
forall a. Default a => a
def { monoSyntChn :: MidiChn
monoSyntChn = MidiChn
chn }) MonoArg -> SE b
instr
                playInstr :: MidiChn -> (CsdNote D -> SE a) -> SE a
playInstr MidiChn
chn CsdNote D -> SE a
instr = PolySyntSpec -> (CsdNote D -> SE a) -> SE a
forall p. p -> (CsdNote D -> SE a) -> SE a
polySyntProc (PolySyntSpec
forall a. Default a => a
def { polySyntChn :: MidiChn
polySyntChn = MidiChn
chn }) CsdNote D -> SE a
instr

vel2amp :: D -> D
vel2amp :: D -> D
vel2amp D
vol = ((D
vol D -> D -> D
forall a. Fractional a => a -> a -> a
/ D
64) D -> D -> D
forall a. Floating a => a -> a -> a
** D
2) D -> D -> D
forall a. Fractional a => a -> a -> a
/ D
2

vel2ampSig :: Sig -> Sig
vel2ampSig :: DryWetRatio -> DryWetRatio
vel2ampSig DryWetRatio
vol = ((DryWetRatio
vol DryWetRatio -> DryWetRatio -> DryWetRatio
forall a. Fractional a => a -> a -> a
/ DryWetRatio
64) DryWetRatio -> DryWetRatio -> DryWetRatio
forall a. Floating a => a -> a -> a
** DryWetRatio
2) DryWetRatio -> DryWetRatio -> DryWetRatio
forall a. Fractional a => a -> a -> a
/ DryWetRatio
2

{-

-- | Triggers patch with Csound API.
-- It creates a named instruement with given name (first argument).
--
-- It simulates the midi-like instrument. Notes are encoded with messages:
--
-- > i "givenName" 1 pitchKey volumeKey     -- note on
-- > i "givenName" 0 pitchKey volumeKey     -- note off
patchByNameMidi :: (SigSpace a, Sigs a) => String -> Patch D a -> SE a
patchByNameMidi = genPatchByNameMidi cpsmidinn

-- | Triggers patch with Csound API.
-- It creates a named instruement with given name (second argument).
-- It behaves like the function @patchByNameMidi@ but we can specify custom temperament.
patchByNameMidiTemp :: (SigSpace a, Sigs a) => Temp -> String -> Patch D a -> SE a
patchByNameMidiTemp tm = genPatchByNameMidi (cpsmidi'D tm)

-- | Wrapper for function @trigByNameMidi@.
genPatchByNameMidi :: forall a . (SigSpace a, Sigs a) => (D -> D) -> String -> Patch D a -> SE a
genPatchByNameMidi key2cps name p = getPatchFx p =<< trigByNameMidi name go
  where
    go :: (D, D, Unit) -> SE a
    go (pitch, vol, _) = patchInstr p (vel2amp vol, key2cps pitch)


-- | Triggers patch with Csound API.
-- It creates a named instruement with given name (first argument).
--
-- It simulates the midi-like instrument. Notes are encoded with messages:
--
-- > i "givenName" 1 pitchKey volumeKey     -- note on
-- > i "givenName" 0 pitchKey volumeKey     -- note off
--
-- It behaves just like the function @patchByNameMidi@ but it's defined for
-- monophonic patches. For instruments that take in continuous signals not messages/notes.
monoPatchByNameMidi :: (SigSpace a, Sigs a) => String -> Patch Sig a -> SE a
monoPatchByNameMidi name p = monoPatchByNameMidi' 0.01 0.1 name p

-- | Triggers patch with Csound API.
-- It creates a named instruement with given name (first argument).
-- It behaves like the function @monoPatchByNameMidi@ but we can specify custom temperament.
monoPatchByNameMidiTemp :: (SigSpace a, Sigs a) => Temp -> String -> Patch Sig a -> SE a
monoPatchByNameMidiTemp tm name p = monoPatchByNameMidiTemp' tm 0.01 0.1 name p

-- | The monophonic patch with sharper transition from note to note.
monoSharpPatchByNameMidi :: (SigSpace a, Sigs a) => String -> Patch Sig a -> SE a
monoSharpPatchByNameMidi name p = monoPatchByNameMidi' 0.005 0.05 name p

-- | The monophonic patch with sharper transition from note to note.
-- We can specify a custom temperament.
monoSharpPatchByNameMidiTemp :: (SigSpace a, Sigs a) => Temp -> String -> Patch Sig a -> SE a
monoSharpPatchByNameMidiTemp tm name p = monoPatchByNameMidiTemp' tm 0.005 0.05 name p

-- | Generic function fr invocation of monophonic instrument with Csound API.
-- We can specify portamento and release times.
monoPatchByNameMidi' :: (SigSpace a, Sigs a) => D -> D -> String -> Patch Sig a -> SE a
monoPatchByNameMidi' = genMonoPatchByNameMidi' cpsmidinn

-- | Generic function fr invocation of monophonic instrument with Csound API.
-- We can specify portamento and release times. Also we can specify a temperament.
monoPatchByNameMidiTemp' :: (SigSpace a, Sigs a) => Temp -> D -> D -> String -> Patch Sig a -> SE a
monoPatchByNameMidiTemp' tm = genMonoPatchByNameMidi' (cpsmidi'Sig tm)

-- | Wrapper for function @trigByNameMidi@ for mono synth.
genMonoPatchByNameMidi' :: forall a . (SigSpace a, Sigs a) => (Sig -> Sig) -> D -> D -> String -> Patch Sig a -> SE a
genMonoPatchByNameMidi' key2cps portTime relTime name p = getPatchFx p =<< patchInstr p =<< fmap convert (trigNamedMono portTime relTime name)
  where
    convert (vol, pch) = (vel2ampSig vol, key2cps pch)

vel2amp :: D -> D
vel2amp vol = ((vol / 64) ** 2) / 2

vel2ampSig :: Sig -> Sig
vel2ampSig vol = ((vol / 64) ** 2) / 2

-}


--------------------------------------------------
-- special functions to add effects

-- | Make an effect out of a pure function.
fxSig :: SigSpace a => (Sig -> Sig) -> GenFxSpec a
fxSig :: (DryWetRatio -> DryWetRatio) -> GenFxSpec a
fxSig DryWetRatio -> DryWetRatio
f = DryWetRatio -> Fx a -> GenFxSpec a
forall a. DryWetRatio -> Fx a -> GenFxSpec a
fxSpec DryWetRatio
1 (Fx a
forall (m :: * -> *) a. Monad m => a -> m a
return Fx a -> (a -> a) -> Fx a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DryWetRatio -> DryWetRatio) -> a -> a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f)

-- | Make an effect out of a pure function and specify dry/wet ratio.
fxSigMix :: SigSpace a => Sig -> (Sig -> Sig) -> GenFxSpec a
fxSigMix :: DryWetRatio -> (DryWetRatio -> DryWetRatio) -> GenFxSpec a
fxSigMix DryWetRatio
ratio DryWetRatio -> DryWetRatio
f = DryWetRatio -> Fx a -> GenFxSpec a
forall a. DryWetRatio -> Fx a -> GenFxSpec a
fxSpec DryWetRatio
ratio (Fx a
forall (m :: * -> *) a. Monad m => a -> m a
return Fx a -> (a -> a) -> Fx a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DryWetRatio -> DryWetRatio) -> a -> a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f)

-- | Make an effect out of a stereo pure function.
fxSig2 :: (Sig2 -> Sig2) -> GenFxSpec Sig2
fxSig2 :: ((DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio))
-> GenFxSpec (DryWetRatio, DryWetRatio)
fxSig2 (DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio)
f = DryWetRatio
-> Fx (DryWetRatio, DryWetRatio)
-> GenFxSpec (DryWetRatio, DryWetRatio)
forall a. DryWetRatio -> Fx a -> GenFxSpec a
fxSpec DryWetRatio
1 (Fx (DryWetRatio, DryWetRatio)
forall (m :: * -> *) a. Monad m => a -> m a
return Fx (DryWetRatio, DryWetRatio)
-> ((DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio))
-> Fx (DryWetRatio, DryWetRatio)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio)
f)

-- | Make an effect out of a stereo pure function and specify dry/wet ratio.
fxSigMix2 :: Sig -> (Sig2 -> Sig2) -> GenFxSpec Sig2
fxSigMix2 :: DryWetRatio
-> ((DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio))
-> GenFxSpec (DryWetRatio, DryWetRatio)
fxSigMix2 DryWetRatio
ratio (DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio)
f = DryWetRatio
-> Fx (DryWetRatio, DryWetRatio)
-> GenFxSpec (DryWetRatio, DryWetRatio)
forall a. DryWetRatio -> Fx a -> GenFxSpec a
fxSpec DryWetRatio
ratio (Fx (DryWetRatio, DryWetRatio)
forall (m :: * -> *) a. Monad m => a -> m a
return Fx (DryWetRatio, DryWetRatio)
-> ((DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio))
-> Fx (DryWetRatio, DryWetRatio)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DryWetRatio, DryWetRatio) -> (DryWetRatio, DryWetRatio)
f)


-- | Adds post fx with pure signal function.
mapFx :: SigSpace a => (Sig -> Sig) -> Patch a -> Patch a
mapFx :: (DryWetRatio -> DryWetRatio) -> Patch a -> Patch a
mapFx DryWetRatio -> DryWetRatio
f = DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPostFx DryWetRatio
1 (Fx a
forall (m :: * -> *) a. Monad m => a -> m a
return Fx a -> (a -> a) -> Fx a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DryWetRatio -> DryWetRatio) -> a -> a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f)

-- | Adds post fx with pure signal function and specifies dry/wet ratio.
mapFx' :: SigSpace a => Sig -> (Sig -> Sig) -> Patch a -> Patch a
mapFx' :: DryWetRatio -> (DryWetRatio -> DryWetRatio) -> Patch a -> Patch a
mapFx' DryWetRatio
rate DryWetRatio -> DryWetRatio
f = DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPostFx DryWetRatio
rate (Fx a
forall (m :: * -> *) a. Monad m => a -> m a
return Fx a -> (a -> a) -> Fx a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DryWetRatio -> DryWetRatio) -> a -> a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f)

-- | Adds post fx with effectful signal function.
bindFx :: BindSig a => (Sig -> SE Sig) -> Patch a -> Patch a
bindFx :: (DryWetRatio -> SE DryWetRatio) -> Patch a -> Patch a
bindFx DryWetRatio -> SE DryWetRatio
f = DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPostFx DryWetRatio
1 ((DryWetRatio -> SE DryWetRatio) -> Fx a
forall a. BindSig a => (DryWetRatio -> SE DryWetRatio) -> a -> SE a
bindSig DryWetRatio -> SE DryWetRatio
f)

-- | Adds post fx with effectful signal function and specifies dry/wet ratio.
bindFx' :: BindSig a => Sig -> (Sig -> SE Sig) -> Patch a -> Patch a
bindFx' :: DryWetRatio
-> (DryWetRatio -> SE DryWetRatio) -> Patch a -> Patch a
bindFx' DryWetRatio
rate DryWetRatio -> SE DryWetRatio
f = DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPostFx DryWetRatio
rate ((DryWetRatio -> SE DryWetRatio) -> Fx a
forall a. BindSig a => (DryWetRatio -> SE DryWetRatio) -> a -> SE a
bindSig DryWetRatio -> SE DryWetRatio
f)


-- | Adds pre fx with pure signal function.
mapPreFx :: SigSpace a => (Sig -> Sig) -> Patch a -> Patch a
mapPreFx :: (DryWetRatio -> DryWetRatio) -> Patch a -> Patch a
mapPreFx DryWetRatio -> DryWetRatio
f = DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPreFx DryWetRatio
1 (Fx a
forall (m :: * -> *) a. Monad m => a -> m a
return Fx a -> (a -> a) -> Fx a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DryWetRatio -> DryWetRatio) -> a -> a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f)

-- | Adds pre fx with pure signal function and specifies dry/wet ratio.
mapPreFx' :: SigSpace a => Sig -> (Sig -> Sig) -> Patch a -> Patch a
mapPreFx' :: DryWetRatio -> (DryWetRatio -> DryWetRatio) -> Patch a -> Patch a
mapPreFx' DryWetRatio
rate DryWetRatio -> DryWetRatio
f = DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPreFx DryWetRatio
rate (Fx a
forall (m :: * -> *) a. Monad m => a -> m a
return Fx a -> (a -> a) -> Fx a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DryWetRatio -> DryWetRatio) -> a -> a
forall a. SigSpace a => (DryWetRatio -> DryWetRatio) -> a -> a
mapSig DryWetRatio -> DryWetRatio
f)

-- | Adds pre fx with effectful signal function.
bindPreFx :: BindSig a => (Sig -> SE Sig) -> Patch a -> Patch a
bindPreFx :: (DryWetRatio -> SE DryWetRatio) -> Patch a -> Patch a
bindPreFx DryWetRatio -> SE DryWetRatio
f = DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPreFx DryWetRatio
1 ((DryWetRatio -> SE DryWetRatio) -> Fx a
forall a. BindSig a => (DryWetRatio -> SE DryWetRatio) -> a -> SE a
bindSig DryWetRatio -> SE DryWetRatio
f)

-- | Adds pre fx with effectful signal function and specifies dry/wet ratio.
bindPreFx' :: BindSig a => Sig -> (Sig -> SE Sig) -> Patch a -> Patch a
bindPreFx' :: DryWetRatio
-> (DryWetRatio -> SE DryWetRatio) -> Patch a -> Patch a
bindPreFx' DryWetRatio
rate DryWetRatio -> SE DryWetRatio
f = DryWetRatio -> Fx a -> Patch a -> Patch a
forall a. DryWetRatio -> Fx a -> Patch a -> Patch a
addPreFx DryWetRatio
rate ((DryWetRatio -> SE DryWetRatio) -> Fx a
forall a. BindSig a => (DryWetRatio -> SE DryWetRatio) -> a -> SE a
bindSig DryWetRatio -> SE DryWetRatio
f)

instance RenderCsd Patch1 where
    renderCsdBy :: Options -> Patch1 -> IO [Char]
renderCsdBy Options
opt Patch1
p = Options -> SE DryWetRatio -> IO [Char]
forall a. RenderCsd a => Options -> a -> IO [Char]
renderCsdBy Options
opt (Patch1 -> SE DryWetRatio
forall a. (SigSpace a, Sigs a) => Patch a -> SE a
atMidi Patch1
p)
    csdArity :: Patch1 -> CsdArity
csdArity Patch1
_ = Int -> Int -> CsdArity
CsdArity Int
0 Int
1

instance RenderCsd Patch2 where
    renderCsdBy :: Options -> Patch2 -> IO [Char]
renderCsdBy Options
opt Patch2
p = Options -> SE (DryWetRatio, DryWetRatio) -> IO [Char]
forall a. RenderCsd a => Options -> a -> IO [Char]
renderCsdBy Options
opt (Patch2 -> SE (DryWetRatio, DryWetRatio)
forall a. (SigSpace a, Sigs a) => Patch a -> SE a
atMidi Patch2
p)
    csdArity :: Patch2 -> CsdArity
csdArity Patch2
_ = Int -> Int -> CsdArity
CsdArity Int
0 Int
2