{-# Language
      FlexibleContexts,
      FlexibleInstances,
      ScopedTypeVariables,
      TypeSynonymInstances,
      CPP,
      MultiParamTypeClasses,
      TypeFamilies #-}
module Csound.Typed.Control.Mix(
    Mix,
    sco, eff, mix, mixBy, monoSco,
    sco_, mix_, mixBy_,
    Sco, CsdEventList, CsdEvent
) where

import Data.Boolean

import Control.Monad.IO.Class
import System.Mem.StableName

import Temporal.Media

import Csound.Dynamic hiding (Instr, Sco, str)

import Csound.Typed.Types
import Csound.Typed.Types.MixSco
import Csound.Typed.GlobalState hiding (notes)
import Csound.Typed.Control.Instr
import Csound.Typed.InnerOpcodes

#if __GLASGOW_HASKELL__ < 710
import Data.Traversable
#endif


{-
instance MixAt Sig (SE Sig) (Sco (Mix Sig2)) where
    type MixAtOut Sig (SE Sig) (Sco (Mix Sig2)) = Sco (Mix Sig2)
    at f = eff (at f)

instance MixAt Sig (SE Sig) (Sco (Mix Sig3)) where
    type MixAtOut Sig (SE Sig) (Sco (Mix Sig3)) = Sco (Mix Sig3)
    at f = eff (at f)

instance MixAt Sig (SE Sig) (Sco (Mix Sig4)) where
    type MixAtOut Sig (SE Sig) (Sco (Mix Sig4)) = Sco (Mix Sig4)
    at f = eff (at f)
-}
toCsdEventList :: Sco a -> CsdEventList a
toCsdEventList :: Sco a -> Sco a
toCsdEventList = Sco a -> Sco a
forall a. a -> a
id

singleCsdEvent :: (Sig, Sig, a) -> Sco a
singleCsdEvent :: (Sig, Sig, a) -> Sco a
singleCsdEvent (Sig
start, Sig
duration, a
content) = DurOf (Sco a) -> Sco a -> Sco a
forall a. Delay a => DurOf a -> a -> a
del DurOf (Sco a)
Sig
start (Sco a -> Sco a) -> Sco a -> Sco a
forall a b. (a -> b) -> a -> b
$ DurOf (Sco a) -> Sco a -> Sco a
forall a. Stretch a => DurOf a -> a -> a
str DurOf (Sco a)
Sig
duration (Sco a -> Sco a) -> Sco a -> Sco a
forall a b. (a -> b) -> a -> b
$ a -> Sco a
forall t a. Num t => a -> Track t a
temp a
content

-- | Special type that represents a scores of sound signals.
-- If an instrument is triggered with the scores the result is wrapped
-- in the value of this type.
newtype Mix a = Mix { Mix a -> GE M
unMix :: GE M }

type Sco a = Track Sig a

wrapSco :: Sco a -> (CsdEventList a -> GE M) -> Sco (Mix b)
wrapSco :: Sco a -> (Sco a -> GE M) -> Sco (Mix b)
wrapSco Sco a
notes Sco a -> GE M
getContent = (Sig, Sig, Mix b) -> Sco (Mix b)
forall a. (Sig, Sig, a) -> Sco a
singleCsdEvent (Sig
0, Sco a -> Sig
forall a. CsdEventList a -> Sig
csdEventListDur Sco a
evts, GE M -> Mix b
forall a. GE M -> Mix a
Mix (GE M -> Mix b) -> GE M -> Mix b
forall a b. (a -> b) -> a -> b
$ Sco a -> GE M
getContent Sco a
evts)
    where evts :: Sco a
evts = Sco a -> Sco a
forall a. Sco a -> Sco a
toCsdEventList Sco a
notes

-- | Plays a bunch of notes with the given instrument.
--
-- > res = sco instrument scores
sco :: (Arg a, Sigs b) => (a -> SE b) -> Sco a -> Sco (Mix b)
sco :: (a -> SE b) -> Sco a -> Sco (Mix b)
sco a -> SE b
instr Sco a
notes = Sco a -> (Sco a -> GE M) -> Sco (Mix b)
forall a b. Sco a -> (Sco a -> GE M) -> Sco (Mix b)
wrapSco Sco a
notes ((Sco a -> GE M) -> Sco (Mix b)) -> (Sco a -> GE M) -> Sco (Mix b)
forall a b. (a -> b) -> a -> b
$ \Sco a
events -> do
    Track Sig [E]
events' <- (a -> GE [E]) -> Sco a -> GE (Track Sig [E])
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> GE [E]
forall a. Arg a => a -> GE [E]
toNote Sco a
events
    InstrId
instrId <- Arity -> InsExp -> GE InstrId
saveSourceInstrCachedWithLivenessWatch ((a -> SE b) -> Arity
forall a b. (Tuple a, Tuple b) => (a -> SE b) -> Arity
funArity a -> SE b
instr) ((a -> SE b) -> InsExp
forall a b. (Arg a, Tuple b) => (a -> SE b) -> InsExp
insExp a -> SE b
instr)
    M -> GE M
forall (m :: * -> *) a. Monad m => a -> m a
return (M -> GE M) -> M -> GE M
forall a b. (a -> b) -> a -> b
$ InstrId -> Track Sig [E] -> M
Snd InstrId
instrId Track Sig [E]
events'

-- | Invokes a procedure for the given bunch of events.
sco_ :: (Arg a) => (a -> SE ()) -> Sco a -> Sco (Mix Unit)
sco_ :: (a -> SE ()) -> Sco a -> Sco (Mix Unit)
sco_ a -> SE ()
instr Sco a
notes = Sco a -> (Sco a -> GE M) -> Sco (Mix Unit)
forall a b. Sco a -> (Sco a -> GE M) -> Sco (Mix b)
wrapSco Sco a
notes ((Sco a -> GE M) -> Sco (Mix Unit))
-> (Sco a -> GE M) -> Sco (Mix Unit)
forall a b. (a -> b) -> a -> b
$ \Sco a
events -> do
    Track Sig [E]
events' <- (a -> GE [E]) -> Sco a -> GE (Track Sig [E])
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> GE [E]
forall a. Arg a => a -> GE [E]
toNote Sco a
events
    InstrId
instrId <- SE () -> GE InstrId
saveSourceInstrCached_ (SE Unit -> SE ()
unitExp (SE Unit -> SE ()) -> SE Unit -> SE ()
forall a b. (a -> b) -> a -> b
$ (() -> Unit) -> SE () -> SE Unit
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Unit -> () -> Unit
forall a b. a -> b -> a
const Unit
unit) (SE () -> SE Unit) -> SE () -> SE Unit
forall a b. (a -> b) -> a -> b
$ a -> SE ()
instr a
forall a. Arg a => a
toArg)
    M -> GE M
forall (m :: * -> *) a. Monad m => a -> m a
return (M -> GE M) -> M -> GE M
forall a b. (a -> b) -> a -> b
$ InstrId -> Track Sig [E] -> M
Snd InstrId
instrId Track Sig [E]
events'

-- | Applies an effect to the sound. Effect is applied to the sound on the give track.
--
-- > res = eff effect sco
--
-- * @effect@ - a function that takes a tuple of signals and produces
--   a tuple of signals.
--
-- * @sco@ - something that is constructed with 'Csound.Base.sco' or
--   'Csound.Base.eff'.
--
-- With the function 'Csound.Base.eff' you can apply a reverb or adjust the
-- level of the signal. It functions like a mixing board but unlike mixing
-- board it produces the value that you can arrange with functions from your
-- favorite Score-generation library. You can delay it or mix with some other track and
-- apply some another effect on top of it!
eff :: (Sigs a, Sigs b) => (a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff :: (a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff a -> SE b
ef Sco (Mix a)
sigs = Sco (Mix a) -> (Sco (Mix a) -> GE M) -> Sco (Mix b)
forall a b. Sco a -> (Sco a -> GE M) -> Sco (Mix b)
wrapSco Sco (Mix a)
sigs ((Sco (Mix a) -> GE M) -> Sco (Mix b))
-> (Sco (Mix a) -> GE M) -> Sco (Mix b)
forall a b. (a -> b) -> a -> b
$ \Sco (Mix a)
events -> do
    Track Sig M
notes <- (Mix a -> GE M) -> Sco (Mix a) -> GE (Track Sig M)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Mix a -> GE M
forall a. Mix a -> GE M
unMix Sco (Mix a)
events
    InstrId
instrId <- Arity -> EffExp -> GE InstrId
saveEffectInstr ((a -> SE b) -> Arity
forall a b. (Tuple a, Tuple b) => (a -> SE b) -> Arity
funArity a -> SE b
ef) ((a -> SE b) -> EffExp
forall a b. (Tuple a, Tuple b) => (a -> SE b) -> EffExp
effExp a -> SE b
ef)
    M -> GE M
forall (m :: * -> *) a. Monad m => a -> m a
return (M -> GE M) -> M -> GE M
forall a b. (a -> b) -> a -> b
$ InstrId -> Track Sig M -> Int -> M
Eff InstrId
instrId Track Sig M
notes (Arity -> Int
arityIns (Arity -> Int) -> Arity -> Int
forall a b. (a -> b) -> a -> b
$ (a -> SE b) -> Arity
forall a b. (Tuple a, Tuple b) => (a -> SE b) -> Arity
funArity a -> SE b
ef)

-- | Plays a bunch of notes with the given monophonic instrument. See details on type @MonoArg@.
-- The scores contain the pairs of amplitude (0 to 1) and frequency (in Hz).
--
-- > res = monoSco instrument scores
monoSco :: forall a . Sigs a => (MonoArg -> SE a) -> Sco (D, D) -> Sco (Mix a)
monoSco :: (MonoArg -> SE a) -> Sco (D, D) -> Sco (Mix a)
monoSco MonoArg -> SE a
instr Sco (D, D)
notes = Sco (D, D) -> (Sco (D, D) -> GE M) -> Sco (Mix a)
forall a b. Sco a -> (Sco a -> GE M) -> Sco (Mix b)
wrapSco Sco (D, D)
notes ((Sco (D, D) -> GE M) -> Sco (Mix a))
-> (Sco (D, D) -> GE M) -> Sco (Mix a)
forall a b. (a -> b) -> a -> b
$ \Sco (D, D)
events -> do
    Track Sig [E]
events' <- ((D, D) -> GE [E]) -> Sco (D, D) -> GE (Track Sig [E])
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (D, D) -> GE [E]
forall a. Arg a => a -> GE [E]
toNote Sco (D, D)
events
    InstrId
argId <- SE () -> GE InstrId
saveSourceInstrCached_ (SE Unit -> SE ()
unitExp (SE Unit -> SE ()) -> SE Unit -> SE ()
forall a b. (a -> b) -> a -> b
$ (() -> Unit) -> SE () -> SE Unit
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Unit -> () -> Unit
forall a b. a -> b -> a
const Unit
unit) (SE () -> SE Unit) -> SE () -> SE Unit
forall a b. (a -> b) -> a -> b
$ ((D, D), Port Sig3) -> SE ()
instrMonoArg ((D, D), Port Sig3)
forall a. Arg a => a
toArg)
    InstrId
instrId <- Arity -> EffExp -> GE InstrId
saveEffectInstr (((MonoArg -> SE a) -> Arity
forall a b. (Tuple a, Tuple b) => (a -> SE b) -> Arity
funArity MonoArg -> SE a
instr) { arityIns :: Int
arityIns = Int
3 }) ((Sig3 -> SE a) -> EffExp
forall a b. (Tuple a, Tuple b) => (a -> SE b) -> EffExp
effExp Sig3 -> SE a
Sigs a => Sig3 -> SE a
effInstr)
    M -> GE M
forall (m :: * -> *) a. Monad m => a -> m a
return (M -> GE M) -> M -> GE M
forall a b. (a -> b) -> a -> b
$ InstrId -> InstrId -> Track Sig [E] -> M
MonoSnd InstrId
instrId InstrId
argId Track Sig [E]
events'
    where
        instrMonoArg :: ((D, D), Port Sig3) -> SE ()
        instrMonoArg :: ((D, D), Port Sig3) -> SE ()
instrMonoArg ((D
amp, D
cps), Port Sig3
port) =
            Port Sig3 -> (Sig3 -> Sig3) -> SE ()
forall a (port :: * -> *).
(Sigs a, IsPort port) =>
port a -> (a -> a) -> SE ()
modifyPort Port Sig3
port ((Sig3 -> Sig3) -> SE ()) -> (Sig3 -> Sig3) -> SE ()
forall a b. (a -> b) -> a -> b
$ \(Sig
_, Sig
_, Sig
notnum) -> (D -> Sig
sig D
amp, D -> Sig
sig D
cps, Sig
notnum Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
+ Sig
1)

        effInstr :: Sigs a => (Sig, Sig, Sig) -> SE a
        effInstr :: Sig3 -> SE a
effInstr (Sig
amp, Sig
cps, Sig
notnum) = MonoArg -> SE a
instr (Sig -> Sig -> Sig -> Sig -> MonoArg
MonoArg Sig
amp Sig
cps Sig
gate ([Sig] -> Sig
changed [Sig
amp, Sig
cps, Sig
gate]))
            where gate :: Sig
gate = BoolSig -> Sig -> Sig -> Sig
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (Sig
notnum Sig -> Sig -> BoolSig
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
0) Sig
0 Sig
1

-- | Renders a scores to the sound signals. we can use it inside the other instruments.
mix :: (Sigs a) => Sco (Mix a) -> a
mix :: Sco (Mix a) -> a
mix Sco (Mix a)
a = (GE InstrId -> Unit -> a) -> Unit -> GE InstrId -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip GE InstrId -> Unit -> a
forall a b. (Arg a, Sigs b) => GE InstrId -> a -> b
apInstr Unit
unit (GE InstrId -> a) -> GE InstrId -> a
forall a b. (a -> b) -> a -> b
$ do
    MixKey
key <- Sco (Mix a) -> GE MixKey
forall a. a -> GE MixKey
mixKey Sco (Mix a)
a
    E
durE <- Sig -> GE E
forall a. Val a => a -> GE E
toGE (Sig -> GE E) -> Sig -> GE E
forall a b. (a -> b) -> a -> b
$ Sco (Mix a) -> DurOf (Sco (Mix a))
forall a. Duration a => a -> DurOf a
dur Sco (Mix a)
a
    TotalDur
-> GetCache MixKey InstrId
-> SetCache MixKey InstrId
-> MixKey
-> GE InstrId
-> GE InstrId
forall key val.
TotalDur
-> GetCache key val -> SetCache key val -> key -> GE val -> GE val
withCache (E -> TotalDur
ExpDur E
durE) GetCache MixKey InstrId
forall (m :: * -> *). GetKey m MixKey InstrId
getMixKey SetCache MixKey InstrId
forall (m :: * -> *). SaveKey m MixKey InstrId
saveMixKey MixKey
key (GE InstrId -> GE InstrId) -> GE InstrId -> GE InstrId
forall a b. (a -> b) -> a -> b
$
        Int -> Track Sig M -> GE InstrId
saveMixInstr (Sco (Mix a) -> Int
forall b (f :: * -> *). Sigs b => f (Mix b) -> Int
mixArity Sco (Mix a)
a) (Track Sig M -> GE InstrId) -> GE (Track Sig M) -> GE InstrId
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Sco (Mix a) -> GE (Track Sig M)
forall a. Sco (Mix a) -> GE (Track Sig M)
toEventList Sco (Mix a)
a'
    where a' :: Sco (Mix a)
a' = Sco (Mix a) -> Sco (Mix a)
forall a. Sco a -> Sco a
toCsdEventList Sco (Mix a)
a

-- | Imitates a closure for a bunch of notes to be played within another instrument.
mixBy :: (Arg a, Sigs b) => (a -> Sco (Mix b)) -> (a -> b)
mixBy :: (a -> Sco (Mix b)) -> a -> b
mixBy a -> Sco (Mix b)
evts a
args = (GE InstrId -> a -> b) -> a -> GE InstrId -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip GE InstrId -> a -> b
forall a b. (Arg a, Sigs b) => GE InstrId -> a -> b
apInstr a
args (GE InstrId -> b) -> GE InstrId -> b
forall a b. (a -> b) -> a -> b
$ do
    MixKey
key <- (a -> Sco (Mix b)) -> GE MixKey
forall a. a -> GE MixKey
mixKey a -> Sco (Mix b)
evts
    E
durE <- Sig -> GE E
forall a. Val a => a -> GE E
toGE (Sig -> GE E) -> Sig -> GE E
forall a b. (a -> b) -> a -> b
$ Sco (Mix b) -> DurOf (Sco (Mix b))
forall a. Duration a => a -> DurOf a
dur Sco (Mix b)
evts'
    TotalDur
-> GetCache MixKey InstrId
-> SetCache MixKey InstrId
-> MixKey
-> GE InstrId
-> GE InstrId
forall key val.
TotalDur
-> GetCache key val -> SetCache key val -> key -> GE val -> GE val
withCache (E -> TotalDur
ExpDur E
durE) GetCache MixKey InstrId
forall (m :: * -> *). GetKey m MixKey InstrId
getMixKey SetCache MixKey InstrId
forall (m :: * -> *). SaveKey m MixKey InstrId
saveMixKey MixKey
key (GE InstrId -> GE InstrId) -> GE InstrId -> GE InstrId
forall a b. (a -> b) -> a -> b
$
        Int -> Track Sig M -> GE InstrId
saveMixInstr ((a -> Sco (Mix b)) -> Int
forall b a (f :: * -> *). Sigs b => (a -> f (Mix b)) -> Int
mixArityFun a -> Sco (Mix b)
evts) (Track Sig M -> GE InstrId) -> GE (Track Sig M) -> GE InstrId
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Sco (Mix b) -> GE (Track Sig M)
forall a. Sco (Mix a) -> GE (Track Sig M)
toEventList Sco (Mix b)
evts')
    where evts' :: Sco (Mix b)
evts' = Sco (Mix b) -> Sco (Mix b)
forall a. Sco a -> Sco a
toCsdEventList (Sco (Mix b) -> Sco (Mix b)) -> Sco (Mix b) -> Sco (Mix b)
forall a b. (a -> b) -> a -> b
$ a -> Sco (Mix b)
evts a
forall a. Arg a => a
toArg

-- | Converts a bunch of procedures scheduled with scores to a single procedure.
mix_ :: Sco (Mix Unit) -> SE ()
mix_ :: Sco (Mix Unit) -> SE ()
mix_ Sco (Mix Unit)
a = Dep () -> SE ()
fromDep_ (Dep () -> SE ()) -> Dep () -> SE ()
forall a b. (a -> b) -> a -> b
$ GE (Dep ()) -> Dep ()
forall a. GE (Dep a) -> Dep a
hideGEinDep (GE (Dep ()) -> Dep ()) -> GE (Dep ()) -> Dep ()
forall a b. (a -> b) -> a -> b
$ do
    MixKey
key <- Sco (Mix Unit) -> GE MixKey
forall a. a -> GE MixKey
mixKey Sco (Mix Unit)
a
    E
durE <- Sig -> GE E
forall a. Val a => a -> GE E
toGE (Sig -> GE E) -> Sig -> GE E
forall a b. (a -> b) -> a -> b
$ Sco (Mix Unit) -> DurOf (Sco (Mix Unit))
forall a. Duration a => a -> DurOf a
dur Sco (Mix Unit)
a
    TotalDur
-> GetCache MixKey (Dep ())
-> SetCache MixKey (Dep ())
-> MixKey
-> GE (Dep ())
-> GE (Dep ())
forall key val.
TotalDur
-> GetCache key val -> SetCache key val -> key -> GE val -> GE val
withCache (E -> TotalDur
ExpDur E
durE) GetCache MixKey (Dep ())
forall (m :: * -> *). GetKey m MixKey (DepT m ())
getMixProcKey SetCache MixKey (Dep ())
forall (m :: * -> *). SaveKey m MixKey (DepT m ())
saveMixProcKey MixKey
key (GE (Dep ()) -> GE (Dep ())) -> GE (Dep ()) -> GE (Dep ())
forall a b. (a -> b) -> a -> b
$
        Track Sig M -> GE (Dep ())
saveMixInstr_ (Track Sig M -> GE (Dep ())) -> GE (Track Sig M) -> GE (Dep ())
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Sco (Mix Unit) -> GE (Track Sig M)
forall a. Sco (Mix a) -> GE (Track Sig M)
toEventList Sco (Mix Unit)
a'
    where a' :: Sco (Mix Unit)
a' = Sco (Mix Unit) -> Sco (Mix Unit)
forall a. Sco a -> Sco a
toCsdEventList Sco (Mix Unit)
a

-- | Imitates a closure for a bunch of procedures to be played within another instrument.
mixBy_ :: (Arg a) => (a -> Sco (Mix Unit)) -> (a -> SE ())
mixBy_ :: (a -> Sco (Mix Unit)) -> a -> SE ()
mixBy_ a -> Sco (Mix Unit)
evts a
args = Sco (Mix Unit) -> SE ()
mix_ (Sco (Mix Unit) -> SE ()) -> Sco (Mix Unit) -> SE ()
forall a b. (a -> b) -> a -> b
$ a -> Sco (Mix Unit)
evts a
args

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

mixKey :: a -> GE MixKey
mixKey :: a -> GE MixKey
mixKey = IO MixKey -> GE MixKey
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO MixKey -> GE MixKey) -> (a -> IO MixKey) -> a -> GE MixKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StableName a -> MixKey) -> IO (StableName a) -> IO MixKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> MixKey
MixKey (Int -> MixKey) -> (StableName a -> Int) -> StableName a -> MixKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StableName a -> Int
forall a. StableName a -> Int
hashStableName) (IO (StableName a) -> IO MixKey)
-> (a -> IO (StableName a)) -> a -> IO MixKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO (StableName a)
forall a. a -> IO (StableName a)
makeStableName

toEventList :: Sco (Mix a) -> GE (CsdEventList M)
toEventList :: Sco (Mix a) -> GE (Track Sig M)
toEventList Sco (Mix a)
evts = (Track Sig M -> Track Sig M)
-> GE (Track Sig M) -> GE (Track Sig M)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Track Sig M -> Track Sig M
delayAndRescaleCsdEventListM (GE (Track Sig M) -> GE (Track Sig M))
-> GE (Track Sig M) -> GE (Track Sig M)
forall a b. (a -> b) -> a -> b
$ (Mix a -> GE M) -> Sco (Mix a) -> GE (Track Sig M)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Mix a -> GE M
forall a. Mix a -> GE M
unMix (Sco (Mix a) -> GE (Track Sig M))
-> Sco (Mix a) -> GE (Track Sig M)
forall a b. (a -> b) -> a -> b
$ Sco (Mix a)
evts

mixArity :: Sigs b => f (Mix b) -> Int
mixArity :: f (Mix b) -> Int
mixArity = b -> Int
forall a. Tuple a => a -> Int
tupleArity (b -> Int) -> (f (Mix b) -> b) -> f (Mix b) -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f (Mix b) -> b
forall (f :: * -> *) b. f (Mix b) -> b
proxy
    where
        proxy :: f (Mix b) -> b
        proxy :: f (Mix b) -> b
proxy = b -> f (Mix b) -> b
forall a b. a -> b -> a
const b
forall a. HasCallStack => a
undefined

mixArityFun :: Sigs b => (a -> f (Mix b)) -> Int
mixArityFun :: (a -> f (Mix b)) -> Int
mixArityFun = b -> Int
forall a. Tuple a => a -> Int
tupleArity (b -> Int) -> ((a -> f (Mix b)) -> b) -> (a -> f (Mix b)) -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> f (Mix b)) -> b
forall a (f :: * -> *) b. (a -> f (Mix b)) -> b
proxy
    where
        proxy :: (a -> f (Mix b)) -> b
        proxy :: (a -> f (Mix b)) -> b
proxy = b -> (a -> f (Mix b)) -> b
forall a b. a -> b -> a
const b
forall a. HasCallStack => a
undefined

-----------------------------------------------------------
-- instances

instance (Sigs a, SigSpace a) => SigSpace (Sco (Mix a)) where
  mapSig :: (Sig -> Sig) -> Sco (Mix a) -> Sco (Mix a)
mapSig Sig -> Sig
f = (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 (a -> SE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> SE a) -> (a -> a) -> a -> SE a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sig -> Sig) -> a -> a
forall a. SigSpace a => (Sig -> Sig) -> a -> a
mapSig Sig -> Sig
f)

instance (Sigs a, SigSpace2 a) => SigSpace2 (Sco (Mix a)) where
  mapSig2 :: (Sig2 -> Sig2) -> Sco (Mix a) -> Sco (Mix a)
mapSig2 Sig2 -> Sig2
f = (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 (a -> SE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> SE a) -> (a -> a) -> a -> SE a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sig2 -> Sig2) -> a -> a
forall a. SigSpace2 a => (Sig2 -> Sig2) -> a -> a
mapSig2 Sig2 -> Sig2
f)

instance At Sig (SE Sig) (Sco (Mix Sig)) where
    type AtOut Sig (SE Sig) (Sco (Mix Sig)) = Sco (Mix Sig)
    at :: (Sig -> SE Sig)
-> Sco (Mix Sig) -> AtOut Sig (SE Sig) (Sco (Mix Sig))
at Sig -> SE Sig
f = (Sig -> SE Sig) -> Sco (Mix Sig) -> Sco (Mix Sig)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff Sig -> SE Sig
f

instance At Sig (SE Sig) (Sco (Mix Sig2)) where
    type AtOut Sig (SE Sig) (Sco (Mix Sig2)) = Sco (Mix Sig2)
    at :: (Sig -> SE Sig)
-> Sco (Mix Sig2) -> AtOut Sig (SE Sig) (Sco (Mix Sig2))
at Sig -> SE Sig
f = (Sig2 -> SE Sig2) -> Sco (Mix Sig2) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff ((Sig -> SE Sig) -> Sig2 -> AtOut Sig (SE Sig) Sig2
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig -> SE Sig
f)

instance At Sig (SE Sig) (Sco (Mix Sig3)) where
    type AtOut Sig (SE Sig) (Sco (Mix Sig3)) = Sco (Mix Sig3)
    at :: (Sig -> SE Sig)
-> Sco (Mix Sig3) -> AtOut Sig (SE Sig) (Sco (Mix Sig3))
at Sig -> SE Sig
f = (Sig3 -> SE Sig3) -> Sco (Mix Sig3) -> Sco (Mix Sig3)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff ((Sig -> SE Sig) -> Sig3 -> AtOut Sig (SE Sig) Sig3
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig -> SE Sig
f)

instance At Sig (SE Sig) (Sco (Mix Sig4)) where
    type AtOut Sig (SE Sig) (Sco (Mix Sig4)) = Sco (Mix Sig4)
    at :: (Sig -> SE Sig)
-> Sco (Mix Sig4) -> AtOut Sig (SE Sig) (Sco (Mix Sig4))
at Sig -> SE Sig
f = (Sig4 -> SE Sig4) -> Sco (Mix Sig4) -> Sco (Mix Sig4)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff ((Sig -> SE Sig) -> Sig4 -> AtOut Sig (SE Sig) Sig4
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig -> SE Sig
f)

--

instance At Sig Sig2 (Sco (Mix Sig)) where
    type AtOut Sig Sig2 (Sco (Mix Sig)) = Sco (Mix Sig2)
    at :: (Sig -> Sig2) -> Sco (Mix Sig) -> AtOut Sig Sig2 (Sco (Mix Sig))
at Sig -> Sig2
f = (Sig -> SE Sig2) -> Sco (Mix Sig) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Sig2 -> SE Sig2
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Sig2 -> SE Sig2) -> (Sig -> Sig2) -> Sig -> SE Sig2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig2
f)

instance At Sig2 Sig2 (Sco (Mix Sig)) where
    type AtOut Sig2 Sig2 (Sco (Mix Sig)) = Sco (Mix Sig2)
    at :: (Sig2 -> Sig2) -> Sco (Mix Sig) -> AtOut Sig2 Sig2 (Sco (Mix Sig))
at Sig2 -> Sig2
f = (Sig -> SE Sig2) -> Sco (Mix Sig) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Sig2 -> SE Sig2
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Sig2 -> SE Sig2) -> (Sig -> Sig2) -> Sig -> SE Sig2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sig2 -> Sig2) -> Sig -> AtOut Sig2 Sig2 Sig
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig2 -> Sig2
f)

instance At Sig (SE Sig2) (Sco (Mix Sig)) where
    type AtOut Sig (SE Sig2) (Sco (Mix Sig)) = Sco (Mix Sig2)
    at :: (Sig -> SE Sig2)
-> Sco (Mix Sig) -> AtOut Sig (SE Sig2) (Sco (Mix Sig))
at Sig -> SE Sig2
f = (Sig -> SE Sig2) -> Sco (Mix Sig) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff Sig -> SE Sig2
f

instance At Sig2 (SE Sig2) (Sco (Mix Sig)) where
    type AtOut Sig2 (SE Sig2)  (Sco (Mix Sig)) = Sco (Mix Sig2)
    at :: (Sig2 -> SE Sig2)
-> Sco (Mix Sig) -> AtOut Sig2 (SE Sig2) (Sco (Mix Sig))
at Sig2 -> SE Sig2
f = (Sig -> SE Sig2) -> Sco (Mix Sig) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff ((Sig2 -> SE Sig2) -> Sig -> AtOut Sig2 (SE Sig2) Sig
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig2 -> SE Sig2
f)

instance At Sig2 Sig2 (Sco (Mix Sig2)) where
    type AtOut Sig2 Sig2 (Sco (Mix Sig2)) = Sco (Mix Sig2)
    at :: (Sig2 -> Sig2)
-> Sco (Mix Sig2) -> AtOut Sig2 Sig2 (Sco (Mix Sig2))
at Sig2 -> Sig2
f = (Sig2 -> SE Sig2) -> Sco (Mix Sig2) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Sig2 -> SE Sig2
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Sig2 -> SE Sig2) -> (Sig2 -> Sig2) -> Sig2 -> SE Sig2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig2 -> Sig2
f)

instance At Sig2 (SE Sig2) (Sco (Mix Sig2)) where
    type AtOut Sig2 (SE Sig2) (Sco (Mix Sig2)) = Sco (Mix Sig2)
    at :: (Sig2 -> SE Sig2)
-> Sco (Mix Sig2) -> AtOut Sig2 (SE Sig2) (Sco (Mix Sig2))
at Sig2 -> SE Sig2
f = (Sig2 -> SE Sig2) -> Sco (Mix Sig2) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff Sig2 -> SE Sig2
f

--

instance MixAt Sig (SE Sig) (Sco (Mix Sig)) where
    mixAt :: Sig
-> (Sig -> SE Sig)
-> Sco (Mix Sig)
-> AtOut Sig (SE Sig) (Sco (Mix Sig))
mixAt Sig
k Sig -> SE Sig
f = (Sig -> SE Sig) -> Sco (Mix Sig) -> Sco (Mix Sig)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Sig -> (Sig -> SE Sig) -> Sig -> AtOut Sig (SE Sig) Sig
forall a b c. MixAt a b c => Sig -> (a -> b) -> c -> AtOut a b c
mixAt Sig
k Sig -> SE Sig
f)

instance MixAt Sig (SE Sig) (Sco (Mix Sig2)) where
    mixAt :: Sig
-> (Sig -> SE Sig)
-> Sco (Mix Sig2)
-> AtOut Sig (SE Sig) (Sco (Mix Sig2))
mixAt Sig
k Sig -> SE Sig
f = (Sig2 -> SE Sig2) -> Sco (Mix Sig2) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Sig -> (Sig -> SE Sig) -> Sig2 -> AtOut Sig (SE Sig) Sig2
forall a b c. MixAt a b c => Sig -> (a -> b) -> c -> AtOut a b c
mixAt Sig
k Sig -> SE Sig
f)

instance MixAt Sig (SE Sig) (Sco (Mix Sig3)) where
    mixAt :: Sig
-> (Sig -> SE Sig)
-> Sco (Mix Sig3)
-> AtOut Sig (SE Sig) (Sco (Mix Sig3))
mixAt Sig
k Sig -> SE Sig
f = (Sig3 -> SE Sig3) -> Sco (Mix Sig3) -> Sco (Mix Sig3)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Sig -> (Sig -> SE Sig) -> Sig3 -> AtOut Sig (SE Sig) Sig3
forall a b c. MixAt a b c => Sig -> (a -> b) -> c -> AtOut a b c
mixAt Sig
k Sig -> SE Sig
f)

instance MixAt Sig (SE Sig) (Sco (Mix Sig4)) where
    mixAt :: Sig
-> (Sig -> SE Sig)
-> Sco (Mix Sig4)
-> AtOut Sig (SE Sig) (Sco (Mix Sig4))
mixAt Sig
k Sig -> SE Sig
f = (Sig4 -> SE Sig4) -> Sco (Mix Sig4) -> Sco (Mix Sig4)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Sig -> (Sig -> SE Sig) -> Sig4 -> AtOut Sig (SE Sig) Sig4
forall a b c. MixAt a b c => Sig -> (a -> b) -> c -> AtOut a b c
mixAt Sig
k Sig -> SE Sig
f)

--

instance MixAt Sig Sig2 (Sco (Mix Sig)) where
    mixAt :: Sig
-> (Sig -> Sig2) -> Sco (Mix Sig) -> AtOut Sig Sig2 (Sco (Mix Sig))
mixAt Sig
k Sig -> Sig2
f = (Sig -> SE Sig2) -> Sco (Mix Sig) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Sig2 -> SE Sig2
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Sig2 -> SE Sig2) -> (Sig -> Sig2) -> Sig -> SE Sig2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> (Sig -> Sig2) -> Sig -> AtOut Sig Sig2 Sig
forall a b c. MixAt a b c => Sig -> (a -> b) -> c -> AtOut a b c
mixAt Sig
k Sig -> Sig2
f)

instance MixAt Sig2 Sig2 (Sco (Mix Sig)) where
    mixAt :: Sig
-> (Sig2 -> Sig2)
-> Sco (Mix Sig)
-> AtOut Sig2 Sig2 (Sco (Mix Sig))
mixAt Sig
k Sig2 -> Sig2
f = (Sig -> SE Sig2) -> Sco (Mix Sig) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Sig2 -> SE Sig2
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Sig2 -> SE Sig2) -> (Sig -> Sig2) -> Sig -> SE Sig2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> (Sig2 -> Sig2) -> Sig -> AtOut Sig2 Sig2 Sig
forall a b c. MixAt a b c => Sig -> (a -> b) -> c -> AtOut a b c
mixAt Sig
k Sig2 -> Sig2
f)

instance MixAt Sig (SE Sig2) (Sco (Mix Sig)) where
    mixAt :: Sig
-> (Sig -> SE Sig2)
-> Sco (Mix Sig)
-> AtOut Sig (SE Sig2) (Sco (Mix Sig))
mixAt Sig
k Sig -> SE Sig2
f = (Sig -> SE Sig2) -> Sco (Mix Sig) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (\Sig
x -> (Sig2 -> Sig2) -> SE Sig2 -> SE Sig2
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> Sig2 -> Sig2 -> Sig2
forall a. (Num a, SigSpace a) => Sig -> a -> a -> a
cfd Sig
k (Sig
x, Sig
x)) (Sig -> SE Sig2
f Sig
x))

instance MixAt Sig2 (SE Sig2) (Sco (Mix Sig)) where
    mixAt :: Sig
-> (Sig2 -> SE Sig2)
-> Sco (Mix Sig)
-> AtOut Sig2 (SE Sig2) (Sco (Mix Sig))
mixAt Sig
k Sig2 -> SE Sig2
f = (Sig -> SE Sig2) -> Sco (Mix Sig) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (\Sig
x -> (Sig2 -> Sig2) -> SE Sig2 -> SE Sig2
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> Sig2 -> Sig2 -> Sig2
forall a. (Num a, SigSpace a) => Sig -> a -> a -> a
cfd Sig
k (Sig
x, Sig
x)) (Sig2 -> SE Sig2
f (Sig
x, Sig
x)))

instance MixAt Sig2 Sig2 (Sco (Mix Sig2)) where
    mixAt :: Sig
-> (Sig2 -> Sig2)
-> Sco (Mix Sig2)
-> AtOut Sig2 Sig2 (Sco (Mix Sig2))
mixAt Sig
k Sig2 -> Sig2
f = (Sig2 -> SE Sig2) -> Sco (Mix Sig2) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (Sig2 -> SE Sig2
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Sig2 -> SE Sig2) -> (Sig2 -> Sig2) -> Sig2 -> SE Sig2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> (Sig2 -> Sig2) -> Sig2 -> AtOut Sig2 Sig2 Sig2
forall a b c. MixAt a b c => Sig -> (a -> b) -> c -> AtOut a b c
mixAt Sig
k Sig2 -> Sig2
f)

instance MixAt Sig2 (SE Sig2) (Sco (Mix Sig2)) where
    mixAt :: Sig
-> (Sig2 -> SE Sig2)
-> Sco (Mix Sig2)
-> AtOut Sig2 (SE Sig2) (Sco (Mix Sig2))
mixAt Sig
k Sig2 -> SE Sig2
f = (Sig2 -> SE Sig2) -> Sco (Mix Sig2) -> Sco (Mix Sig2)
forall a b.
(Sigs a, Sigs b) =>
(a -> SE b) -> Sco (Mix a) -> Sco (Mix b)
eff (\Sig2
x -> (Sig2 -> Sig2) -> SE Sig2 -> SE Sig2
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> Sig2 -> Sig2 -> Sig2
forall a. (Num a, SigSpace a) => Sig -> a -> a -> a
cfd Sig
k Sig2
x) (Sig2 -> SE Sig2
f Sig2
x))