{-# Language FlexibleContexts #-}
-- | Graphical widgets for playing samples
module Csound.Sam.Ui(
  freeSim, hfreeSim, freeSimWith, hfreeSimWith,
  freeTog, hfreeTog,
  sim, hsim, simWith, hsimWith,
  tog, htog,
  live, liveEf,
  mixSam, uiSam, addGain
) where

import Data.List(transpose)
import Data.String (fromString)
import Data.Text (Text)
import Control.Monad
import Control.Monad.Trans.Reader

import Csound.Base
import Csound.Sam.Core

groupToggles :: ([Sig2] -> Sig2) -> [Sam] -> [Evt D] -> Sam
groupToggles :: ([Sig2] -> Sig2) -> [Sample Sig2] -> [Evt D] -> Sample Sig2
groupToggles [Sig2] -> Sig2
group [Sample Sig2]
sams [Evt D]
ts = ReaderT Sig SE (S Sig2) -> Sample Sig2
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sample Sig2)
-> ReaderT Sig SE (S Sig2) -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ (Sig -> S Sig2) -> ReaderT Sig SE (S Sig2)
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
reader ((Sig -> S Sig2) -> ReaderT Sig SE (S Sig2))
-> (Sig -> S Sig2) -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ \Sig
r ->
  Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S ([Sig2] -> Sig2
group ([Sig2] -> Sig2) -> [Sig2] -> Sig2
forall a b. (a -> b) -> a -> b
$ (Sample Sig2 -> Evt D -> Sig2)
-> [Sample Sig2] -> [Evt D] -> [Sig2]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Sample Sig2
sam Evt D
t -> SE Sig2 -> Evt D -> Sig2
forall b. Sigs b => SE b -> Evt D -> b
schedToggle (Sig -> Sample Sig2 -> SE Sig2
runSam Sig
r Sample Sig2
sam) Evt D
t) [Sample Sig2]
sams [Evt D]
ts) Dur
InfDur

-- | A widget for playing several samples at the same time (aka `sim`ultaneously).
-- The prefix `free` means no syncronization. the samples start to play when the button is pressed.
freeSim :: [(Text, Sam)] -> Source Sam
freeSim :: [(Text, Sample Sig2)] -> Source (Sample Sig2)
freeSim = ([Gui] -> Gui) -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genFreeSim [Gui] -> Gui
ver

-- | It's just like the function @freeSim@ but the visual representation is horizontal.
-- That's why there is a prefix @h@.
hfreeSim :: [(Text, Sam)] -> Source Sam
hfreeSim :: [(Text, Sample Sig2)] -> Source (Sample Sig2)
hfreeSim = ([Gui] -> Gui) -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genFreeSim [Gui] -> Gui
hor

-- | It's just like the function `freeSim` but the user can
-- activate some samples right in the code. If the third
-- element is @True@ the sample is played.
freeSimWith :: [(Text, Sam, Bool)] -> Source Sam
freeSimWith :: [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
freeSimWith = ([Gui] -> Gui)
-> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
genFreeSimInits [Gui] -> Gui
ver

-- | It's just like the function `freeSimWith` but the visual representation is horizontal.
-- That's why there is a prefix @h@.
hfreeSimWith :: [(Text, Sam, Bool)] -> Source Sam
hfreeSimWith :: [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
hfreeSimWith = ([Gui] -> Gui)
-> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
genFreeSimInits [Gui] -> Gui
hor

genFreeSim :: ([Gui] -> Gui) -> [(Text, Sam)] -> Source Sam
genFreeSim :: ([Gui] -> Gui) -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genFreeSim [Gui] -> Gui
gcat [(Text, Sample Sig2)]
as = ([Gui] -> Gui)
-> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
genFreeSimInits [Gui] -> Gui
gcat ([(Text, Sample Sig2, Bool)] -> Source (Sample Sig2))
-> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
forall a b. (a -> b) -> a -> b
$ ((Text, Sample Sig2) -> (Text, Sample Sig2, Bool))
-> [(Text, Sample Sig2)] -> [(Text, Sample Sig2, Bool)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Text
a, Sample Sig2
b) -> (Text
a, Sample Sig2
b, Bool
False)) [(Text, Sample Sig2)]
as

genFreeSimInits :: ([Gui] -> Gui) -> [(Text, Sam, Bool)] -> Source Sam
genFreeSimInits :: ([Gui] -> Gui)
-> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
genFreeSimInits [Gui] -> Gui
gcat [(Text, Sample Sig2, Bool)]
as = Source (Sample Sig2) -> Source (Sample Sig2)
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source (Sample Sig2) -> Source (Sample Sig2))
-> Source (Sample Sig2) -> Source (Sample Sig2)
forall a b. (a -> b) -> a -> b
$ do
  ([Gui]
guis, [Evt D]
ts) <- ([(Gui, Evt D)] -> ([Gui], [Evt D]))
-> SE [(Gui, Evt D)] -> SE ([Gui], [Evt D])
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, Evt D)] -> ([Gui], [Evt D])
forall a b. [(a, b)] -> ([a], [b])
unzip (SE [(Gui, Evt D)] -> SE ([Gui], [Evt D]))
-> SE [(Gui, Evt D)] -> SE ([Gui], [Evt D])
forall a b. (a -> b) -> a -> b
$ (Text -> Bool -> SE (Gui, Evt D))
-> [Text] -> [Bool] -> SE [(Gui, Evt D)]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (\Text
a Bool
b -> Text -> Bool -> SE (Gui, Evt D)
toggle Text
a Bool
b) [Text]
names [Bool]
initVals
  let res :: Sample Sig2
res = ([Sig2] -> Sig2) -> [Sample Sig2] -> [Evt D] -> Sample Sig2
groupToggles [Sig2] -> Sig2
forall a. Fractional a => [a] -> a
mean [Sample Sig2]
sams [Evt D]
ts
  (Gui, Sample Sig2) -> Source (Sample Sig2)
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Gui] -> Gui
gcat [Gui]
guis, Sample Sig2
res)
  where
    ([Text]
names, [Sample Sig2]
sams, [Bool]
initVals) = [(Text, Sample Sig2, Bool)] -> ([Text], [Sample Sig2], [Bool])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 [(Text, Sample Sig2, Bool)]
as

-- | The widget to toggle between several samples (aka `tog`gle).
-- The prefix `free` means no syncronization. the samples start to play when the button is pressed.
freeTog :: [(Text, Sam)] -> Source Sam
freeTog :: [(Text, Sample Sig2)] -> Source (Sample Sig2)
freeTog = ([Gui] -> Gui) -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genFreeTog [Gui] -> Gui
ver

-- | It's just like the function @freeTog@ but the visual representation is horizontal.
hfreeTog :: [(Text, Sam)] -> Source Sam
hfreeTog :: [(Text, Sample Sig2)] -> Source (Sample Sig2)
hfreeTog = ([Gui] -> Gui) -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genFreeTog [Gui] -> Gui
hor

genFreeTog :: ([Gui] -> Gui) -> [(Text, Sam)] -> Source Sam
genFreeTog :: ([Gui] -> Gui) -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genFreeTog [Gui] -> Gui
gcat [(Text, Sample Sig2)]
as = Source (Sample Sig2) -> Source (Sample Sig2)
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source (Sample Sig2) -> Source (Sample Sig2))
-> Source (Sample Sig2) -> Source (Sample Sig2)
forall a b. (a -> b) -> a -> b
$ do
  ([Gui]
guis, [Output Sig]
writeProcs, [Sig]
readProcs) <- ([(Gui, Output Sig, Sig)] -> ([Gui], [Output Sig], [Sig]))
-> SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig])
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, Output Sig, Sig)] -> ([Gui], [Output Sig], [Sig])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 (SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig]))
-> SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig])
forall a b. (a -> b) -> a -> b
$ (Text -> SE (Gui, Output Sig, Sig))
-> [Text] -> SE [(Gui, Output Sig, Sig)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((Text -> Bool -> SE (Gui, Output Sig, Sig))
-> Bool -> Text -> SE (Gui, Output Sig, Sig)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> Bool -> SE (Gui, Output Sig, Sig)
setToggleSig Bool
False) [Text]
names
  Ref Sig
curRef <- Sig -> SE (Ref Sig)
forall a. Tuple a => a -> SE (Ref a)
newGlobalRef (Sig
0 :: Sig)
  Sig
current <- Ref Sig -> SE Sig
forall a. Tuple a => Ref a -> SE a
readRef Ref Sig
curRef
  (Output Sig -> Output Sig) -> [Output Sig] -> [Sig] -> SE ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ (\Output Sig
w Sig
i -> Output Sig
w Output Sig -> Output Sig
forall a b. (a -> b) -> a -> b
$ BoolSig -> Sig -> Sig -> Sig
forall bool. (bool ~ BooleanOf Sig) => bool -> Sig -> Sig -> Sig
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (Sig
current Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
i) Sig
1 Sig
0) [Output Sig]
writeProcs [Sig]
ids
  (Sig -> Output Sig) -> [Sig] -> [Sig] -> SE ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ (\Sig
r Sig
i -> Evt D -> Bam D -> SE ()
forall a. Evt a -> Bam a -> SE ()
runEvt (Sig -> Evt D
snaps Sig
r) (Bam D -> SE ()) -> Bam D -> SE ()
forall a b. (a -> b) -> a -> b
$ \D
x -> do
    BoolSig -> SE () -> SE ()
when1 (D -> Sig
sig D
x Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
0 BoolSig -> BoolSig -> BoolSig
forall b. Boolean b => b -> b -> b
&&* Sig
current Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
i) (SE () -> SE ()) -> SE () -> SE ()
forall a b. (a -> b) -> a -> b
$ do
      Ref Sig -> Output Sig
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref Sig
curRef Sig
0
    BoolSig -> SE () -> SE ()
when1 (D -> Sig
sig D
x Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
1) (SE () -> SE ()) -> SE () -> SE ()
forall a b. (a -> b) -> a -> b
$ do
      Ref Sig -> Output Sig
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref Sig
curRef Sig
i
    ) [Sig]
readProcs [Sig]
ids

  let res :: Sample Sig2
res = ([Sig2] -> Sig2) -> [Sample Sig2] -> [Evt D] -> Sample Sig2
groupToggles [Sig2] -> Sig2
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Sample Sig2]
sams ([Evt D] -> Sample Sig2) -> [Evt D] -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ (Sig -> Evt D) -> [Sig] -> [Evt D]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> Evt D
snaps (Sig -> Evt D) -> (Sig -> Sig) -> Sig -> Evt D
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\Sig
i -> BoolSig -> Sig -> Sig -> Sig
forall bool. (bool ~ BooleanOf Sig) => bool -> Sig -> Sig -> Sig
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (Sig
current Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
i) Sig
1 Sig
0)) [Sig]
ids
  (Gui, Sample Sig2) -> Source (Sample Sig2)
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Gui] -> Gui
gcat [Gui]
guis, Sample Sig2
res)
  where
    ([Text]
names, [Sample Sig2]
sams) = [(Text, Sample Sig2)] -> ([Text], [Sample Sig2])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Text, Sample Sig2)]
as
    ids :: [Sig]
ids = (Int -> Sig) -> [Int] -> [Sig]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (D -> Sig
sig (D -> Sig) -> (Int -> D) -> Int -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> D
int) [Int
1 .. [(Text, Sample Sig2)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Text, Sample Sig2)]
as]


genSim :: ([Gui] -> Gui) -> Int -> [(Text, Sam)] -> Source Sam
genSim :: ([Gui] -> Gui)
-> Int -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genSim [Gui] -> Gui
gcat Int
numBeats [(Text, Sample Sig2)]
as = ([Gui] -> Gui)
-> Int -> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
genSimInits [Gui] -> Gui
gcat Int
numBeats ([(Text, Sample Sig2, Bool)] -> Source (Sample Sig2))
-> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
forall a b. (a -> b) -> a -> b
$ ((Text, Sample Sig2) -> (Text, Sample Sig2, Bool))
-> [(Text, Sample Sig2)] -> [(Text, Sample Sig2, Bool)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Text
a, Sample Sig2
b) -> (Text
a, Sample Sig2
b, Bool
False)) [(Text, Sample Sig2)]
as

genSimInits :: ([Gui] -> Gui) -> Int -> [(Text, Sam, Bool)] -> Source Sam
genSimInits :: ([Gui] -> Gui)
-> Int -> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
genSimInits [Gui] -> Gui
gcat Int
numBeats [(Text, Sample Sig2, Bool)]
as = Source (Sample Sig2) -> Source (Sample Sig2)
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source (Sample Sig2) -> Source (Sample Sig2))
-> Source (Sample Sig2) -> Source (Sample Sig2)
forall a b. (a -> b) -> a -> b
$ do
  ([Gui]
guis, [Output Sig]
writeProcs, [Sig]
readProcs) <- ([(Gui, Output Sig, Sig)] -> ([Gui], [Output Sig], [Sig]))
-> SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig])
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, Output Sig, Sig)] -> ([Gui], [Output Sig], [Sig])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 (SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig]))
-> SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig])
forall a b. (a -> b) -> a -> b
$ (Text -> Bool -> SE (Gui, Output Sig, Sig))
-> [Text] -> [Bool] -> SE [(Gui, Output Sig, Sig)]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (\Text
a Bool
b -> Text -> Bool -> SE (Gui, Output Sig, Sig)
setToggleSig Text
a Bool
b) [Text]
names [Bool]
initVals
  [Ref Sig]
curRefs <- (Sig -> SE (Ref Sig)) -> [Sig] -> SE [Ref Sig]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (SE (Ref Sig) -> Sig -> SE (Ref Sig)
forall a b. a -> b -> a
const (SE (Ref Sig) -> Sig -> SE (Ref Sig))
-> SE (Ref Sig) -> Sig -> SE (Ref Sig)
forall a b. (a -> b) -> a -> b
$ Sig -> SE (Ref Sig)
forall a. Tuple a => a -> SE (Ref a)
newGlobalRef (Sig
0 :: Sig)) [Sig]
ids
  [Sig]
currents <- (Ref Sig -> SE Sig) -> [Ref Sig] -> SE [Sig]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Ref Sig -> SE Sig
forall a. Tuple a => Ref a -> SE a
readRef [Ref Sig]
curRefs
  (Output Sig -> Output Sig) -> [Output Sig] -> [Sig] -> SE ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ (\Output Sig
w Sig
val -> Output Sig
w Sig
val) [Output Sig]
writeProcs [Sig]
currents
  let mkReaders :: Output Sig
mkReaders Sig
bpm = (Sig -> Ref Sig -> SE ()) -> [Sig] -> [Ref Sig] -> SE ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ (\Sig
r Ref Sig
ref -> Evt D -> Bam D -> SE ()
forall a. Evt a -> Bam a -> SE ()
runEvt (Sig -> Evt D -> Evt D
forall a. (Default a, Tuple a) => Sig -> Evt a -> Evt a
syncBpm (Sig
bpm Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ D -> Sig
sig (Int -> D
int Int
numBeats)) (Evt D -> Evt D) -> Evt D -> Evt D
forall a b. (a -> b) -> a -> b
$ Sig -> Evt D
snaps Sig
r) (Bam D -> SE ()) -> Bam D -> SE ()
forall a b. (a -> b) -> a -> b
$ \D
x -> do
                          Ref Sig -> Output Sig
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref Sig
ref (D -> Sig
sig D
x)
                        ) [Sig]
readProcs [Ref Sig]
curRefs
  let res :: Sample Sig2
res = (Sig -> Sig2 -> SE Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (Sig -> a -> SE b) -> Sample a -> Sample b
bindBpm (\Sig
bpm Sig2
x -> Output Sig
mkReaders Sig
bpm SE () -> SE Sig2 -> SE Sig2
forall a b. SE a -> SE b -> SE b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Sig2 -> SE Sig2
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return Sig2
x) (Sample Sig2 -> Sample Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ ([Sig2] -> Sig2) -> [Sample Sig2] -> [Evt D] -> Sample Sig2
groupToggles [Sig2] -> Sig2
forall a. Fractional a => [a] -> a
mean [Sample Sig2]
sams ([Evt D] -> Sample Sig2) -> [Evt D] -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ (Sig -> Evt D) -> [Sig] -> [Evt D]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sig -> Evt D
snaps [Sig]
currents
  (Gui, Sample Sig2) -> Source (Sample Sig2)
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Gui] -> Gui
gcat [Gui]
guis, Sample Sig2
res)
  where
    ([Text]
names, [Sample Sig2]
sams, [Bool]
initVals) = [(Text, Sample Sig2, Bool)] -> ([Text], [Sample Sig2], [Bool])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 [(Text, Sample Sig2, Bool)]
as
    ids :: [Sig]
ids = (Int -> Sig) -> [Int] -> [Sig]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (D -> Sig
sig (D -> Sig) -> (Int -> D) -> Int -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> D
int) [Int
1 .. [(Text, Sample Sig2, Bool)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Text, Sample Sig2, Bool)]
as]

-- | A widget for playing several samples at the same time (aka `sim`ultaneously).
-- The first argument is about syncronization.
--
-- > sim n nameAndSamples
--
-- The samples are started only on every n'th beat.
-- The tempo is specified with rendering the sample (see the function @runSam@).
sim :: Int -> [(Text, Sam)] -> Source Sam
sim :: Int -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
sim = ([Gui] -> Gui)
-> Int -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genSim [Gui] -> Gui
ver

-- | It's just like the function @sim@ but the visual representation is horizontal.
-- That's why there is a prefix @h@.
hsim :: Int -> [(Text, Sam)] -> Source Sam
hsim :: Int -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
hsim = ([Gui] -> Gui)
-> Int -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genSim [Gui] -> Gui
hor


-- | It's just like the function `sim` but the user can
-- activate some samples right in the code. If the third
-- element is @True@ the sample is played.
simWith :: Int -> [(Text, Sam, Bool)] -> Source Sam
simWith :: Int -> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
simWith = ([Gui] -> Gui)
-> Int -> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
genSimInits [Gui] -> Gui
ver

-- | It's just like the function `hsimWith` but the visual representation is horizontal.
-- That's why there is a prefix @h@.
hsimWith :: Int -> [(Text, Sam, Bool)] -> Source Sam
hsimWith :: Int -> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
hsimWith = ([Gui] -> Gui)
-> Int -> [(Text, Sample Sig2, Bool)] -> Source (Sample Sig2)
genSimInits [Gui] -> Gui
hor


genTog :: ([Gui] -> Gui) -> Int -> [(Text, Sam)] -> Source Sam
genTog :: ([Gui] -> Gui)
-> Int -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genTog [Gui] -> Gui
gcat Int
numBeats [(Text, Sample Sig2)]
as = ((Gui, Input (Sample Sig2, Ref Sig)) -> (Gui, Sample Sig2))
-> SE (Gui, Input (Sample Sig2, Ref Sig)) -> Source (Sample Sig2)
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Gui
g, Input (Sample Sig2, Ref Sig)
x) -> (Gui
g, Input (Sample Sig2, Ref Sig) -> Sample Sig2
forall a b. (a, b) -> a
fst Input (Sample Sig2, Ref Sig)
x)) (SE (Gui, Input (Sample Sig2, Ref Sig)) -> Source (Sample Sig2))
-> SE (Gui, Input (Sample Sig2, Ref Sig)) -> Source (Sample Sig2)
forall a b. (a -> b) -> a -> b
$ ([Gui] -> Gui)
-> Int
-> [(Text, Sample Sig2)]
-> SE (Gui, Input (Sample Sig2, Ref Sig))
genTogWithRef [Gui] -> Gui
gcat Int
numBeats [(Text, Sample Sig2)]
as

genTogWithRef :: ([Gui] -> Gui) -> Int -> [(Text, Sam)] -> Source (Sam, Ref Sig)
genTogWithRef :: ([Gui] -> Gui)
-> Int
-> [(Text, Sample Sig2)]
-> SE (Gui, Input (Sample Sig2, Ref Sig))
genTogWithRef [Gui] -> Gui
gcat Int
numBeats [(Text, Sample Sig2)]
as = SE (Gui, Input (Sample Sig2, Ref Sig))
-> SE (Gui, Input (Sample Sig2, Ref Sig))
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (SE (Gui, Input (Sample Sig2, Ref Sig))
 -> SE (Gui, Input (Sample Sig2, Ref Sig)))
-> SE (Gui, Input (Sample Sig2, Ref Sig))
-> SE (Gui, Input (Sample Sig2, Ref Sig))
forall a b. (a -> b) -> a -> b
$ do
  ([Gui]
guis, [Output Sig]
writeProcs, [Sig]
readProcs) <- ([(Gui, Output Sig, Sig)] -> ([Gui], [Output Sig], [Sig]))
-> SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig])
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, Output Sig, Sig)] -> ([Gui], [Output Sig], [Sig])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 (SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig]))
-> SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig])
forall a b. (a -> b) -> a -> b
$ (Text -> SE (Gui, Output Sig, Sig))
-> [Text] -> SE [(Gui, Output Sig, Sig)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((Text -> Bool -> SE (Gui, Output Sig, Sig))
-> Bool -> Text -> SE (Gui, Output Sig, Sig)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> Bool -> SE (Gui, Output Sig, Sig)
setToggleSig Bool
False) [Text]
names
  Ref Sig
curRef <- Sig -> SE (Ref Sig)
forall a. Tuple a => a -> SE (Ref a)
newGlobalRef (Sig
0 :: Sig)
  Sig
current <- Ref Sig -> SE Sig
forall a. Tuple a => Ref a -> SE a
readRef Ref Sig
curRef
  (Output Sig -> Output Sig) -> [Output Sig] -> [Sig] -> SE ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ (\Output Sig
w Sig
i -> Output Sig
w Output Sig -> Output Sig
forall a b. (a -> b) -> a -> b
$ BoolSig -> Sig -> Sig -> Sig
forall bool. (bool ~ BooleanOf Sig) => bool -> Sig -> Sig -> Sig
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (Sig
current Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
i) Sig
1 Sig
0) [Output Sig]
writeProcs [Sig]
ids
  let mkReaders :: Output Sig
mkReaders Sig
bpm = (Sig -> Output Sig) -> [Sig] -> [Sig] -> SE ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ (\Sig
r Sig
i -> Evt D -> Bam D -> SE ()
forall a. Evt a -> Bam a -> SE ()
runEvt (Sig -> Evt D -> Evt D
forall a. (Default a, Tuple a) => Sig -> Evt a -> Evt a
syncBpm (Sig
bpm Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ (D -> Sig
sig (D -> Sig) -> D -> Sig
forall a b. (a -> b) -> a -> b
$ Int -> D
int Int
numBeats)) (Evt D -> Evt D) -> Evt D -> Evt D
forall a b. (a -> b) -> a -> b
$ Sig -> Evt D
snaps Sig
r) (Bam D -> SE ()) -> Bam D -> SE ()
forall a b. (a -> b) -> a -> b
$ \D
x -> do
                        BoolSig -> SE () -> SE ()
when1 (D -> Sig
sig D
x Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
0 BoolSig -> BoolSig -> BoolSig
forall b. Boolean b => b -> b -> b
&&* Sig
current Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
i) (SE () -> SE ()) -> SE () -> SE ()
forall a b. (a -> b) -> a -> b
$ do
                          Ref Sig -> Output Sig
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref Sig
curRef Sig
0
                        BoolSig -> SE () -> SE ()
when1 (D -> Sig
sig D
x Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
1) (SE () -> SE ()) -> SE () -> SE ()
forall a b. (a -> b) -> a -> b
$ do
                          Ref Sig -> Output Sig
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref Sig
curRef Sig
i
                        ) [Sig]
readProcs [Sig]
ids

  let res :: Sample Sig2
res = (Sig -> Sig2 -> SE Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (Sig -> a -> SE b) -> Sample a -> Sample b
bindBpm (\Sig
bpm Sig2
x -> Output Sig
mkReaders Sig
bpm SE () -> SE Sig2 -> SE Sig2
forall a b. SE a -> SE b -> SE b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Sig2 -> SE Sig2
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return Sig2
x) (Sample Sig2 -> Sample Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ ([Sig2] -> Sig2) -> [Sample Sig2] -> [Evt D] -> Sample Sig2
groupToggles [Sig2] -> Sig2
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Sample Sig2]
sams ([Evt D] -> Sample Sig2) -> [Evt D] -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ (Sig -> Evt D) -> [Sig] -> [Evt D]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> Evt D
snaps (Sig -> Evt D) -> (Sig -> Sig) -> Sig -> Evt D
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\Sig
i -> BoolSig -> Sig -> Sig -> Sig
forall bool. (bool ~ BooleanOf Sig) => bool -> Sig -> Sig -> Sig
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (Sig
current Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
i) Sig
1 Sig
0)) [Sig]
ids
  (Gui, Input (Sample Sig2, Ref Sig))
-> SE (Gui, Input (Sample Sig2, Ref Sig))
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Gui] -> Gui
gcat [Gui]
guis, (Sample Sig2
res, Ref Sig
curRef))
  where
    ([Text]
names, [Sample Sig2]
sams) = [(Text, Sample Sig2)] -> ([Text], [Sample Sig2])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Text, Sample Sig2)]
as
    ids :: [Sig]
ids = (Int -> Sig) -> [Int] -> [Sig]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (D -> Sig
sig (D -> Sig) -> (Int -> D) -> Int -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> D
int) [Int
1 .. [(Text, Sample Sig2)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Text, Sample Sig2)]
as]

-- | A widget to toggle playing of several samples. The switch
-- of the playing is synchronized with each n'th beat where
-- n is the first argument of the function.
tog :: Int -> [(Text, Sam)] -> Source Sam
tog :: Int -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
tog = ([Gui] -> Gui)
-> Int -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genTog [Gui] -> Gui
ver

-- | It's just like the function @tog@ but the visual representation is horizontal.
-- That's why there is a prefix @h@.
htog :: Int -> [(Text, Sam)] -> Source Sam
htog :: Int -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
htog = ([Gui] -> Gui)
-> Int -> [(Text, Sample Sig2)] -> Source (Sample Sig2)
genTog [Gui] -> Gui
hor

-- | The widget resembles the Ableton Live session view.
-- We create a matrix of samples. we can toggle the samples in
-- each row and we can start playing the whole row of samples.
--
-- > live n groupNames samples
--
-- The first argument is for synchroization. we can start samples
-- only on every n'th beat. The second argument gives names to the columns.
-- the length of the list is the number of columns.
-- the column represents samples that belong to the same group.
-- The third argument is a list of samples. It represents the matrix of samples
-- in row-wise fashion.
live :: Int -> [Text] -> [Sam] -> Source Sam
live :: Int -> [Text] -> [Sample Sig2] -> Source (Sample Sig2)
live Int
numBeats [Text]
names [Sample Sig2]
sams = Source (Sample Sig2) -> Source (Sample Sig2)
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source (Sample Sig2) -> Source (Sample Sig2))
-> Source (Sample Sig2) -> Source (Sample Sig2)
forall a b. (a -> b) -> a -> b
$ do
  ([Gui]
gVols, [Sig]
vols) <- ([(Gui, Sig)] -> ([Gui], [Sig]))
-> SE [(Gui, Sig)] -> SE ([Gui], [Sig])
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, Sig)] -> ([Gui], [Sig])
forall a b. [(a, b)] -> ([a], [b])
unzip (SE [(Gui, Sig)] -> SE ([Gui], [Sig]))
-> SE [(Gui, Sig)] -> SE ([Gui], [Sig])
forall a b. (a -> b) -> a -> b
$  (Text -> SE (Gui, Sig)) -> [Text] -> SE [(Gui, Sig)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM  Text -> SE (Gui, Sig)
defSlider ([Text] -> SE [(Gui, Sig)]) -> [Text] -> SE [(Gui, Sig)]
forall a b. (a -> b) -> a -> b
$ Int -> Text -> [Text]
forall a. Int -> a -> [a]
replicate Int
n Text
"vol"
  ([Gui]
gs, [Input (Sample Sig2, Ref Sig)]
xs) <- ([(Gui, Input (Sample Sig2, Ref Sig))]
 -> ([Gui], [Input (Sample Sig2, Ref Sig)]))
-> SE [(Gui, Input (Sample Sig2, Ref Sig))]
-> SE ([Gui], [Input (Sample Sig2, Ref Sig)])
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, Input (Sample Sig2, Ref Sig))]
-> ([Gui], [Input (Sample Sig2, Ref Sig)])
forall a b. [(a, b)] -> ([a], [b])
unzip (SE [(Gui, Input (Sample Sig2, Ref Sig))]
 -> SE ([Gui], [Input (Sample Sig2, Ref Sig)]))
-> SE [(Gui, Input (Sample Sig2, Ref Sig))]
-> SE ([Gui], [Input (Sample Sig2, Ref Sig)])
forall a b. (a -> b) -> a -> b
$ ((Text, Gui)
 -> [Sample Sig2] -> SE (Gui, Input (Sample Sig2, Ref Sig)))
-> [(Text, Gui)]
-> [[Sample Sig2]]
-> SE [(Gui, Input (Sample Sig2, Ref Sig))]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (\(Text, Gui)
a [Sample Sig2]
b -> Int
-> (Text, Gui)
-> [Sample Sig2]
-> SE (Gui, Input (Sample Sig2, Ref Sig))
mkLiveRow Int
numBeats (Text, Gui)
a [Sample Sig2]
b) ([Text] -> [Gui] -> [(Text, Gui)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Text]
names [Gui]
gVols) [[Sample Sig2]]
rows
  let ([Sample Sig2]
sigs, [Ref Sig]
refs) = [Input (Sample Sig2, Ref Sig)] -> ([Sample Sig2], [Ref Sig])
forall a b. [(a, b)] -> ([a], [b])
unzip [Input (Sample Sig2, Ref Sig)]
xs
  (Gui
gMaster, Sig
masterVol) <- Text -> SE (Gui, Sig)
defSlider Text
"master"
  (Gui
g, Output Sig
proc) <- Int -> Gui -> [Sig] -> [Ref Sig] -> SE (Gui, Output Sig)
mkLiveSceneRow Int
numBeats Gui
gMaster [Sig]
ids [Ref Sig]
refs
  (Gui, Sample Sig2) -> Source (Sample Sig2)
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Gui, Sample Sig2) -> Source (Sample Sig2))
-> (Gui, Sample Sig2) -> Source (Sample Sig2)
forall a b. (a -> b) -> a -> b
$ ([Gui] -> Gui
hor ([Gui] -> Gui) -> [Gui] -> Gui
forall a b. (a -> b) -> a -> b
$ Gui
g Gui -> [Gui] -> [Gui]
forall a. a -> [a] -> [a]
: [Gui]
gs, (Sig -> Sig2 -> SE Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (Sig -> a -> SE b) -> Sample a -> Sample b
bindBpm (\Sig
bpm Sig2
asig -> Output Sig
proc Sig
bpm SE () -> SE Sig2 -> SE Sig2
forall a b. SE a -> SE b -> SE b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Sig2 -> SE Sig2
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return Sig2
asig) (Sample Sig2 -> Sample Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ Sig -> Sample Sig2 -> Sample Sig2
forall a. SigSpace a => Sig -> a -> a
mul Sig
masterVol (Sample Sig2 -> Sample Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ [Sample Sig2] -> Sample Sig2
forall a. Fractional a => [a] -> a
mean ([Sample Sig2] -> Sample Sig2) -> [Sample Sig2] -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ (Sig -> Sample Sig2 -> Sample Sig2)
-> [Sig] -> [Sample Sig2] -> [Sample Sig2]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Sig -> Sample Sig2 -> Sample Sig2
forall a. SigSpace a => Sig -> a -> a
mul [Sig]
vols [Sample Sig2]
sigs)
  where
    rows :: [[Sample Sig2]]
rows = [[Sample Sig2]] -> [[Sample Sig2]]
forall a. [[a]] -> [[a]]
transpose ([[Sample Sig2]] -> [[Sample Sig2]])
-> [[Sample Sig2]] -> [[Sample Sig2]]
forall a b. (a -> b) -> a -> b
$ Int -> [Sample Sig2] -> [[Sample Sig2]]
forall a. Int -> [a] -> [[a]]
splitRows Int
n [Sample Sig2]
sams
    ids :: [Sig]
ids = (Int -> Sig) -> [Int] -> [Sig]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (D -> Sig
sig (D -> Sig) -> (Int -> D) -> Int -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> D
int) [Int
1 .. [Sample Sig2] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([[Sample Sig2]] -> [Sample Sig2]
forall a. HasCallStack => [a] -> a
head [[Sample Sig2]]
rows)]
    n :: Int
n = [Text] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
names

mkLiveRow :: Int -> (Text, Gui) -> [Sam] -> Source (Sam, Ref Sig)
mkLiveRow :: Int
-> (Text, Gui)
-> [Sample Sig2]
-> SE (Gui, Input (Sample Sig2, Ref Sig))
mkLiveRow Int
numBeats (Text
name, Gui
gVol) [Sample Sig2]
as = ([Gui] -> Gui)
-> Int
-> [(Text, Sample Sig2)]
-> SE (Gui, Input (Sample Sig2, Ref Sig))
genTogWithRef (\[Gui]
xs -> [Gui] -> Gui
ver ([Gui] -> Gui) -> [Gui] -> Gui
forall a b. (a -> b) -> a -> b
$ [Gui]
xs [Gui] -> [Gui] -> [Gui]
forall a. [a] -> [a] -> [a]
++ [Gui
gVol]) Int
numBeats ([Text] -> [Sample Sig2] -> [(Text, Sample Sig2)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Text
name Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: Text -> [Text]
forall a. a -> [a]
repeat Text
"") [Sample Sig2]
as)

mkLiveSceneRow :: Int -> Gui -> [Sig] -> [Ref Sig] -> SE (Gui, Sig -> SE ())
mkLiveSceneRow :: Int -> Gui -> [Sig] -> [Ref Sig] -> SE (Gui, Output Sig)
mkLiveSceneRow Int
numBeats Gui
gMaster [Sig]
ids [Ref Sig]
refs = do
  ([Gui]
guis, [Output Sig]
writeProcs, [Sig]
readProcs) <- ([(Gui, Output Sig, Sig)] -> ([Gui], [Output Sig], [Sig]))
-> SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig])
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, Output Sig, Sig)] -> ([Gui], [Output Sig], [Sig])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 (SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig]))
-> SE [(Gui, Output Sig, Sig)] -> SE ([Gui], [Output Sig], [Sig])
forall a b. (a -> b) -> a -> b
$ (Text -> SE (Gui, Output Sig, Sig))
-> [Text] -> SE [(Gui, Output Sig, Sig)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((Text -> Bool -> SE (Gui, Output Sig, Sig))
-> Bool -> Text -> SE (Gui, Output Sig, Sig)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> Bool -> SE (Gui, Output Sig, Sig)
setToggleSig Bool
False) [Text]
names
  Ref Sig
curRef <- Sig -> SE (Ref Sig)
forall a. Tuple a => a -> SE (Ref a)
newGlobalRef (Sig
0 :: Sig)
  Sig
current <- Ref Sig -> SE Sig
forall a. Tuple a => Ref a -> SE a
readRef Ref Sig
curRef
  (Output Sig -> Output Sig) -> [Output Sig] -> [Sig] -> SE ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ (\Output Sig
w Sig
i -> Output Sig
w Output Sig -> Output Sig
forall a b. (a -> b) -> a -> b
$ BoolSig -> Sig -> Sig -> Sig
forall bool. (bool ~ BooleanOf Sig) => bool -> Sig -> Sig -> Sig
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (Sig
current Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
i) Sig
1 Sig
0) [Output Sig]
writeProcs [Sig]
ids
  let mkReaders :: Output Sig
mkReaders Sig
bpm = (Sig -> Output Sig) -> [Sig] -> [Sig] -> SE ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ (\Sig
r Sig
i -> Evt D -> Bam D -> SE ()
forall a. Evt a -> Bam a -> SE ()
runEvt (Sig -> Evt D -> Evt D
forall a. (Default a, Tuple a) => Sig -> Evt a -> Evt a
syncBpm (Sig
bpm Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ D -> Sig
sig (Int -> D
int Int
numBeats)) (Evt D -> Evt D) -> Evt D -> Evt D
forall a b. (a -> b) -> a -> b
$ Sig -> Evt D
snaps Sig
r) (Bam D -> SE ()) -> Bam D -> SE ()
forall a b. (a -> b) -> a -> b
$ \D
x -> do
                        BoolSig -> SE () -> SE ()
when1 (D -> Sig
sig D
x Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
0 BoolSig -> BoolSig -> BoolSig
forall b. Boolean b => b -> b -> b
&&* Sig
current Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
i) (SE () -> SE ()) -> SE () -> SE ()
forall a b. (a -> b) -> a -> b
$ do
                          Ref Sig -> Output Sig
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref Sig
curRef Sig
0
                          (Ref Sig -> SE ()) -> [Ref Sig] -> SE ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((Ref Sig -> Output Sig) -> Sig -> Ref Sig -> SE ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ref Sig -> Output Sig
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Sig
0) [Ref Sig]
refs
                        BoolSig -> SE () -> SE ()
when1 (D -> Sig
sig D
x Sig -> Sig -> BoolSig
forall bool. (bool ~ BooleanOf Sig) => Sig -> Sig -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* Sig
1) (SE () -> SE ()) -> SE () -> SE ()
forall a b. (a -> b) -> a -> b
$ do
                          Ref Sig -> Output Sig
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref Sig
curRef Sig
i
                          (Ref Sig -> SE ()) -> [Ref Sig] -> SE ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((Ref Sig -> Output Sig) -> Sig -> Ref Sig -> SE ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ref Sig -> Output Sig
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Sig
i) [Ref Sig]
refs
                        ) [Sig]
readProcs [Sig]
ids

  (Gui, Output Sig) -> SE (Gui, Output Sig)
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Gui] -> Gui
ver ([Gui] -> Gui) -> [Gui] -> Gui
forall a b. (a -> b) -> a -> b
$ [Gui]
guis [Gui] -> [Gui] -> [Gui]
forall a. [a] -> [a] -> [a]
++ [Gui
gMaster], Output Sig
mkReaders)
  where
    names :: [Text]
names = Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
take Int
len ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ (Int -> Text) -> [Int] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> (Int -> String) -> Int -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show) [(Int
1::Int) ..]
    len :: Int
len = [Sig] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Sig]
ids

splitRows :: Int -> [a] -> [[a]]
splitRows :: forall a. Int -> [a] -> [[a]]
splitRows Int
n [a]
as
  | [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
as Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = []
  | Bool
otherwise     = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
n [a]
as [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: Int -> [a] -> [[a]]
forall a. Int -> [a] -> [[a]]
splitRows Int
n (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop Int
n [a]
as)

defSlider :: Text -> Source Sig
defSlider :: Text -> SE (Gui, Sig)
defSlider Text
tag = Text -> ValSpan -> Double -> SE (Gui, Sig)
slider Text
tag (Double -> Double -> ValSpan
linSpan Double
0 Double
1) Double
0.5

-- | It's just like the function @live@ but we can provide the list
-- of effects for each column. The double value specifies the mix
-- between dry and wet signals.
liveEf :: Int -> [Text] -> [Sam] -> (Double, Fx2) -> [(Double, Fx2)] -> Source Sam
liveEf :: Int
-> [Text]
-> [Sample Sig2]
-> (Double, Sig2 -> SE Sig2)
-> [(Double, Sig2 -> SE Sig2)]
-> Source (Sample Sig2)
liveEf Int
numBeats [Text]
names [Sample Sig2]
sams (Double, Sig2 -> SE Sig2)
masterEff [(Double, Sig2 -> SE Sig2)]
effs = Source (Sample Sig2) -> Source (Sample Sig2)
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source (Sample Sig2) -> Source (Sample Sig2))
-> Source (Sample Sig2) -> Source (Sample Sig2)
forall a b. (a -> b) -> a -> b
$ do
  ([Gui]
gVols, [Sig]
vols) <- ([(Gui, Sig)] -> ([Gui], [Sig]))
-> SE [(Gui, Sig)] -> SE ([Gui], [Sig])
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, Sig)] -> ([Gui], [Sig])
forall a b. [(a, b)] -> ([a], [b])
unzip (SE [(Gui, Sig)] -> SE ([Gui], [Sig]))
-> SE [(Gui, Sig)] -> SE ([Gui], [Sig])
forall a b. (a -> b) -> a -> b
$  (Text -> SE (Gui, Sig)) -> [Text] -> SE [(Gui, Sig)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Text -> SE (Gui, Sig)
defSlider ([Text] -> SE [(Gui, Sig)]) -> [Text] -> SE [(Gui, Sig)]
forall a b. (a -> b) -> a -> b
$ Int -> Text -> [Text]
forall a. Int -> a -> [a]
replicate Int
n Text
"vol"
  ([Gui]
gEffs, [Sig]
effCtrls) <- ([(Gui, Sig)] -> ([Gui], [Sig]))
-> SE [(Gui, Sig)] -> SE ([Gui], [Sig])
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, Sig)] -> ([Gui], [Sig])
forall a b. [(a, b)] -> ([a], [b])
unzip (SE [(Gui, Sig)] -> SE ([Gui], [Sig]))
-> SE [(Gui, Sig)] -> SE ([Gui], [Sig])
forall a b. (a -> b) -> a -> b
$
    ((Text, Double) -> SE (Gui, Sig))
-> [(Text, Double)] -> SE [(Gui, Sig)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\(Text
tag, Double
initVal) -> Text -> ValSpan -> Double -> SE (Gui, Sig)
slider Text
tag (Double -> Double -> ValSpan
linSpan Double
0 Double
1) Double
initVal) ([(Text, Double)] -> SE [(Gui, Sig)])
-> [(Text, Double)] -> SE [(Gui, Sig)]
forall a b. (a -> b) -> a -> b
$ [Text] -> [Double] -> [(Text, Double)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Int -> Text -> [Text]
forall a. Int -> a -> [a]
replicate Int
n Text
"eff") (((Double, Sig2 -> SE Sig2) -> Double)
-> [(Double, Sig2 -> SE Sig2)] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Double, Sig2 -> SE Sig2) -> Double
forall a b. (a, b) -> a
fst [(Double, Sig2 -> SE Sig2)]
effs)
  let gCtrls :: [Gui]
gCtrls = (Gui -> Gui -> Gui) -> [Gui] -> [Gui] -> [Gui]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Gui -> Gui -> Gui
ctrlGui [Gui]
gEffs [Gui]
gVols
  ([Gui]
gs, [Input (Sample Sig2, Ref Sig)]
xs) <- ([(Gui, Input (Sample Sig2, Ref Sig))]
 -> ([Gui], [Input (Sample Sig2, Ref Sig)]))
-> SE [(Gui, Input (Sample Sig2, Ref Sig))]
-> SE ([Gui], [Input (Sample Sig2, Ref Sig)])
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, Input (Sample Sig2, Ref Sig))]
-> ([Gui], [Input (Sample Sig2, Ref Sig)])
forall a b. [(a, b)] -> ([a], [b])
unzip (SE [(Gui, Input (Sample Sig2, Ref Sig))]
 -> SE ([Gui], [Input (Sample Sig2, Ref Sig)]))
-> SE [(Gui, Input (Sample Sig2, Ref Sig))]
-> SE ([Gui], [Input (Sample Sig2, Ref Sig)])
forall a b. (a -> b) -> a -> b
$ ((Text, Gui)
 -> [Sample Sig2] -> SE (Gui, Input (Sample Sig2, Ref Sig)))
-> [(Text, Gui)]
-> [[Sample Sig2]]
-> SE [(Gui, Input (Sample Sig2, Ref Sig))]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (\(Text, Gui)
a [Sample Sig2]
b -> Int
-> (Text, Gui)
-> [Sample Sig2]
-> SE (Gui, Input (Sample Sig2, Ref Sig))
mkLiveRow Int
numBeats (Text, Gui)
a [Sample Sig2]
b) ([Text] -> [Gui] -> [(Text, Gui)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Text]
names [Gui]
gCtrls) [[Sample Sig2]]
rows
  let ([Sample Sig2]
sigs, [Ref Sig]
refs) = [Input (Sample Sig2, Ref Sig)] -> ([Sample Sig2], [Ref Sig])
forall a b. [(a, b)] -> ([a], [b])
unzip [Input (Sample Sig2, Ref Sig)]
xs
  (Gui
gMaster, Sig
masterVol) <- Text -> SE (Gui, Sig)
defSlider Text
"master"
  (Gui
gMasterEff, Sig
masterEffCtrl) <- Text -> ValSpan -> Double -> SE (Gui, Sig)
slider Text
"eff" (Double -> Double -> ValSpan
linSpan Double
0 Double
1) ((Double, Sig2 -> SE Sig2) -> Double
forall a b. (a, b) -> a
fst (Double, Sig2 -> SE Sig2)
masterEff)
  (Gui
g, Output Sig
proc) <- Int -> Gui -> [Sig] -> [Ref Sig] -> SE (Gui, Output Sig)
mkLiveSceneRow Int
numBeats (Gui -> Gui -> Gui
ctrlGui Gui
gMasterEff Gui
gMaster) [Sig]
ids [Ref Sig]
refs
  (Gui, Sample Sig2) -> Source (Sample Sig2)
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Gui, Sample Sig2) -> Source (Sample Sig2))
-> (Gui, Sample Sig2) -> Source (Sample Sig2)
forall a b. (a -> b) -> a -> b
$ ([Gui] -> Gui
hor ([Gui] -> Gui) -> [Gui] -> Gui
forall a b. (a -> b) -> a -> b
$ Gui
g Gui -> [Gui] -> [Gui]
forall a. a -> [a] -> [a]
: [Gui]
gs, (Sig -> Sig2 -> SE Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (Sig -> a -> SE b) -> Sample a -> Sample b
bindBpm (\Sig
bpm Sig2
asig -> Output Sig
proc Sig
bpm SE () -> SE Sig2 -> SE Sig2
forall a b. SE a -> SE b -> SE b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Sig2 -> SE Sig2
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return Sig2
asig) (Sample Sig2 -> Sample Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (a -> b) -> a -> b
$
    Sig -> Sample Sig2 -> Sample Sig2
forall a. SigSpace a => Sig -> a -> a
mul Sig
masterVol (Sample Sig2 -> Sample Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ (Sig2 -> SE Sig2) -> Sig -> Sample Sig2 -> Sample Sig2
forall {t}.
(Num t, SigSpace t, SigSpace (SE t)) =>
(t -> SE t) -> Sig -> Sample t -> Sample t
appEff ((Double, Sig2 -> SE Sig2) -> Sig2 -> SE Sig2
forall a b. (a, b) -> b
snd  (Double, Sig2 -> SE Sig2)
masterEff) Sig
masterEffCtrl (Sample Sig2 -> Sample Sig2) -> Sample Sig2 -> Sample Sig2
forall a b. (a -> b) -> a -> b
$
    [Sample Sig2] -> Sample Sig2
forall a. Fractional a => [a] -> a
mean ([Sample Sig2] -> Sample Sig2) -> [Sample Sig2] -> Sample Sig2
forall a b. (a -> b) -> a -> b
$ (Sig -> Sample Sig2 -> Sample Sig2)
-> [Sig] -> [Sample Sig2] -> [Sample Sig2]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Sig -> Sample Sig2 -> Sample Sig2
forall a. SigSpace a => Sig -> a -> a
mul [Sig]
vols ([Sample Sig2] -> [Sample Sig2]) -> [Sample Sig2] -> [Sample Sig2]
forall a b. (a -> b) -> a -> b
$ ((Sig2 -> SE Sig2, Sig) -> Sample Sig2 -> Sample Sig2)
-> [(Sig2 -> SE Sig2, Sig)] -> [Sample Sig2] -> [Sample Sig2]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (((Sig2 -> SE Sig2) -> Sig -> Sample Sig2 -> Sample Sig2)
-> (Sig2 -> SE Sig2, Sig) -> Sample Sig2 -> Sample Sig2
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Sig2 -> SE Sig2) -> Sig -> Sample Sig2 -> Sample Sig2
forall {t}.
(Num t, SigSpace t, SigSpace (SE t)) =>
(t -> SE t) -> Sig -> Sample t -> Sample t
appEff) ([Sig2 -> SE Sig2] -> [Sig] -> [(Sig2 -> SE Sig2, Sig)]
forall a b. [a] -> [b] -> [(a, b)]
zip (((Double, Sig2 -> SE Sig2) -> Sig2 -> SE Sig2)
-> [(Double, Sig2 -> SE Sig2)] -> [Sig2 -> SE Sig2]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Double, Sig2 -> SE Sig2) -> Sig2 -> SE Sig2
forall a b. (a, b) -> b
snd [(Double, Sig2 -> SE Sig2)]
effs) [Sig]
effCtrls) [Sample Sig2]
sigs)
  where
    rows :: [[Sample Sig2]]
rows = [[Sample Sig2]] -> [[Sample Sig2]]
forall a. [[a]] -> [[a]]
transpose ([[Sample Sig2]] -> [[Sample Sig2]])
-> [[Sample Sig2]] -> [[Sample Sig2]]
forall a b. (a -> b) -> a -> b
$ Int -> [Sample Sig2] -> [[Sample Sig2]]
forall a. Int -> [a] -> [[a]]
splitRows Int
n [Sample Sig2]
sams
    ids :: [Sig]
ids = (Int -> Sig) -> [Int] -> [Sig]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (D -> Sig
sig (D -> Sig) -> (Int -> D) -> Int -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> D
int) [Int
1 .. [Sample Sig2] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([[Sample Sig2]] -> [Sample Sig2]
forall a. HasCallStack => [a] -> a
head [[Sample Sig2]]
rows)]
    n :: Int
n = [Text] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
names

    appEff :: (t -> SE t) -> Sig -> Sample t -> Sample t
appEff t -> SE t
f Sig
depth Sample t
a = (t -> SE t) -> Sample t -> Sample t
forall a b. (a -> SE b) -> Sample a -> Sample b
bindSam (\t
x -> (t -> t) -> SE t -> SE t
forall a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\t
y -> t
y t -> t -> t
forall a. Num a => a -> a -> a
+ (Sig -> t -> t
forall a. SigSpace a => Sig -> a -> a
mul (Sig
1 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
- Sig
depth) t
x)) (SE t -> SE t) -> SE t -> SE t
forall a b. (a -> b) -> a -> b
$ Sig -> SE t -> SE t
forall a. SigSpace a => Sig -> a -> a
mul Sig
depth (SE t -> SE t) -> SE t -> SE t
forall a b. (a -> b) -> a -> b
$ t -> SE t
f t
x) Sample t
a

    ctrlGui :: Gui -> Gui -> Gui
ctrlGui Gui
ef Gui
vol = Double -> Gui -> Gui
sca Double
2.5 (Gui -> Gui) -> Gui -> Gui
forall a b. (a -> b) -> a -> b
$ [Gui] -> Gui
ver [Gui
ef, Gui
vol]

-- | It's useful to convert samples to signals an insert
-- them in the widget @mixer@.
mixSam :: Text -> Bpm -> Sam -> (Text, SE Sig2)
mixSam :: Text -> Sig -> Sample Sig2 -> (Text, SE Sig2)
mixSam Text
name Sig
bpm Sample Sig2
sam = (Text
name, Sig -> Sample Sig2 -> SE Sig2
runSam Sig
bpm Sample Sig2
sam)

-- | Creates fx-unit from sampler widget.
--
-- > uisam name isOn bpm samWidget
uiSam :: Text -> Bool -> Sig -> Source Sam -> Source Fx2
uiSam :: Text
-> Bool -> Sig -> Source (Sample Sig2) -> Source (Sig2 -> SE Sig2)
uiSam Text
name Bool
onOff Sig
bpm Source (Sample Sig2)
sam = Text -> Bool -> Source Sig2 -> Source (Sig2 -> SE Sig2)
forall a. Sigs a => Text -> Bool -> Source a -> Source (Fx a)
uiSig Text
name Bool
onOff (Source (SE Sig2) -> Source Sig2
forall a. Source (SE a) -> Source a
joinSource (Source (SE Sig2) -> Source Sig2)
-> Source (SE Sig2) -> Source Sig2
forall a b. (a -> b) -> a -> b
$ (Sample Sig2 -> SE Sig2)
-> Source (Sample Sig2) -> Source (SE Sig2)
forall a b. (a -> b) -> Source a -> Source b
mapSource (Sig -> Sample Sig2 -> SE Sig2
runSam Sig
bpm) Source (Sample Sig2)
sam)

-- | Adds gain slider on top of the widget.
addGain :: SigSpace a => Source a -> Source a
addGain :: forall a. SigSpace a => Source a -> Source a
addGain Source a
x = Source a -> Source a
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source a -> Source a) -> Source a -> Source a
forall a b. (a -> b) -> a -> b
$ do
  (Gui
g, a
asig) <- Source a
x
  (Gui
gainGui, Sig
gainSig) <- Text -> ValSpan -> Double -> SE (Gui, Sig)
slider Text
"gain" (Double -> Double -> ValSpan
linSpan Double
0 Double
1) Double
0.5
  (Gui, a) -> Source a
forall a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Gui] -> Gui
ver [Double -> Gui -> Gui
sca Double
0.15 Gui
gainGui, Gui
g], Sig -> a -> a
forall a. SigSpace a => Sig -> a -> a
mul Sig
gainSig a
asig)