module Csound.Sam.Trig (
  -- * Char sampler
  samCharTrig, samCharTap, samCharPush, samCharToggle, samCharGroup, samCharCycle,

  -- ** Synchronized with number of beats
  samSyncCharTrig, samSyncCharPush, samSyncCharToggle, samSyncCharTap, samSyncCharGroup, samSyncCharCycle,

  -- * Midi sampler
  samMidiTrig, samMidiTap, samMidiPush, samMidiToggle, samMidiGroup,

  -- ** Generic functions
  samMidiTrigBy, samMidiTapBy, samMidiPushBy, samMidiToggleBy, samMidiGroupBy,
) where

import Csound.Base
import qualified Csound.Sam.Core as S
import Csound.Sam.Core(Sam, bindSam, mapBpm, mapBpm2)

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

-- | Triggers the sample with any char from the first string
-- and stops the sample with any char from the second string.
samCharTrig :: Maybe Sam -> String -> String -> Sam -> Sam
samCharTrig :: Maybe Sam -> String -> String -> Sam -> Sam
samCharTrig Maybe Sam
initVal String
starts String
stops Sam
x = case Maybe Sam
initVal of
  Maybe Sam
Nothing -> (Sig2 -> Sig2) -> Sam -> Sam
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe Sig2 -> String -> String -> Sig2 -> Sig2
forall a. Sigs a => Maybe a -> String -> String -> a -> a
charTrig Maybe Sig2
forall a. Maybe a
Nothing String
starts String
stops) Sam
x
  Just Sam
v0 -> (Sig2 -> Sig2 -> Sig2) -> Sam -> Sam -> Sam
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\Sig2
v Sig2
sigs -> Maybe Sig2 -> String -> String -> Sig2 -> Sig2
forall a. Sigs a => Maybe a -> String -> String -> a -> a
charTrig (Sig2 -> Maybe Sig2
forall a. a -> Maybe a
Just Sig2
v) String
starts String
stops Sig2
sigs) Sam
v0 Sam
x

-- | Plays a sample while the key is pressed.
samCharPush :: Maybe Sam -> Char -> Sam -> Sam
samCharPush :: Maybe Sam -> Char -> Sam -> Sam
samCharPush Maybe Sam
initVal Char
ch Sam
x = case Maybe Sam
initVal of
  Maybe Sam
Nothing -> (Sig2 -> Sig2) -> Sam -> Sam
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe Sig2 -> Char -> Sig2 -> Sig2
forall a. Sigs a => Maybe a -> Char -> a -> a
charPush Maybe Sig2
forall a. Maybe a
Nothing Char
ch) Sam
x
  Just Sam
v0 -> (Sig2 -> Sig2 -> Sig2) -> Sam -> Sam -> Sam
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\Sig2
v Sig2
sigs -> Maybe Sig2 -> Char -> Sig2 -> Sig2
forall a. Sigs a => Maybe a -> Char -> a -> a
charPush (Sig2 -> Maybe Sig2
forall a. a -> Maybe a
Just Sig2
v) Char
ch Sig2
sigs) Sam
v0 Sam
x

-- | Toggles the sample when the key is pressed.
samCharToggle :: Maybe Sam -> Char -> Sam -> Sam
samCharToggle :: Maybe Sam -> Char -> Sam -> Sam
samCharToggle Maybe Sam
initVal Char
ch Sam
x = case Maybe Sam
initVal of
  Maybe Sam
Nothing -> (Sig2 -> Sig2) -> Sam -> Sam
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe Sig2 -> Char -> Sig2 -> Sig2
forall a. Sigs a => Maybe a -> Char -> a -> a
charToggle Maybe Sig2
forall a. Maybe a
Nothing Char
ch) Sam
x
  Just Sam
v0 -> (Sig2 -> Sig2 -> Sig2) -> Sam -> Sam -> Sam
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\Sig2
v Sig2
sigs -> Maybe Sig2 -> Char -> Sig2 -> Sig2
forall a. Sigs a => Maybe a -> Char -> a -> a
charToggle (Sig2 -> Maybe Sig2
forall a. a -> Maybe a
Just Sig2
v) Char
ch Sig2
sigs) Sam
v0 Sam
x

-- | Char trigger with fixed note limiting by length in second.
-- It's useful optimization. It's good to use for drum notes and short sounds.
samCharTap :: Sig -> String -> Sam -> Sam
samCharTap :: Sig -> String -> Sam -> Sam
samCharTap Sig
stop String
starts = (Sig2 -> Sig2) -> Sam -> Sam
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> String -> Sig2 -> Sig2
forall a. Sigs a => Sig -> String -> a -> a
charTap Sig
stop String
starts)

-- | Plays one of the sample from the list when corresponding char is pressed.
-- The last string is for stopping the samples.
samCharGroup :: Maybe Sam -> [(Char, Sam)] -> String -> Sam
samCharGroup :: Maybe Sam -> [(Char, Sam)] -> String -> Sam
samCharGroup Maybe Sam
initVal [(Char, Sam)]
as String
stop = case Maybe Sam
initVal of
  Maybe Sam
Nothing -> ([Sig2] -> Sig2) -> Sample [Sig2] -> Sam
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\[Sig2]
xs -> Maybe Sig2 -> [(Char, Sig2)] -> String -> Sig2
forall a. Sigs a => Maybe a -> [(Char, a)] -> String -> a
charGroup Maybe Sig2
forall a. Maybe a
Nothing (String -> [Sig2] -> [(Char, Sig2)]
forall a b. [a] -> [b] -> [(a, b)]
zip String
starts [Sig2]
xs) String
stop) ([Sam] -> Sample [Sig2]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Sam]
sams)
  Just Sam
v0 -> (Sig2 -> [Sig2] -> Sig2) -> Sam -> Sample [Sig2] -> Sam
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\Sig2
v [Sig2]
xs -> Maybe Sig2 -> [(Char, Sig2)] -> String -> Sig2
forall a. Sigs a => Maybe a -> [(Char, a)] -> String -> a
charGroup (Sig2 -> Maybe Sig2
forall a. a -> Maybe a
Just Sig2
v) (String -> [Sig2] -> [(Char, Sig2)]
forall a b. [a] -> [b] -> [(a, b)]
zip String
starts [Sig2]
xs) String
stop) Sam
v0 ([Sam] -> Sample [Sig2]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Sam]
sams)
  where (String
starts, [Sam]
sams) = [(Char, Sam)] -> (String, [Sam])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Char, Sam)]
as

-- | Plays samples in sequence when key is pressed. The last string is
-- for stopping the sequence.
samCharCycle :: Maybe Sam -> Char -> String -> [Sam] -> Sam
samCharCycle :: Maybe Sam -> Char -> String -> [Sam] -> Sam
samCharCycle Maybe Sam
initVal Char
start String
stop [Sam]
as = case Maybe Sam
initVal of
  Maybe Sam
Nothing -> ([Sig2] -> Sig2) -> Sample [Sig2] -> Sam
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe Sig2 -> Char -> String -> [Sig2] -> Sig2
forall a. Sigs a => Maybe a -> Char -> String -> [a] -> a
charCycle Maybe Sig2
forall a. Maybe a
Nothing Char
start String
stop) ([Sam] -> Sample [Sig2]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Sam]
as)
  Just Sam
v0 -> (Sig2 -> [Sig2] -> Sig2) -> Sam -> Sample [Sig2] -> Sam
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\Sig2
v [Sig2]
xs -> Maybe Sig2 -> Char -> String -> [Sig2] -> Sig2
forall a. Sigs a => Maybe a -> Char -> String -> [a] -> a
charCycle (Sig2 -> Maybe Sig2
forall a. a -> Maybe a
Just Sig2
v) Char
start String
stop [Sig2]
xs) Sam
v0 ([Sam] -> Sample [Sig2]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Sam]
as)


------------------------------------------------------
-- synchronised

syncBeats :: Sig -> Sig -> Sig
syncBeats :: Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats = Sig
bpm Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ Sig
beats

-- | Triggers the sample with any char from the first string
-- and stops the sample with any char from the second string.
-- The first argument is the number of beats for syncronization.
samSyncCharTrig :: Sig -> Maybe Sam -> String -> String -> Sam -> Sam
samSyncCharTrig :: Sig -> Maybe Sam -> String -> String -> Sam -> Sam
samSyncCharTrig Sig
beats Maybe Sam
initVal String
starts String
stops Sam
x = case Maybe Sam
initVal of
  Maybe Sam
Nothing -> (Sig -> Sig2 -> Sig2) -> Sam -> Sam
forall a b. (Sig -> a -> b) -> Sample a -> Sample b
mapBpm (\Sig
bpm Sig2
a -> Sig -> Maybe Sig2 -> String -> String -> Sig2 -> Sig2
forall a. Sigs a => Sig -> Maybe a -> String -> String -> a -> a
syncCharTrig (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) Maybe Sig2
forall a. Maybe a
Nothing String
starts String
stops Sig2
a) Sam
x
  Just Sam
v0 -> (Sig -> Sig2 -> Sig2 -> Sig2) -> Sam -> Sam -> Sam
forall a b c.
(Sig -> a -> b -> c) -> Sample a -> Sample b -> Sample c
mapBpm2 (\Sig
bpm Sig2
v Sig2
sigs -> Sig -> Maybe Sig2 -> String -> String -> Sig2 -> Sig2
forall a. Sigs a => Sig -> Maybe a -> String -> String -> a -> a
syncCharTrig (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) (Sig2 -> Maybe Sig2
forall a. a -> Maybe a
Just Sig2
v) String
starts String
stops Sig2
sigs) Sam
v0 Sam
x

-- | Plays a sample while the key is pressed.
-- The first argument is the number of beats for syncronization.
samSyncCharPush :: Sig -> Maybe Sam -> Char -> Sam -> Sam
samSyncCharPush :: Sig -> Maybe Sam -> Char -> Sam -> Sam
samSyncCharPush Sig
beats Maybe Sam
initVal Char
ch Sam
x = case Maybe Sam
initVal of
  Maybe Sam
Nothing -> (Sig -> Sig2 -> Sig2) -> Sam -> Sam
forall a b. (Sig -> a -> b) -> Sample a -> Sample b
mapBpm (\Sig
bpm Sig2
a -> Sig -> Maybe Sig2 -> Char -> Sig2 -> Sig2
forall a. Sigs a => Sig -> Maybe a -> Char -> a -> a
syncCharPush (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) Maybe Sig2
forall a. Maybe a
Nothing Char
ch Sig2
a) Sam
x
  Just Sam
v0 -> (Sig -> Sig2 -> Sig2 -> Sig2) -> Sam -> Sam -> Sam
forall a b c.
(Sig -> a -> b -> c) -> Sample a -> Sample b -> Sample c
mapBpm2 (\Sig
bpm Sig2
v Sig2
sigs -> Sig -> Maybe Sig2 -> Char -> Sig2 -> Sig2
forall a. Sigs a => Sig -> Maybe a -> Char -> a -> a
syncCharPush (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) (Sig2 -> Maybe Sig2
forall a. a -> Maybe a
Just Sig2
v) Char
ch Sig2
sigs) Sam
v0 Sam
x

-- | Toggles the sample when the key is pressed.
-- The first argument is the number of beats for syncronization.
samSyncCharToggle :: Sig -> Maybe Sam -> Char -> Sam -> Sam
samSyncCharToggle :: Sig -> Maybe Sam -> Char -> Sam -> Sam
samSyncCharToggle Sig
beats Maybe Sam
initVal Char
ch Sam
x = case Maybe Sam
initVal of
  Maybe Sam
Nothing -> (Sig -> Sig2 -> Sig2) -> Sam -> Sam
forall a b. (Sig -> a -> b) -> Sample a -> Sample b
mapBpm (\Sig
bpm Sig2
a -> Sig -> Maybe Sig2 -> Char -> Sig2 -> Sig2
forall a. Sigs a => Sig -> Maybe a -> Char -> a -> a
syncCharToggle (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) Maybe Sig2
forall a. Maybe a
Nothing Char
ch Sig2
a) Sam
x
  Just Sam
v0 -> (Sig -> Sig2 -> Sig2 -> Sig2) -> Sam -> Sam -> Sam
forall a b c.
(Sig -> a -> b -> c) -> Sample a -> Sample b -> Sample c
mapBpm2 (\Sig
bpm Sig2
v Sig2
sigs -> Sig -> Maybe Sig2 -> Char -> Sig2 -> Sig2
forall a. Sigs a => Sig -> Maybe a -> Char -> a -> a
syncCharToggle (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) (Sig2 -> Maybe Sig2
forall a. a -> Maybe a
Just Sig2
v) Char
ch Sig2
sigs) Sam
v0 Sam
x

-- | Char trigger with fixed note limiting by length in second.
-- It's useful optimization. It's good to use for drum notes and short sounds.
-- The first argument is the number of beats for syncronization.
samSyncCharTap :: Sig -> Sig -> String -> Sam -> Sam
samSyncCharTap :: Sig -> Sig -> String -> Sam -> Sam
samSyncCharTap Sig
beats Sig
stop String
starts = (Sig -> Sig2 -> Sig2) -> Sam -> Sam
forall a b. (Sig -> a -> b) -> Sample a -> Sample b
mapBpm (\Sig
bpm Sig2
x -> Sig -> Sig -> String -> Sig2 -> Sig2
forall a. Sigs a => Sig -> Sig -> String -> a -> a
syncCharTap (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) Sig
stop String
starts Sig2
x)

-- | Plays one of the sample from the list when corresponding char is pressed.
-- The last string is for stopping the samples.
samSyncCharGroup :: Sig -> Maybe Sam -> [(Char, Sam)] -> String -> Sam
samSyncCharGroup :: Sig -> Maybe Sam -> [(Char, Sam)] -> String -> Sam
samSyncCharGroup Sig
beats Maybe Sam
initVal [(Char, Sam)]
as String
stop = case Maybe Sam
initVal of
  Maybe Sam
Nothing -> (Sig -> [Sig2] -> Sig2) -> Sample [Sig2] -> Sam
forall a b. (Sig -> a -> b) -> Sample a -> Sample b
mapBpm (\Sig
bpm [Sig2]
xs -> Sig -> Maybe Sig2 -> [(Char, Sig2)] -> String -> Sig2
forall a. Sigs a => Sig -> Maybe a -> [(Char, a)] -> String -> a
syncCharGroup (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) Maybe Sig2
forall a. Maybe a
Nothing (String -> [Sig2] -> [(Char, Sig2)]
forall a b. [a] -> [b] -> [(a, b)]
zip String
starts [Sig2]
xs) String
stop) ([Sam] -> Sample [Sig2]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Sam]
sams)
  Just Sam
v0 -> (Sig -> Sig2 -> [Sig2] -> Sig2) -> Sam -> Sample [Sig2] -> Sam
forall a b c.
(Sig -> a -> b -> c) -> Sample a -> Sample b -> Sample c
mapBpm2 (\Sig
bpm Sig2
v [Sig2]
xs -> Sig -> Maybe Sig2 -> [(Char, Sig2)] -> String -> Sig2
forall a. Sigs a => Sig -> Maybe a -> [(Char, a)] -> String -> a
syncCharGroup (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) (Sig2 -> Maybe Sig2
forall a. a -> Maybe a
Just Sig2
v) (String -> [Sig2] -> [(Char, Sig2)]
forall a b. [a] -> [b] -> [(a, b)]
zip String
starts [Sig2]
xs) String
stop) Sam
v0 ([Sam] -> Sample [Sig2]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Sam]
sams)
  where (String
starts, [Sam]
sams) = [(Char, Sam)] -> (String, [Sam])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Char, Sam)]
as

-- | Plays samples in sequence when key is pressed. The last string is
-- for stopping the sequence.
-- The first argument is the number of beats for syncronization.
samSyncCharCycle :: Sig -> Maybe Sam -> Char -> String -> [Sam] -> Sam
samSyncCharCycle :: Sig -> Maybe Sam -> Char -> String -> [Sam] -> Sam
samSyncCharCycle Sig
beats Maybe Sam
initVal Char
start String
stop [Sam]
as = case Maybe Sam
initVal of
  Maybe Sam
Nothing -> (Sig -> [Sig2] -> Sig2) -> Sample [Sig2] -> Sam
forall a b. (Sig -> a -> b) -> Sample a -> Sample b
mapBpm (\Sig
bpm -> Sig -> Maybe Sig2 -> Char -> String -> [Sig2] -> Sig2
forall a. Sigs a => Sig -> Maybe a -> Char -> String -> [a] -> a
syncCharCycle (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) Maybe Sig2
forall a. Maybe a
Nothing Char
start String
stop) ([Sam] -> Sample [Sig2]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Sam]
as)
  Just Sam
v0 -> (Sig -> Sig2 -> [Sig2] -> Sig2) -> Sam -> Sample [Sig2] -> Sam
forall a b c.
(Sig -> a -> b -> c) -> Sample a -> Sample b -> Sample c
mapBpm2 (\Sig
bpm Sig2
v [Sig2]
xs -> Sig -> Maybe Sig2 -> Char -> String -> [Sig2] -> Sig2
forall a. Sigs a => Sig -> Maybe a -> Char -> String -> [a] -> a
syncCharCycle (Sig -> Sig -> Sig
syncBeats Sig
bpm Sig
beats) (Sig2 -> Maybe Sig2
forall a. a -> Maybe a
Just Sig2
v) Char
start String
stop [Sig2]
xs) Sam
v0 ([Sam] -> Sample [Sig2]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Sam]
as)

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

-- | Triggers a sample with midi key.
-- The key is an integer midi code. The C1 is 60 and the A1 is 69.
samMidiTrig :: MidiChn -> Int -> Sam -> Sam
samMidiTrig :: MidiChn -> Int -> Sam -> Sam
samMidiTrig = MidiTrigFun Sig2 -> MidiChn -> Int -> Sam -> Sam
samMidiTrigBy MidiTrigFun Sig2
forall a. (SigSpace a, Sigs a) => a -> D -> SE a
midiAmpInstr

-- | Midi trigger with fixed note limiting by length in second.
-- It's useful optimization. It's good to use for drum notes and short sounds.
-- The key is an integer midi code. The C1 is 60 and the A1 is 69.
samMidiTap :: MidiChn -> Sig -> Int -> Sam -> Sam
samMidiTap :: MidiChn -> Sig -> Int -> Sam -> Sam
samMidiTap = MidiTrigFun Sig2 -> MidiChn -> Sig -> Int -> Sam -> Sam
samMidiTapBy MidiTrigFun Sig2
forall a. (SigSpace a, Sigs a) => a -> D -> SE a
midiAmpInstr

samMidiPush :: MidiChn -> Int -> Sam -> Sam
samMidiPush :: MidiChn -> Int -> Sam -> Sam
samMidiPush = MidiTrigFun Sig2 -> MidiChn -> Int -> Sam -> Sam
samMidiPushBy MidiTrigFun Sig2
forall a. (SigSpace a, Sigs a) => a -> D -> SE a
midiAmpInstr

-- | Toggles samples with midi key.
-- The key is an integer midi code. The C1 is 60 and the A1 is 69.
samMidiToggle :: MidiChn -> Int -> Sam -> Sam
samMidiToggle :: MidiChn -> Int -> Sam -> Sam
samMidiToggle = MidiTrigFun Sig2 -> MidiChn -> Int -> Sam -> Sam
samMidiToggleBy MidiTrigFun Sig2
forall a. (SigSpace a, Sigs a) => a -> D -> SE a
midiAmpInstr

-- | Plays samples in the group. It's like the samCharGroup.
-- The key is an integer midi code. The C1 is 60 and the A1 is 69.
samMidiGroup :: MidiChn -> [(Int, Sam)] -> Sam
samMidiGroup :: MidiChn -> [(Int, Sam)] -> Sam
samMidiGroup MidiChn
midiChn [(Int, Sam)]
as = Sample (SE Sig2) -> Sam
forall a. Sample (SE a) -> Sample a
S.liftSam (Sample (SE Sig2) -> Sam) -> Sample (SE Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ ([Sig2] -> SE Sig2) -> Sample [Sig2] -> Sample (SE Sig2)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\[Sig2]
xs -> MidiChn -> [(Int, Sig2)] -> SE Sig2
forall a. (SigSpace a, Sigs a) => MidiChn -> [(Int, a)] -> SE a
midiGroup MidiChn
midiChn ([(Int, Sig2)] -> SE Sig2) -> [(Int, Sig2)] -> SE Sig2
forall a b. (a -> b) -> a -> b
$ [Int] -> [Sig2] -> [(Int, Sig2)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
keys [Sig2]
xs) (Sample [Sig2] -> Sample (SE Sig2))
-> Sample [Sig2] -> Sample (SE Sig2)
forall a b. (a -> b) -> a -> b
$ [Sam] -> Sample [Sig2]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Sam]
sams
  where ([Int]
keys, [Sam]
sams) = [(Int, Sam)] -> ([Int], [Sam])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Int, Sam)]
as

-- | Generic samMidiTrig. We can specify the midi triggering function.
-- The midi function takes in a signal and a volume of the pressed key (it ranges from 0 to 1).
-- It produces some output. The default is scaling the signal with the amplitude.
samMidiTrigBy :: MidiTrigFun Sig2 -> MidiChn -> Int -> Sam -> Sam
samMidiTrigBy :: MidiTrigFun Sig2 -> MidiChn -> Int -> Sam -> Sam
samMidiTrigBy MidiTrigFun Sig2
midiFun MidiChn
midiChn Int
key = (Sig2 -> SE Sig2) -> Sam -> Sam
forall a b. (a -> SE b) -> Sample a -> Sample b
bindSam (MidiTrigFun Sig2 -> MidiChn -> Int -> Sig2 -> SE Sig2
forall a.
(SigSpace a, Sigs a) =>
MidiTrigFun a -> MidiChn -> Int -> a -> SE a
midiTrigBy MidiTrigFun Sig2
midiFun MidiChn
midiChn Int
key)

-- | Generic samMidiTap. We can specify the midi triggering function.
-- The midi function takes in a signal and a volume of the pressed key (it ranges from 0 to 1).
-- It produces some output. The default is scaling the signal with the amplitude.
samMidiTapBy :: MidiTrigFun Sig2 -> MidiChn -> Sig -> Int -> Sam -> Sam
samMidiTapBy :: MidiTrigFun Sig2 -> MidiChn -> Sig -> Int -> Sam -> Sam
samMidiTapBy MidiTrigFun Sig2
midiFun MidiChn
midiChn Sig
dt Int
key = (Sig2 -> SE Sig2) -> Sam -> Sam
forall a b. (a -> SE b) -> Sample a -> Sample b
bindSam (MidiTrigFun Sig2 -> MidiChn -> Sig -> Int -> Sig2 -> SE Sig2
forall a.
(SigSpace a, Sigs a) =>
MidiTrigFun a -> MidiChn -> Sig -> Int -> a -> SE a
midiTapBy MidiTrigFun Sig2
midiFun MidiChn
midiChn Sig
dt Int
key)

-- | Generic samMidiPush. We can specify the midi triggering function.
-- The midi function takes in a signal and a volume of the pressed key (it ranges from 0 to 1).
-- It produces some output. The default is scaling the signal with the amplitude.
samMidiPushBy :: MidiTrigFun Sig2 -> MidiChn -> Int -> Sam -> Sam
samMidiPushBy :: MidiTrigFun Sig2 -> MidiChn -> Int -> Sam -> Sam
samMidiPushBy MidiTrigFun Sig2
midiFun MidiChn
midiChn Int
key = (Sig2 -> SE Sig2) -> Sam -> Sam
forall a b. (a -> SE b) -> Sample a -> Sample b
bindSam (MidiTrigFun Sig2 -> MidiChn -> Int -> Sig2 -> SE Sig2
forall a.
(SigSpace a, Sigs a) =>
MidiTrigFun a -> MidiChn -> Int -> a -> SE a
midiPushBy MidiTrigFun Sig2
midiFun MidiChn
midiChn Int
key)

-- | Generic samMidiToggle. We can specify the midi triggering function.
-- The midi function takes in a signal and a volume of the pressed key (it ranges from 0 to 1).
-- It produces some output. The default is scaling the signal with the amplitude.
samMidiToggleBy :: MidiTrigFun Sig2 -> MidiChn -> Int -> Sam -> Sam
samMidiToggleBy :: MidiTrigFun Sig2 -> MidiChn -> Int -> Sam -> Sam
samMidiToggleBy MidiTrigFun Sig2
midiFun MidiChn
midiChn Int
key = (Sig2 -> SE Sig2) -> Sam -> Sam
forall a b. (a -> SE b) -> Sample a -> Sample b
bindSam (MidiTrigFun Sig2 -> MidiChn -> Int -> Sig2 -> SE Sig2
forall a.
(SigSpace a, Sigs a) =>
MidiTrigFun a -> MidiChn -> Int -> a -> SE a
midiToggleBy MidiTrigFun Sig2
midiFun MidiChn
midiChn Int
key)

-- | Generic samMidiGroup. We can specify the midi triggering function.
-- The midi function takes in a signal and a volume of the pressed key (it ranges from 0 to 1).
-- It produces some output. The default is scaling the signal with the amplitude.
samMidiGroupBy :: MidiTrigFun Sig2 -> MidiChn -> [(Int, Sam)] -> Sam
samMidiGroupBy :: MidiTrigFun Sig2 -> MidiChn -> [(Int, Sam)] -> Sam
samMidiGroupBy  MidiTrigFun Sig2
midiFun MidiChn
midiChn [(Int, Sam)]
as = Sample (SE Sig2) -> Sam
forall a. Sample (SE a) -> Sample a
S.liftSam (Sample (SE Sig2) -> Sam) -> Sample (SE Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ ([Sig2] -> SE Sig2) -> Sample [Sig2] -> Sample (SE Sig2)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\[Sig2]
xs -> MidiTrigFun Sig2 -> MidiChn -> [(Int, Sig2)] -> SE Sig2
forall a.
(SigSpace a, Sigs a) =>
MidiTrigFun a -> MidiChn -> [(Int, a)] -> SE a
midiGroupBy MidiTrigFun Sig2
midiFun MidiChn
midiChn ([(Int, Sig2)] -> SE Sig2) -> [(Int, Sig2)] -> SE Sig2
forall a b. (a -> b) -> a -> b
$ [Int] -> [Sig2] -> [(Int, Sig2)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
keys [Sig2]
xs) (Sample [Sig2] -> Sample (SE Sig2))
-> Sample [Sig2] -> Sample (SE Sig2)
forall a b. (a -> b) -> a -> b
$ [Sam] -> Sample [Sig2]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Sam]
sams
  where ([Int]
keys, [Sam]
sams) = [(Int, Sam)] -> ([Int], [Sam])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Int, Sam)]
as