{-# OPTIONS_GHC -fno-warn-orphans #-}
-- | The sampler
{-# Language TypeFamilies, DeriveFunctor, TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses #-}
module Csound.Sam (
  Sample, Sam, Bpm, runSam,
  -- * Lifters
  mapBpm, bindSam, bindBpm, liftSam, mapBpm2, bindBpm2, withBpm,
  -- * Constructors
  sig1, sig2, infSig1, infSig2, fromSig1, fromSig2, ToSam(..), limSam,
  -- ** Stereo
  wav, wavr, seg, segr, rndWav, rndWavr, rndSeg, rndSegr, ramWav,
  -- ** Mono
  wav1, wavr1, seg1, segr1, rndWav1, rndWavr1, rndSeg1, rndSegr1, ramWav1,
  -- * Reading from RAM
  -- ** Stereo
  ramLoop, ramRead, segLoop, segRead, relLoop, relRead,
  -- ** Mono
  ramLoop1, ramRead1, segLoop1, segRead1, relLoop1, relRead1,

    -- ** Tempo/pitch scaling based on temposcal
    wavScale, wavScale1, drumScale, drumScale1, harmScale, harmScale1,
  -- * Envelopes
  linEnv, expEnv, hatEnv, decEnv, riseEnv, edecEnv, eriseEnv,
  -- * Arrange
  wide, flow, pick, pickBy,
  atPan, atPch, atCps, atPanRnd, atVolRnd, atVolGauss,
  -- * Loops
  rep1, rep, pat1, pat, pat', rndPat, rndPat',
  -- * Arpeggio
    Chord,
  arpUp, arpDown, arpOneOf, arpFreqOf,
  arpUp1, arpDown1, arpOneOf1, arpFreqOf1,
    -- * Misc patterns
    wall, forAirports, genForAirports, arpy,

    -- * Utils
    metroS, toSec,

    -- * UIs
    module Csound.Sam.Ui,

    -- * Triggering samples
    module Csound.Sam.Trig
) where

import Control.Monad.Trans.Class
import Control.Monad.Trans.Reader

import Csound.Base hiding (pitch, tempo, dur)
import Csound.Sam.Core
import Csound.Sam.Ui
import Csound.Sam.Trig

type instance DurOf Sam = Sig

instance Melody Sam where
  mel :: [Sam] -> Sam
mel = [Sam] -> Sam
flow

instance Harmony Sam where
  =:= :: Sam -> Sam -> Sam
(=:=) = Sam -> Sam -> Sam
forall a. Num a => a -> a -> a
(+)

instance Compose Sam where

instance Delay Sam where
  del :: DurOf Sam -> Sam -> Sam
del DurOf Sam
dt = (Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam
tfmS ((Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam)
-> (Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm S Sig2
x ->
    let absDt :: Bpm
absDt = Bpm -> Bpm -> Bpm
toSec Bpm
bpm DurOf Sam
Bpm
dt
        asig :: Sig2
asig  = Bpm -> Sig2 -> Sig2
forall a. Sigs a => Bpm -> a -> a
delaySnd Bpm
absDt (Sig2 -> Sig2) -> Sig2 -> Sig2
forall a b. (a -> b) -> a -> b
$ S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
x
        dur :: Dur
dur   = Bpm -> Dur -> Dur
addDur Bpm
absDt (Dur -> Dur) -> Dur -> Dur
forall a b. (a -> b) -> a -> b
$ S Sig2 -> Dur
forall a. S a -> Dur
samDur S Sig2
x
    in  S Sig2
x { samSig :: Sig2
samSig = Sig2
asig, samDur :: Dur
samDur = Dur
dur }

instance Stretch Sam where
  str :: DurOf Sam -> Sam -> Sam
str DurOf Sam
k (Sam ReaderT Bpm SE (S Sig2)
a) = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ (Bpm -> Bpm) -> ReaderT Bpm SE (S Sig2) -> ReaderT Bpm SE (S Sig2)
forall r' r (m :: * -> *) a.
(r' -> r) -> ReaderT r m a -> ReaderT r' m a
withReaderT ( Bpm -> Bpm -> Bpm
forall a. Num a => a -> a -> a
* DurOf Sam
Bpm
k) ReaderT Bpm SE (S Sig2)
a

instance Limit Sam where
  lim :: DurOf Sam -> Sam -> Sam
lim DurOf Sam
d = (Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam
tfmS ((Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam)
-> (Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm S Sig2
x ->
    let absD :: Bpm
absD = Bpm -> Bpm -> Bpm
toSec Bpm
bpm DurOf Sam
Bpm
d
    in  S Sig2
x { samSig :: Sig2
samSig = Bpm -> Sig2 -> Sig2
forall a. Sigs a => Bpm -> a -> a
takeSnd Bpm
absD (Sig2 -> Sig2) -> Sig2 -> Sig2
forall a b. (a -> b) -> a -> b
$ S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
x
        , samDur :: Dur
samDur = Bpm -> Dur
Dur Bpm
absD }

instance Loop Sam where
  loop :: Sam -> Sam
loop = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
_ Bpm
d Sig2
asig -> Bpm -> Sig2 -> Sig2
forall a. Sigs a => Bpm -> a -> a
repeatSnd Bpm
d Sig2
asig

instance Rest Sam where
  rest :: DurOf Sam -> Sam
rest DurOf Sam
dt = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ (Bpm -> S Sig2) -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
reader ((Bpm -> S Sig2) -> ReaderT Bpm SE (S Sig2))
-> (Bpm -> S Sig2) -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm -> Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S Sig2
0 (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Bpm
toSec Bpm
bpm DurOf Sam
Bpm
dt)

instance At Sig2 Sig2 Sam where
  type AtOut Sig2 Sig2 Sam = Sam
  at :: (Sig2 -> Sig2) -> Sam -> AtOut Sig2 Sig2 Sam
at Sig2 -> Sig2
f Sam
x = (Sig2 -> Sig2) -> Sam -> Sam
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sig2 -> Sig2
f Sam
x

instance At Sig2 (SE Sig2) Sam where
  type AtOut Sig2 (SE Sig2) Sam = Sam
  at :: (Sig2 -> SE Sig2) -> Sam -> AtOut Sig2 (SE Sig2) Sam
at Sig2 -> SE Sig2
f Sam
x = (Sig2 -> SE Sig2) -> Sam -> Sam
forall a b. (a -> SE b) -> Sample a -> Sample b
bindSam Sig2 -> SE Sig2
f Sam
x

instance At Sig (SE Sig) Sam where
  type AtOut Sig (SE Sig) Sam = Sam
  at :: (Bpm -> SE Bpm) -> Sam -> AtOut Bpm (SE Bpm) Sam
at Bpm -> SE Bpm
f Sam
x = Sample (SE Sig2) -> Sam
forall a. Sample (SE a) -> Sample a
liftSam (Sample (SE Sig2) -> Sam) -> Sample (SE Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ (Sig2 -> SE Sig2) -> Sam -> Sample (SE Sig2)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Bpm -> SE Bpm) -> Sig2 -> AtOut Bpm (SE Bpm) Sig2
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Bpm -> SE Bpm
f) Sam
x

instance At Sig Sig2 Sam where
  type AtOut Sig Sig2 Sam = Sam
  at :: (Bpm -> Sig2) -> Sam -> AtOut Bpm Sig2 Sam
at Bpm -> Sig2
f Sam
x = (Sig2 -> Sig2) -> Sam -> AtOut Sig2 Sig2 Sam
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig2 -> Sig2
phi Sam
x
    where
      phi :: Sig2 -> Sig2
phi (Bpm
a, Bpm
b) = Sig2
0.5 Sig2 -> Sig2 -> Sig2
forall a. Num a => a -> a -> a
* (Bpm -> Sig2
f Bpm
a Sig2 -> Sig2 -> Sig2
forall a. Num a => a -> a -> a
+ Bpm -> Sig2
f Bpm
b)

instance At Sig (SE Sig2) Sam where
  type AtOut Sig (SE Sig2) Sam = Sam
  at :: (Bpm -> SE Sig2) -> Sam -> AtOut Bpm (SE Sig2) Sam
at Bpm -> SE Sig2
f Sam
x = (Sig2 -> SE Sig2) -> Sam -> AtOut Sig2 (SE Sig2) Sam
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig2 -> SE Sig2
phi Sam
x
    where
      phi :: Sig2 -> SE Sig2
phi (Bpm
a, Bpm
b) = do
        Sig2
a' <- Bpm -> SE Sig2
f Bpm
a
        Sig2
b' <- Bpm -> SE Sig2
f Bpm
b
        Sig2 -> SE Sig2
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig2 -> SE Sig2) -> Sig2 -> SE Sig2
forall a b. (a -> b) -> a -> b
$ Sig2
0.5 Sig2 -> Sig2 -> Sig2
forall a. Num a => a -> a -> a
* (Sig2
a' Sig2 -> Sig2 -> Sig2
forall a. Num a => a -> a -> a
+ Sig2
b')

instance MixAt Sig2 Sig2 Sam where
  mixAt :: Bpm -> (Sig2 -> Sig2) -> Sam -> AtOut Sig2 Sig2 Sam
mixAt Bpm
k Sig2 -> Sig2
f Sam
sam = (Sig2 -> Sig2) -> Sam -> AtOut Sig2 Sig2 Sam
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at (\Sig2
x -> Bpm -> Sig2 -> Sig2 -> Sig2
forall a. (Num a, SigSpace a) => Bpm -> a -> a -> a
cfd Bpm
k Sig2
x (Sig2 -> Sig2
f Sig2
x)) Sam
sam

instance MixAt Sig2 (SE Sig2) Sam where
  mixAt :: Bpm -> (Sig2 -> SE Sig2) -> Sam -> AtOut Sig2 (SE Sig2) Sam
mixAt Bpm
k Sig2 -> SE Sig2
f Sam
sam = (Sig2 -> SE Sig2) -> Sam -> AtOut Sig2 (SE Sig2) Sam
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at (\Sig2
x -> (Sig2 -> Sig2) -> SE Sig2 -> SE Sig2
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bpm -> Sig2 -> Sig2 -> Sig2
forall a. (Num a, SigSpace a) => Bpm -> a -> a -> a
cfd Bpm
k Sig2
x) (Sig2 -> SE Sig2
f Sig2
x)) Sam
sam

instance MixAt Sig (SE Sig) Sam where
  mixAt :: Bpm -> (Bpm -> SE Bpm) -> Sam -> AtOut Bpm (SE Bpm) Sam
mixAt Bpm
k Bpm -> SE Bpm
f Sam
sam = (Bpm -> SE Bpm) -> Sam -> AtOut Bpm (SE Bpm) Sam
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at (\Bpm
x -> (Bpm -> Bpm) -> SE Bpm -> SE Bpm
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bpm -> Bpm -> Bpm -> Bpm
forall a. (Num a, SigSpace a) => Bpm -> a -> a -> a
cfd Bpm
k Bpm
x) (Bpm -> SE Bpm
f Bpm
x)) Sam
sam

instance MixAt Sig Sig2 Sam where
  mixAt :: Bpm -> (Bpm -> Sig2) -> Sam -> AtOut Bpm Sig2 Sam
mixAt Bpm
k Bpm -> Sig2
f Sam
sam = (Bpm -> Sig2) -> Sam -> AtOut Bpm Sig2 Sam
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at (\Bpm
x -> Bpm -> Sig2 -> Sig2 -> Sig2
forall a. (Num a, SigSpace a) => Bpm -> a -> a -> a
cfd Bpm
k (Bpm
x, Bpm
x) (Bpm -> Sig2
f Bpm
x)) Sam
sam

instance MixAt Sig (SE Sig2) Sam where
  mixAt :: Bpm -> (Bpm -> SE Sig2) -> Sam -> AtOut Bpm (SE Sig2) Sam
mixAt Bpm
k Bpm -> SE Sig2
f Sam
sam = (Bpm -> SE Sig2) -> Sam -> AtOut Bpm (SE Sig2) Sam
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at (\Bpm
x -> (Sig2 -> Sig2) -> SE Sig2 -> SE Sig2
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bpm -> Sig2 -> Sig2 -> Sig2
forall a. (Num a, SigSpace a) => Bpm -> a -> a -> a
cfd Bpm
k (Bpm
x, Bpm
x)) (Bpm -> SE Sig2
f Bpm
x)) Sam
sam

-- | Constructs sample from mono signal
infSig1 :: Sig -> Sam
infSig1 :: Bpm -> Sam
infSig1 Bpm
x = Sig2 -> Sam
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bpm
x, Bpm
x)

-- | Constructs sample from stereo signal
infSig2 :: Sig2 -> Sam
infSig2 :: Sig2 -> Sam
infSig2 = Sig2 -> Sam
forall (f :: * -> *) a. Applicative f => a -> f a
pure

-- | Constructs sample from limited mono signal (duration is in seconds)
sig1 :: Sig -> Sig -> Sam
sig1 :: Bpm -> Bpm -> Sam
sig1 Bpm
dt Bpm
a = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ (Bpm -> S Sig2) -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
reader ((Bpm -> S Sig2) -> ReaderT Bpm SE (S Sig2))
-> (Bpm -> S Sig2) -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ \Bpm
_ -> Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (Bpm
a, Bpm
a) (Bpm -> Dur
Dur Bpm
dt)

-- | Constructs sample from limited stereo signal (duration is in seconds)
sig2 :: Sig -> Sig2 -> Sam
sig2 :: Bpm -> Sig2 -> Sam
sig2 Bpm
dt Sig2
a = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ (Bpm -> S Sig2) -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
reader ((Bpm -> S Sig2) -> ReaderT Bpm SE (S Sig2))
-> (Bpm -> S Sig2) -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ \Bpm
_ -> Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S Sig2
a (Bpm -> Dur
Dur Bpm
dt)

-- | Constructs sample from limited mono signal (duration is in BPMs)
fromSig1 :: Sig -> Sig -> Sam
fromSig1 :: Bpm -> Bpm -> Sam
fromSig1 Bpm
dt = DurOf Sam -> Sam -> Sam
forall a. Limit a => DurOf a -> a -> a
lim DurOf Sam
Bpm
dt (Sam -> Sam) -> (Bpm -> Sam) -> Bpm -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bpm -> Sam
infSig1

-- | Constructs sample from limited stereo signal (duration is in BPMs)
fromSig2 :: Sig -> Sig2 -> Sam
fromSig2 :: Bpm -> Sig2 -> Sam
fromSig2 Bpm
dt = DurOf Sam -> Sam -> Sam
forall a. Limit a => DurOf a -> a -> a
lim DurOf Sam
Bpm
dt (Sam -> Sam) -> (Sig2 -> Sam) -> Sig2 -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig2 -> Sam
infSig2

-- | Constructs sample from wav or aiff files.
wav :: String -> Sam
wav :: String -> Sam
wav String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (String -> Sig2
readSnd String
fileName) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig (D -> Bpm) -> D -> Bpm
forall a b. (a -> b) -> a -> b
$ String -> D
lengthSnd String
fileName)

-- | Constructs sample from wav that is played in reverse.
wavr :: String -> Sam
wavr :: String -> Sam
wavr String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (Bpm -> Sig2 -> Sig2
forall a. Sigs a => Bpm -> a -> a
takeSnd (D -> Bpm
sig D
len) (Sig2 -> Sig2) -> Sig2 -> Sig2
forall a b. (a -> b) -> a -> b
$ Bpm -> String -> Sig2
loopWav (-Bpm
1) String
fileName) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig D
len)
  where len :: D
len = String -> D
lengthSnd String
fileName

-- | Constructs sample from the segment of a wav file. The start and end times are measured in seconds.
--
-- > seg begin end fileName
seg :: D -> D -> String -> Sam
seg :: D -> D -> String -> Sam
seg D
start D
end String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (D -> D -> Bpm -> String -> Sig2
readSegWav D
start D
end Bpm
1 String
fileName) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig D
len)
  where len :: D
len = D
end D -> D -> D
forall a. Num a => a -> a -> a
- D
start

--- | Constructs reversed sample from segment of an audio file.
segr :: D -> D -> String -> Sam
segr :: D -> D -> String -> Sam
segr D
start D
end String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (D -> D -> Bpm -> String -> Sig2
readSegWav D
start D
end (-Bpm
1) String
fileName) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig D
len)
  where len :: D
len = D
end D -> D -> D
forall a. Num a => a -> a -> a
- D
start

-- | Picks segments from the wav file at random. The first argument is the length of the segment.
rndWav :: D -> String -> Sam
rndWav :: D -> String -> Sam
rndWav D
dt String
fileName = D -> D -> D -> String -> Sam
rndSeg D
dt D
0 (String -> D
lengthSnd String
fileName) String
fileName

-- | Picks segments from the wav file at random. The first argument is the length of the segment.
rndWavr :: D -> String -> Sam
rndWavr :: D -> String -> Sam
rndWavr D
dt String
fileName = D -> D -> D -> String -> Sam
rndSegr D
dt D
0 (String -> D
lengthSnd String
fileName) String
fileName

-- | Constructs random segments of the given length from an interval.
rndSeg :: D -> D -> D -> String -> Sam
rndSeg :: D -> D -> D -> String -> Sam
rndSeg = Bpm -> D -> D -> D -> String -> Sam
genRndSeg Bpm
1

-- | Constructs reversed random segments of the given length from an interval.
rndSegr :: D -> D -> D -> String -> Sam
rndSegr :: D -> D -> D -> String -> Sam
rndSegr = Bpm -> D -> D -> D -> String -> Sam
genRndSeg (-Bpm
1)

genRndSeg :: Sig -> D -> D -> D -> String -> Sam
genRndSeg :: Bpm -> D -> D -> D -> String -> Sam
genRndSeg Bpm
speed D
len D
start D
end String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ SE (S Sig2) -> ReaderT Bpm SE (S Sig2)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (SE (S Sig2) -> ReaderT Bpm SE (S Sig2))
-> SE (S Sig2) -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ do
  D
x <- D -> D -> SE D
forall a. SigOrD a => a -> a -> SE a
random D
0 D
1
  let a :: D
a = D
start D -> D -> D
forall a. Num a => a -> a -> a
+ D
dl D -> D -> D
forall a. Num a => a -> a -> a
* D
x
  let b :: D
b = D
a D -> D -> D
forall a. Num a => a -> a -> a
+ D
len
  S Sig2 -> SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> SE (S Sig2)) -> S Sig2 -> SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (D -> D -> Bpm -> String -> Sig2
readSegWav D
a D
b Bpm
speed String
fileName) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig D
len)
  where dl :: D
dl = D
end D -> D -> D
forall a. Num a => a -> a -> a
- D
len

-- | Reads a sample from the file in RAM.
--
-- > ramWav loopMode speed fileName
ramWav :: LoopMode -> Sig -> String -> Sam
ramWav :: LoopMode -> Bpm -> String -> Sam
ramWav LoopMode
loopMode Bpm
speed String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (LoopMode -> Bpm -> String -> Sig2
ramSnd LoopMode
loopMode Bpm
speed String
fileName) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig (D -> Bpm) -> D -> Bpm
forall a b. (a -> b) -> a -> b
$ String -> D
lengthSnd String
fileName)

-- | Reads a sample from the mono file in RAM.
--
-- > ramWav1 loopMode speed fileName
ramWav1 :: LoopMode -> Sig -> String -> Sam
ramWav1 :: LoopMode -> Bpm -> String -> Sam
ramWav1 LoopMode
loopMode Bpm
speed String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let x :: Bpm
x = LoopMode -> Bpm -> String -> Bpm
ramSnd1 LoopMode
loopMode Bpm
speed String
fileName in (Bpm
x, Bpm
x)) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig (D -> Bpm) -> D -> Bpm
forall a b. (a -> b) -> a -> b
$ String -> D
lengthSnd String
fileName)

-- | Constructs sample from mono wav or aiff files.
wav1 :: String -> Sam
wav1 :: String -> Sam
wav1 String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let x :: Bpm
x = String -> Bpm
readSnd1 String
fileName in (Bpm
x, Bpm
x)) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig (D -> Bpm) -> D -> Bpm
forall a b. (a -> b) -> a -> b
$ String -> D
lengthSnd String
fileName)

-- | Constructs sample from mono wav that is played in reverse.
wavr1 :: String -> Sam
wavr1 :: String -> Sam
wavr1 String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let x :: Bpm
x = Bpm -> Bpm -> Bpm
forall a. Sigs a => Bpm -> a -> a
takeSnd (D -> Bpm
sig D
len) (Bpm -> Bpm) -> Bpm -> Bpm
forall a b. (a -> b) -> a -> b
$ Bpm -> String -> Bpm
loopWav1 (-Bpm
1) String
fileName in (Bpm
x, Bpm
x)) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig D
len)
  where len :: D
len = String -> D
lengthSnd String
fileName

-- | Constructs sample from the segment of a mono wav file. The start and end times are measured in seconds.
--
-- > seg begin end fileName
seg1 :: D -> D -> String -> Sam
seg1 :: D -> D -> String -> Sam
seg1 D
start D
end String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let x :: Bpm
x = D -> D -> Bpm -> String -> Bpm
readSegWav1 D
start D
end Bpm
1 String
fileName in (Bpm
x, Bpm
x)) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig D
len)
  where len :: D
len = D
end D -> D -> D
forall a. Num a => a -> a -> a
- D
start

--- | Constructs reversed sample from segment of a mono audio file.
segr1 :: D -> D -> String -> Sam
segr1 :: D -> D -> String -> Sam
segr1 D
start D
end String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let x :: Bpm
x = D -> D -> Bpm -> String -> Bpm
readSegWav1 D
start D
end (-Bpm
1) String
fileName in (Bpm
x, Bpm
x)) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig D
len)
  where len :: D
len = D
end D -> D -> D
forall a. Num a => a -> a -> a
- D
start

-- | Picks segments from the mono wav file at random. The first argument is the length of the segment.
rndWav1 :: D -> String -> Sam
rndWav1 :: D -> String -> Sam
rndWav1 D
dt String
fileName = D -> D -> D -> String -> Sam
rndSeg1 D
dt D
0 (String -> D
lengthSnd String
fileName) String
fileName

-- | Picks segments from the mono wav file at random. The first argument is the length of the segment.
rndWavr1 :: D -> String -> Sam
rndWavr1 :: D -> String -> Sam
rndWavr1 D
dt String
fileName = D -> D -> D -> String -> Sam
rndSegr1 D
dt D
0 (String -> D
lengthSnd String
fileName) String
fileName

-- | Constructs random segments of the given length from an interval.
rndSeg1 :: D -> D -> D -> String -> Sam
rndSeg1 :: D -> D -> D -> String -> Sam
rndSeg1 = Bpm -> D -> D -> D -> String -> Sam
genRndSeg1 Bpm
1

-- | Constructs reversed random segments of the given length from an interval.
rndSegr1 :: D -> D -> D -> String -> Sam
rndSegr1 :: D -> D -> D -> String -> Sam
rndSegr1 = Bpm -> D -> D -> D -> String -> Sam
genRndSeg1 (-Bpm
1)

genRndSeg1 :: Sig -> D -> D -> D -> String -> Sam
genRndSeg1 :: Bpm -> D -> D -> D -> String -> Sam
genRndSeg1 Bpm
speed D
len D
start D
end String
fileName = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ SE (S Sig2) -> ReaderT Bpm SE (S Sig2)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (SE (S Sig2) -> ReaderT Bpm SE (S Sig2))
-> SE (S Sig2) -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ do
  D
x <- D -> D -> SE D
forall a. SigOrD a => a -> a -> SE a
random D
0 D
1
  let a :: D
a = D
start D -> D -> D
forall a. Num a => a -> a -> a
+ D
dl D -> D -> D
forall a. Num a => a -> a -> a
* D
x
  let b :: D
b = D
a D -> D -> D
forall a. Num a => a -> a -> a
+ D
len
  S Sig2 -> SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> SE (S Sig2)) -> S Sig2 -> SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let y :: Bpm
y = D -> D -> Bpm -> String -> Bpm
readSegWav1 D
a D
b Bpm
speed String
fileName in (Bpm
y, Bpm
y)) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig D
len)
  where dl :: D
dl = D
end D -> D -> D
forall a. Num a => a -> a -> a
- D
len


toSec :: Bpm -> Sig -> Sig
toSec :: Bpm -> Bpm -> Bpm
toSec Bpm
bpm Bpm
a = Bpm
a Bpm -> Bpm -> Bpm
forall a. Num a => a -> a -> a
* Bpm
60 Bpm -> Bpm -> Bpm
forall a. Fractional a => a -> a -> a
/ Bpm
bpm

toSecD :: Bpm -> D -> D
toSecD :: Bpm -> D -> D
toSecD Bpm
bpm D
a = D
a D -> D -> D
forall a. Num a => a -> a -> a
* D
60 D -> D -> D
forall a. Fractional a => a -> a -> a
/ (Bpm -> D
ir Bpm
bpm)

addDur :: Sig -> Dur -> Dur
addDur :: Bpm -> Dur -> Dur
addDur Bpm
d Dur
x = case Dur
x of
  Dur Bpm
a  -> Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ Bpm
d Bpm -> Bpm -> Bpm
forall a. Num a => a -> a -> a
+ Bpm
a
  Dur
InfDur -> Dur
InfDur

-- | Scales sample by pitch in tones.
atPch :: Sig -> Sam -> Sam
atPch :: Bpm -> Sam -> Sam
atPch Bpm
k = (Bpm -> Bpm) -> Sam -> Sam
forall a. SigSpace a => (Bpm -> Bpm) -> a -> a
mapSig (Bpm -> Bpm -> Bpm
scalePitch Bpm
k)

-- | Panning. 0 is all left and 1 is all right.
atPan :: Sig -> Sam -> Sam
atPan :: Bpm -> Sam -> Sam
atPan Bpm
k = (Sig2 -> Sig2) -> Sam -> Sam
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Bpm
a, Bpm
b) -> Bpm -> Bpm -> Sig2
pan2 ([Bpm] -> Bpm
forall a. Fractional a => [a] -> a
mean [Bpm
a, Bpm
b]) Bpm
k)

-- | Scales sample by pitch in factor of frequency.
atCps :: Sig -> Sam -> Sam
atCps :: Bpm -> Sam -> Sam
atCps Bpm
k = (Bpm -> Bpm) -> Sam -> Sam
forall a. SigSpace a => (Bpm -> Bpm) -> a -> a
mapSig (Bpm -> Bpm -> Bpm
scaleSpec Bpm
k)

tfmBy :: (S Sig2 -> Sig2) -> Sam -> Sam
tfmBy :: (S Sig2 -> Sig2) -> Sam -> Sam
tfmBy S Sig2 -> Sig2
f = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam)
-> (Sam -> ReaderT Bpm SE (S Sig2)) -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (S Sig2 -> S Sig2)
-> ReaderT Bpm SE (S Sig2) -> ReaderT Bpm SE (S Sig2)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\S Sig2
x -> S Sig2
x { samSig :: Sig2
samSig = S Sig2 -> Sig2
f S Sig2
x }) (ReaderT Bpm SE (S Sig2) -> ReaderT Bpm SE (S Sig2))
-> (Sam -> ReaderT Bpm SE (S Sig2))
-> Sam
-> ReaderT Bpm SE (S Sig2)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sam -> ReaderT Bpm SE (S Sig2)
forall a. Sample a -> ReaderT Bpm SE (S a)
unSam

tfmS :: (Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam
tfmS :: (Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam
tfmS Bpm -> S Sig2 -> S Sig2
f Sam
ra = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ do
  Bpm
bpm <- ReaderT Bpm SE Bpm
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
  S Sig2
a <- Sam -> ReaderT Bpm SE (S Sig2)
forall a. Sample a -> ReaderT Bpm SE (S a)
unSam Sam
ra
  S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Bpm -> S Sig2 -> S Sig2
f Bpm
bpm S Sig2
a

setInfDur :: Sam -> Sam
setInfDur :: Sam -> Sam
setInfDur = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam)
-> (Sam -> ReaderT Bpm SE (S Sig2)) -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (S Sig2 -> S Sig2)
-> ReaderT Bpm SE (S Sig2) -> ReaderT Bpm SE (S Sig2)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\S Sig2
a -> S Sig2
a { samDur :: Dur
samDur = Dur
InfDur }) (ReaderT Bpm SE (S Sig2) -> ReaderT Bpm SE (S Sig2))
-> (Sam -> ReaderT Bpm SE (S Sig2))
-> Sam
-> ReaderT Bpm SE (S Sig2)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sam -> ReaderT Bpm SE (S Sig2)
forall a. Sample a -> ReaderT Bpm SE (S a)
unSam

-- | Makes the sampler broader. It's reciprocal of str
--
-- > wide k = str (1 / k)
wide :: Sig -> Sam -> Sam
wide :: Bpm -> Sam -> Sam
wide = Bpm -> Sam -> Sam
forall a. Stretch a => DurOf a -> a -> a
str (Bpm -> Sam -> Sam) -> (Bpm -> Bpm) -> Bpm -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bpm -> Bpm
forall a. Fractional a => a -> a
recip

-- | Plays a list of samples one after another.
flow :: [Sam] -> Sam
flow :: [Sam] -> Sam
flow [] = Sam
0
flow [Sam]
as = (Sam -> Sam -> Sam) -> [Sam] -> Sam
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Sam -> Sam -> Sam
flow2 [Sam]
as

flow2 :: Sam -> Sam -> Sam
flow2 :: Sam -> Sam -> Sam
flow2 (Sam ReaderT Bpm SE (S Sig2)
ra) (Sam ReaderT Bpm SE (S Sig2)
rb) = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ do
  S Sig2
a <- ReaderT Bpm SE (S Sig2)
ra
  S Sig2
b <- ReaderT Bpm SE (S Sig2)
rb
  let sa :: Sig2
sa = S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
a
  let sb :: Sig2
sb = S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
b
  S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ case (S Sig2 -> Dur
forall a. S a -> Dur
samDur S Sig2
a, S Sig2 -> Dur
forall a. S a -> Dur
samDur S Sig2
b) of
    (Dur Bpm
da, Dur Bpm
db) -> Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (Sig2
sa Sig2 -> Sig2 -> Sig2
forall a. Num a => a -> a -> a
+ Bpm -> Sig2 -> Sig2
forall a. Sigs a => Bpm -> a -> a
delaySnd Bpm
da Sig2
sb) (Bpm -> Dur
Dur (Bpm -> Dur) -> Bpm -> Dur
forall a b. (a -> b) -> a -> b
$ Bpm
da Bpm -> Bpm -> Bpm
forall a. Num a => a -> a -> a
+ Bpm
db)
    (Dur
InfDur, Dur
_)      -> S Sig2
a
    (Dur Bpm
da, Dur
InfDur) -> Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (Sig2
sa Sig2 -> Sig2 -> Sig2
forall a. Num a => a -> a -> a
+ Bpm -> Sig2 -> Sig2
forall a. Sigs a => Bpm -> a -> a
delaySnd Bpm
da Sig2
sb) Dur
InfDur

type PickFun = [(D, D)] -> Evt Unit -> Evt (D, D)

genPick :: PickFun -> Sig -> [Sam] -> Sam
genPick :: PickFun -> Bpm -> [Sam] -> Sam
genPick PickFun
pickFun Bpm
dtSig [Sam]
as = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ do
  Bpm
bpm <- ReaderT Bpm SE Bpm
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
  [S Sig2]
xs <- [ReaderT Bpm SE (S Sig2)] -> ReaderT Bpm SE [S Sig2]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence ([ReaderT Bpm SE (S Sig2)] -> ReaderT Bpm SE [S Sig2])
-> [ReaderT Bpm SE (S Sig2)] -> ReaderT Bpm SE [S Sig2]
forall a b. (a -> b) -> a -> b
$ (Sam -> ReaderT Bpm SE (S Sig2))
-> [Sam] -> [ReaderT Bpm SE (S Sig2)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sam -> ReaderT Bpm SE (S Sig2)
forall a. Sample a -> ReaderT Bpm SE (S a)
unSam [Sam]
as
  let ds :: [D]
ds = (S Sig2 -> D) -> [S Sig2] -> [D]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bpm -> D
ir (Bpm -> D) -> (S Sig2 -> Bpm) -> S Sig2 -> D
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dur -> Bpm
getDur (Dur -> Bpm) -> (S Sig2 -> Dur) -> S Sig2 -> Bpm
forall b c a. (b -> c) -> (a -> b) -> a -> c
. S Sig2 -> Dur
forall a. S a -> Dur
samDur)  [S Sig2]
xs
  let sigs :: [Sig2]
sigs = (S Sig2 -> Sig2) -> [S Sig2] -> [Sig2]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap S Sig2 -> Sig2
forall a. S a -> a
samSig [S Sig2]
xs
  S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S ((D -> SE Sig2) -> Evt (Sco D) -> Sig2
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Evt (Sco a) -> b
sched (\D
n -> Sig2 -> SE Sig2
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig2 -> SE Sig2) -> Sig2 -> SE Sig2
forall a b. (a -> b) -> a -> b
$ [Sig2] -> Bpm -> Sig2
forall a. Tuple a => [a] -> Bpm -> a
atTuple [Sig2]
sigs (Bpm -> Sig2) -> Bpm -> Sig2
forall a b. (a -> b) -> a -> b
$ D -> Bpm
sig D
n) (Evt (Sco D) -> Sig2) -> Evt (Sco D) -> Sig2
forall a b. (a -> b) -> a -> b
$ ((D, D) -> Sco D) -> Evt (D, D) -> Evt (Sco D)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(D
dt, D
a) -> DurOf (Sco D) -> Sco D -> Sco D
forall a. Stretch a => DurOf a -> a -> a
str (D -> Bpm
sig D
dt) (Sco D -> Sco D) -> Sco D -> Sco D
forall a b. (a -> b) -> a -> b
$ D -> Sco D
forall t a. Num t => a -> Track t a
temp D
a) (Evt (D, D) -> Evt (Sco D)) -> Evt (D, D) -> Evt (Sco D)
forall a b. (a -> b) -> a -> b
$ PickFun
pickFun ([D] -> [D] -> [(D, D)]
forall a b. [a] -> [b] -> [(a, b)]
zip [D]
ds ((Int -> D) -> [Int] -> [D]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> D
int [Int
0..])) (Evt Unit -> Evt (D, D)) -> Evt Unit -> Evt (D, D)
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Evt Unit
metroS Bpm
bpm Bpm
dtSig) Dur
InfDur
  where
    getDur :: Dur -> Bpm
getDur Dur
x = case Dur
x of
      Dur
InfDur -> -Bpm
1
      Dur Bpm
d  -> Bpm
d

-- | Picks samples at random. The first argument is the period ofmetronome in BPMs.
-- The tick of metronome produces new random sample from the list.
pick :: Sig -> [Sam] -> Sam
pick :: Bpm -> [Sam] -> Sam
pick = PickFun -> Bpm -> [Sam] -> Sam
genPick PickFun
forall a b. (Tuple a, Arg a) => [a] -> Evt b -> Evt a
oneOf

-- | Picks samples at random. We can specify a frequency of the occurernce.
-- The sum of all frequencies should be equal to 1.
pickBy :: Sig -> [(Sig, Sam)] -> Sam
pickBy :: Bpm -> [(Bpm, Sam)] -> Sam
pickBy Bpm
dt [(Bpm, Sam)]
as = PickFun -> Bpm -> [Sam] -> Sam
genPick (\[(D, D)]
ds -> Rnds (D, D) -> Evt Unit -> Evt (D, D)
forall a b. (Tuple a, Arg a) => Rnds a -> Evt b -> Evt a
freqOf (Rnds (D, D) -> Evt Unit -> Evt (D, D))
-> Rnds (D, D) -> Evt Unit -> Evt (D, D)
forall a b. (a -> b) -> a -> b
$ [Bpm] -> [(D, D)] -> Rnds (D, D)
forall a b. [a] -> [b] -> [(a, b)]
zip (((Bpm, Sam) -> Bpm) -> [(Bpm, Sam)] -> [Bpm]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bpm, Sam) -> Bpm
forall a b. (a, b) -> a
fst [(Bpm, Sam)]
as) [(D, D)]
ds) Bpm
dt (((Bpm, Sam) -> Sam) -> [(Bpm, Sam)] -> [Sam]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bpm, Sam) -> Sam
forall a b. (a, b) -> b
snd [(Bpm, Sam)]
as)

type EnvFun = (Dur -> D -> D -> Sig)

genEnv :: EnvFun -> D -> D -> Sam -> Sam
genEnv :: EnvFun -> D -> D -> Sam -> Sam
genEnv EnvFun
env D
start D
end = (Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam
tfmS ((Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam)
-> (Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm S Sig2
a ->
  let absStart :: D
absStart = Bpm -> D -> D
toSecD Bpm
bpm D
start
      absEnd :: D
absEnd   = Bpm -> D -> D
toSecD Bpm
bpm D
end
  in  S Sig2
a { samSig :: Sig2
samSig = Bpm -> Sig2 -> Sig2
forall a. SigSpace a => Bpm -> a -> a
mul (EnvFun
env (S Sig2 -> Dur
forall a. S a -> Dur
samDur S Sig2
a) D
absStart D
absEnd) (Sig2 -> Sig2) -> Sig2 -> Sig2
forall a b. (a -> b) -> a -> b
$ S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
a }

-- | A linear rise-decay envelope. Times a given in BPMs.
--
-- > linEnv rise dec sample
linEnv :: D -> D -> Sam -> Sam
linEnv :: D -> D -> Sam -> Sam
linEnv = EnvFun -> D -> D -> Sam -> Sam
genEnv (EnvFun -> D -> D -> Sam -> Sam) -> EnvFun -> D -> D -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Dur
dur D
start D
end -> case Dur
dur of
  Dur
InfDur -> [D] -> Bpm
linseg [D
0, D
start, D
1]
  Dur Bpm
d  -> [D] -> Bpm
linseg [D
0, D
start, D
1, D -> D -> D
forall a. (IfB a, OrdB a) => a -> a -> a
maxB D
0 (Bpm -> D
ir Bpm
d D -> D -> D
forall a. Num a => a -> a -> a
- D
start D -> D -> D
forall a. Num a => a -> a -> a
- D
end), D
1, D
end , D
0]

-- | An exponential rise-decay envelope. Times a given in BPMs.
--
-- > expEnv rise dec sample
expEnv :: D -> D -> Sam -> Sam
expEnv :: D -> D -> Sam -> Sam
expEnv = EnvFun -> D -> D -> Sam -> Sam
genEnv EnvFun
f
  where
    f :: EnvFun
f Dur
dur D
start D
end = case Dur
dur of
      Dur
InfDur -> [D] -> Bpm
expseg [D
zero, D
start, D
1]
      Dur Bpm
d  -> [D] -> Bpm
expseg [D
zero, D
start, D
1, D -> D -> D
forall a. (IfB a, OrdB a) => a -> a -> a
maxB D
0 (Bpm -> D
ir Bpm
d D -> D -> D
forall a. Num a => a -> a -> a
- D
start D -> D -> D
forall a. Num a => a -> a -> a
- D
end), D
1, D
end , D
zero]
    zero :: D
zero = D
0.00001

genEnv1 :: (D -> Sig) -> Sam -> Sam
genEnv1 :: (D -> Bpm) -> Sam -> Sam
genEnv1 D -> Bpm
envFun = (S Sig2 -> Sig2) -> Sam -> Sam
tfmBy S Sig2 -> Sig2
f
  where
    f :: S Sig2 -> Sig2
f S Sig2
a = (Bpm -> Sig2 -> Sig2) -> Sig2 -> Bpm -> Sig2
forall a b c. (a -> b -> c) -> b -> a -> c
flip Bpm -> Sig2 -> Sig2
forall a. SigSpace a => Bpm -> a -> a
mul (S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
a) (Bpm -> Sig2) -> Bpm -> Sig2
forall a b. (a -> b) -> a -> b
$ case S Sig2 -> Dur
forall a. S a -> Dur
samDur S Sig2
a of
      Dur
InfDur -> Bpm
1
      Dur Bpm
d  -> D -> Bpm
envFun (Bpm -> D
ir Bpm
d)


-- | Parabolic envelope that starts and ends at zero and reaches maximum at the center.
hatEnv :: Sam -> Sam
hatEnv :: Sam -> Sam
hatEnv = (D -> Bpm) -> Sam -> Sam
genEnv1 ((D -> Bpm) -> Sam -> Sam) -> (D -> Bpm) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \D
d -> Tab -> Bpm -> Bpm
oscBy (Double -> Double -> [Double] -> Tab
polys Double
0 Double
1 [Double
0, Double
1, -Double
1]) (Bpm
1 Bpm -> Bpm -> Bpm
forall a. Fractional a => a -> a -> a
/ D -> Bpm
sig D
d)

-- | Fade in linear envelope.
riseEnv :: Sam -> Sam
riseEnv :: Sam -> Sam
riseEnv = (D -> Bpm) -> Sam -> Sam
genEnv1 ((D -> Bpm) -> Sam -> Sam) -> (D -> Bpm) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \D
d -> [D] -> Bpm
linseg [D
0, D
d, D
1]

-- | Fade out linear envelope.
decEnv :: Sam -> Sam
decEnv :: Sam -> Sam
decEnv = (D -> Bpm) -> Sam -> Sam
genEnv1 ((D -> Bpm) -> Sam -> Sam) -> (D -> Bpm) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \D
d -> [D] -> Bpm
linseg [D
1, D
d, D
0]

-- | Fade in exponential envelope.
eriseEnv :: Sam -> Sam
eriseEnv :: Sam -> Sam
eriseEnv = (D -> Bpm) -> Sam -> Sam
genEnv1 ((D -> Bpm) -> Sam -> Sam) -> (D -> Bpm) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \D
d -> [D] -> Bpm
expseg [D
0.0001, D
d, D
1]

-- | Fade out exponential envelope.
edecEnv :: Sam -> Sam
edecEnv :: Sam -> Sam
edecEnv = (D -> Bpm) -> Sam -> Sam
genEnv1 ((D -> Bpm) -> Sam -> Sam) -> (D -> Bpm) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \D
d -> [D] -> Bpm
expseg [D
1, D
d, D
0.0001]

type LoopFun = Sig -> Sig -> Sig2 -> Sig2

genLoop :: LoopFun -> Sam -> Sam
genLoop :: LoopFun -> Sam -> Sam
genLoop LoopFun
g = Sam -> Sam
setInfDur (Sam -> Sam) -> (Sam -> Sam) -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bpm -> S Sig2 -> S Sig2) -> Sam -> Sam
tfmS Bpm -> S Sig2 -> S Sig2
f
  where
    f :: Bpm -> S Sig2 -> S Sig2
f Bpm
bpm S Sig2
a = S Sig2
a { samSig :: Sig2
samSig = case S Sig2 -> Dur
forall a. S a -> Dur
samDur S Sig2
a of
      Dur
InfDur -> S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
a
      Dur Bpm
d  -> LoopFun
g Bpm
bpm Bpm
d (S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
a)
    }


-- | Plays the sample at the given period (in BPMs). The samples don't overlap.
rep1 :: Sig -> Sam -> Sam
rep1 :: Bpm -> Sam -> Sam
rep1 = [Bpm] -> Sam -> Sam
rep ([Bpm] -> Sam -> Sam) -> (Bpm -> [Bpm]) -> Bpm -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bpm -> [Bpm]
forall (m :: * -> *) a. Monad m => a -> m a
return

-- | Plays the sample at the given period (in BPMs). The overlapped samples are mixed together.
pat1 :: Sig -> Sam -> Sam
pat1 :: Bpm -> Sam -> Sam
pat1 = [Bpm] -> Sam -> Sam
pat ([Bpm] -> Sam -> Sam) -> (Bpm -> [Bpm]) -> Bpm -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bpm -> [Bpm]
forall (m :: * -> *) a. Monad m => a -> m a
return

-- | Plays the sample at the given pattern of periods (in BPMs). The samples don't overlap.
rep :: [Sig] -> Sam -> Sam
rep :: [Bpm] -> Sam -> Sam
rep [Bpm]
dts = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm Bpm
_d Sig2
asig -> (Unit -> SE Sig2) -> Evt (Sco Unit) -> Sig2
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Evt (Sco a) -> b
sched (SE Sig2 -> Unit -> SE Sig2
forall a b. a -> b -> a
const (SE Sig2 -> Unit -> SE Sig2) -> SE Sig2 -> Unit -> SE Sig2
forall a b. (a -> b) -> a -> b
$ Sig2 -> SE Sig2
forall (m :: * -> *) a. Monad m => a -> m a
return Sig2
asig) (Evt (Sco Unit) -> Sig2) -> Evt (Sco Unit) -> Sig2
forall a b. (a -> b) -> a -> b
$ (Unit -> Sco Unit) -> Evt Unit -> Evt (Sco Unit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sco Unit -> Unit -> Sco Unit
forall a b. a -> b -> a
const (Sco Unit -> Unit -> Sco Unit) -> Sco Unit -> Unit -> Sco Unit
forall a b. (a -> b) -> a -> b
$ Bpm -> Sco Unit
notes Bpm
bpm) (Evt Unit -> Evt (Sco Unit)) -> Evt Unit -> Evt (Sco Unit)
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Evt Unit
metroS Bpm
bpm ([Bpm] -> Bpm
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Bpm]
dts)
  where notes :: Bpm -> Sco Unit
notes Bpm
bpm = [Sco Unit] -> Sco Unit
forall a. Harmony a => [a] -> a
har ([Sco Unit] -> Sco Unit) -> [Sco Unit] -> Sco Unit
forall a b. (a -> b) -> a -> b
$ (Bpm -> Bpm -> Sco Unit) -> [Bpm] -> [Bpm] -> [Sco Unit]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Bpm
t Bpm
dt-> Bpm -> Bpm -> Unit -> Sco Unit
forall t a. Num t => t -> t -> a -> Track t a
singleEvent (Bpm -> Bpm -> Bpm
toSec Bpm
bpm Bpm
t) (Bpm -> Bpm -> Bpm
toSec Bpm
bpm Bpm
dt) Unit
unit) ([Bpm] -> [Bpm]
patDurs [Bpm]
dts) [Bpm]
dts

-- | Plays the sample at the given pattern of periods (in BPMs). The overlapped samples are mixed together.
pat :: [Sig] -> Sam -> Sam
pat :: [Bpm] -> Sam -> Sam
pat [Bpm]
dts = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm Bpm
d Sig2
asig -> (Unit -> SE Sig2) -> Evt (Sco Unit) -> Sig2
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Evt (Sco a) -> b
sched (SE Sig2 -> Unit -> SE Sig2
forall a b. a -> b -> a
const (SE Sig2 -> Unit -> SE Sig2) -> SE Sig2 -> Unit -> SE Sig2
forall a b. (a -> b) -> a -> b
$ Sig2 -> SE Sig2
forall (m :: * -> *) a. Monad m => a -> m a
return Sig2
asig) (Evt (Sco Unit) -> Sig2) -> Evt (Sco Unit) -> Sig2
forall a b. (a -> b) -> a -> b
$ (Unit -> Sco Unit) -> Evt Unit -> Evt (Sco Unit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sco Unit -> Unit -> Sco Unit
forall a b. a -> b -> a
const (Sco Unit -> Unit -> Sco Unit) -> Sco Unit -> Unit -> Sco Unit
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Sco Unit
notes Bpm
bpm Bpm
d) (Evt Unit -> Evt (Sco Unit)) -> Evt Unit -> Evt (Sco Unit)
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Evt Unit
metroS Bpm
bpm ([Bpm] -> Bpm
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Bpm]
dts)
  where notes :: Bpm -> Bpm -> Sco Unit
notes Bpm
bpm Bpm
d = [Sco Unit] -> Sco Unit
forall a. Harmony a => [a] -> a
har ([Sco Unit] -> Sco Unit) -> [Sco Unit] -> Sco Unit
forall a b. (a -> b) -> a -> b
$ (Bpm -> Sco Unit) -> [Bpm] -> [Sco Unit]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Bpm
t -> Event Bpm Unit -> Sco Unit
forall t a. Num t => Event t a -> Track t a
fromEvent (Event Bpm Unit -> Sco Unit) -> Event Bpm Unit -> Sco Unit
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Unit -> Event Bpm Unit
forall t a. t -> t -> a -> Event t a
Event (Bpm -> Bpm -> Bpm
toSec Bpm
bpm Bpm
t) Bpm
d Unit
unit) ([Bpm] -> [Sco Unit]) -> [Bpm] -> [Sco Unit]
forall a b. (a -> b) -> a -> b
$ [Bpm] -> [Bpm]
patDurs [Bpm]
dts

-- | Plays the sample at the given pattern of periods (in BPMs) and sometimes skips the samples from playback. The overlapped samples are mixed together.
-- The first argument is the probability of inclusion.
rndPat :: Sig -> [Sig] -> Sam -> Sam
rndPat :: Bpm -> [Bpm] -> Sam -> Sam
rndPat Bpm
prob [Bpm]
dts = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm Bpm
d Sig2
asig -> (Unit -> SE Sig2) -> Evt (Sco Unit) -> Sig2
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Evt (Sco a) -> b
sched (SE Sig2 -> Unit -> SE Sig2
forall a b. a -> b -> a
const (SE Sig2 -> Unit -> SE Sig2) -> SE Sig2 -> Unit -> SE Sig2
forall a b. (a -> b) -> a -> b
$ Bpm -> Sig2 -> SE Sig2
forall a. (Tuple a, Num a) => Bpm -> a -> SE a
rndSkipInstr Bpm
prob Sig2
asig) (Evt (Sco Unit) -> Sig2) -> Evt (Sco Unit) -> Sig2
forall a b. (a -> b) -> a -> b
$ (Unit -> Sco Unit) -> Evt Unit -> Evt (Sco Unit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sco Unit -> Unit -> Sco Unit
forall a b. a -> b -> a
const (Sco Unit -> Unit -> Sco Unit) -> Sco Unit -> Unit -> Sco Unit
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Sco Unit
notes Bpm
bpm Bpm
d) (Evt Unit -> Evt (Sco Unit)) -> Evt Unit -> Evt (Sco Unit)
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Evt Unit
metroS Bpm
bpm ([Bpm] -> Bpm
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Bpm]
dts)
  where
    notes :: Bpm -> Bpm -> Sco Unit
notes Bpm
bpm Bpm
d = [Sco Unit] -> Sco Unit
forall a. Harmony a => [a] -> a
har ([Sco Unit] -> Sco Unit) -> [Sco Unit] -> Sco Unit
forall a b. (a -> b) -> a -> b
$ (Bpm -> Sco Unit) -> [Bpm] -> [Sco Unit]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Bpm
t -> Event Bpm Unit -> Sco Unit
forall t a. Num t => Event t a -> Track t a
fromEvent (Event Bpm Unit -> Sco Unit) -> Event Bpm Unit -> Sco Unit
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Unit -> Event Bpm Unit
forall t a. t -> t -> a -> Event t a
Event (Bpm -> Bpm -> Bpm
toSec Bpm
bpm Bpm
t) Bpm
d Unit
unit) ([Bpm] -> [Sco Unit]) -> [Bpm] -> [Sco Unit]
forall a b. (a -> b) -> a -> b
$ [Bpm] -> [Bpm]
patDurs [Bpm]
dts

-- | Plays the sample at the given pattern of volumes and periods (in BPMs). The overlapped samples are mixed together.
--
-- > pat' volumes periods
pat' :: [D] -> [Sig] -> Sam -> Sam
pat' :: [D] -> [Bpm] -> Sam -> Sam
pat' [D]
vols [Bpm]
dts = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm Bpm
d Sig2
asig -> (D -> SE Sig2) -> Evt (Sco D) -> Sig2
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Evt (Sco a) -> b
sched (Sig2 -> D -> SE Sig2
forall (m :: * -> *) a. (Monad m, SigSpace a) => a -> D -> m a
instr Sig2
asig) (Evt (Sco D) -> Sig2) -> Evt (Sco D) -> Sig2
forall a b. (a -> b) -> a -> b
$ (Unit -> Sco D) -> Evt Unit -> Evt (Sco D)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sco D -> Unit -> Sco D
forall a b. a -> b -> a
const (Sco D -> Unit -> Sco D) -> Sco D -> Unit -> Sco D
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Sco D
notes Bpm
bpm Bpm
d) (Evt Unit -> Evt (Sco D)) -> Evt Unit -> Evt (Sco D)
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Evt Unit
metroS Bpm
bpm ([Bpm] -> Bpm
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Bpm]
dts')
  where
    notes :: Bpm -> Bpm -> Sco D
notes Bpm
bpm Bpm
d = [Sco D] -> Sco D
forall a. Harmony a => [a] -> a
har ([Sco D] -> Sco D) -> [Sco D] -> Sco D
forall a b. (a -> b) -> a -> b
$ (D -> Bpm -> Sco D) -> [D] -> [Bpm] -> [Sco D]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\D
v Bpm
t -> Bpm -> Bpm -> D -> Sco D
forall t a. Num t => t -> t -> a -> Track t a
singleEvent (Bpm -> Bpm -> Bpm
toSec Bpm
bpm Bpm
t) Bpm
d D
v) [D]
vols' ([Bpm] -> [Sco D]) -> [Bpm] -> [Sco D]
forall a b. (a -> b) -> a -> b
$ [Bpm] -> [Bpm]
patDurs [Bpm]
dts'
    instr :: a -> D -> m a
instr a
asig D
v = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ Bpm -> a -> a
forall a. SigSpace a => Bpm -> a -> a
mul (D -> Bpm
sig D
v) a
asig
    ([D]
vols', [Bpm]
dts') = [(D, Bpm)] -> ([D], [Bpm])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(D, Bpm)] -> ([D], [Bpm])) -> [(D, Bpm)] -> ([D], [Bpm])
forall a b. (a -> b) -> a -> b
$ [D] -> [Bpm] -> [(D, Bpm)]
forall a b. [a] -> [b] -> [(a, b)]
lcmList [D]
vols [Bpm]
dts

rndSkipInstr :: (Tuple a, Num a) => Sig -> a -> SE a
rndSkipInstr :: Bpm -> a -> SE a
rndSkipInstr Bpm
probSig a
asig = do
  let prob :: D
prob = Bpm -> D
ir Bpm
probSig
  Ref a
ref <- a -> SE (Ref a)
forall a. Tuple a => a -> SE (Ref a)
newRef a
0
  D
p <- D -> D -> SE D
forall a. SigOrD a => a -> a -> SE a
random D
0 (D
1 :: D)
  BoolD -> SE () -> SE ()
whenD1 (D
p D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`lessThan` D
prob) (SE () -> SE ()) -> SE () -> SE ()
forall a b. (a -> b) -> a -> b
$
    Ref a -> a -> SE ()
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref a
ref a
asig
  BoolD -> SE () -> SE ()
whenD1 (D
p D -> D -> BooleanOf D
forall a. OrdB a => a -> a -> BooleanOf a
`greaterThanEquals` D
prob) (SE () -> SE ()) -> SE () -> SE ()
forall a b. (a -> b) -> a -> b
$
    Ref a -> a -> SE ()
forall a. Tuple a => Ref a -> a -> SE ()
writeRef Ref a
ref a
0
  Ref a -> SE a
forall a. Tuple a => Ref a -> SE a
readRef Ref a
ref

-- | Plays the sample at the given pattern of volumes and periods (in BPMs) and sometimes skips the samples from playback.  The overlapped samples are mixed together.
-- The first argument is the probability of inclusion.
--
-- > rndPat' probability volumes periods
rndPat' :: Sig -> [D] -> [Sig] -> Sam -> Sam
rndPat' :: Bpm -> [D] -> [Bpm] -> Sam -> Sam
rndPat' Bpm
prob [D]
vols [Bpm]
dts = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm Bpm
d Sig2
asig -> (D -> SE Sig2) -> Evt (Sco D) -> Sig2
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Evt (Sco a) -> b
sched (Sig2 -> D -> SE Sig2
instr Sig2
asig) (Evt (Sco D) -> Sig2) -> Evt (Sco D) -> Sig2
forall a b. (a -> b) -> a -> b
$ (Unit -> Sco D) -> Evt Unit -> Evt (Sco D)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sco D -> Unit -> Sco D
forall a b. a -> b -> a
const (Sco D -> Unit -> Sco D) -> Sco D -> Unit -> Sco D
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Sco D
notes Bpm
bpm Bpm
d) (Evt Unit -> Evt (Sco D)) -> Evt Unit -> Evt (Sco D)
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Evt Unit
metroS Bpm
bpm ([Bpm] -> Bpm
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Bpm]
dts')
  where
    notes :: Bpm -> Bpm -> Sco D
notes Bpm
bpm Bpm
d = [Sco D] -> Sco D
forall a. Harmony a => [a] -> a
har ([Sco D] -> Sco D) -> [Sco D] -> Sco D
forall a b. (a -> b) -> a -> b
$ (D -> Bpm -> Sco D) -> [D] -> [Bpm] -> [Sco D]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\D
v Bpm
t -> Bpm -> Bpm -> D -> Sco D
forall t a. Num t => t -> t -> a -> Track t a
singleEvent (Bpm -> Bpm -> Bpm
toSec Bpm
bpm Bpm
t) Bpm
d D
v) [D]
vols' ([Bpm] -> [Sco D]) -> [Bpm] -> [Sco D]
forall a b. (a -> b) -> a -> b
$ [Bpm] -> [Bpm]
patDurs [Bpm]
dts'
    instr :: Sig2 -> D -> SE Sig2
instr Sig2
asig D
v = Bpm -> SE Sig2 -> SE Sig2
forall a. SigSpace a => Bpm -> a -> a
mul (D -> Bpm
sig D
v) (SE Sig2 -> SE Sig2) -> SE Sig2 -> SE Sig2
forall a b. (a -> b) -> a -> b
$ Bpm -> Sig2 -> SE Sig2
forall a. (Tuple a, Num a) => Bpm -> a -> SE a
rndSkipInstr Bpm
prob Sig2
asig
    ([D]
vols', [Bpm]
dts') = [(D, Bpm)] -> ([D], [Bpm])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(D, Bpm)] -> ([D], [Bpm])) -> [(D, Bpm)] -> ([D], [Bpm])
forall a b. (a -> b) -> a -> b
$ [D] -> [Bpm] -> [(D, Bpm)]
forall a b. [a] -> [b] -> [(a, b)]
lcmList [D]
vols [Bpm]
dts


lcmList :: [a] -> [b] -> [(a, b)]
lcmList :: [a] -> [b] -> [(a, b)]
lcmList [a]
as [b]
bs = Int -> [(a, b)] -> [(a, b)]
forall a. Int -> [a] -> [a]
take Int
n ([(a, b)] -> [(a, b)]) -> [(a, b)] -> [(a, b)]
forall a b. (a -> b) -> a -> b
$ [a] -> [b] -> [(a, b)]
forall a b. [a] -> [b] -> [(a, b)]
zip ([a] -> [a]
forall a. [a] -> [a]
cycle [a]
as) ([b] -> [b]
forall a. [a] -> [a]
cycle [b]
bs)
  where n :: Int
n = Int -> Int -> Int
forall a. Integral a => a -> a -> a
lcm ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
as) ([b] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [b]
bs)

-- | Constructs the wall of sound from the initial segment of the sample.
-- The segment length is given in BPMs.
--
-- > wall segLength
wall :: Sig -> Sam -> Sam
wall :: Bpm -> Sam -> Sam
wall Bpm
dt Sam
a = [Sam] -> Sam
forall a. Fractional a => [a] -> a
mean [Sam
b, DurOf Sam -> Sam -> Sam
forall a. Delay a => DurOf a -> a -> a
del DurOf Sam
Bpm
hdt Sam
b]
  where
    hdt :: Bpm
hdt = Bpm
0.5 Bpm -> Bpm -> Bpm
forall a. Num a => a -> a -> a
* Bpm
dt
    f :: Sam -> Sam
f = Bpm -> Sam -> Sam
pat1 Bpm
hdt (Sam -> Sam) -> (Sam -> Sam) -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sam -> Sam
hatEnv (Sam -> Sam) -> (Sam -> Sam) -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DurOf Sam -> Sam -> Sam
forall a. Limit a => DurOf a -> a -> a
lim DurOf Sam
Bpm
dt
    b :: Sam
b = Sam -> Sam
f Sam
a

-- | The tones of the chord.
type Chord = [D]

type Arp1Fun = Evt Unit -> Evt D

arpInstr :: Sig2 -> D -> SE Sig2
arpInstr :: Sig2 -> D -> SE Sig2
arpInstr Sig2
asig D
k = Sig2 -> SE Sig2
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig2 -> SE Sig2) -> Sig2 -> SE Sig2
forall a b. (a -> b) -> a -> b
$ (Bpm -> Bpm) -> Sig2 -> Sig2
forall a. SigSpace a => (Bpm -> Bpm) -> a -> a
mapSig (Bpm -> Bpm -> Bpm
scalePitch (D -> Bpm
sig D
k)) Sig2
asig

patDurs :: [Sig] -> [Sig]
patDurs :: [Bpm] -> [Bpm]
patDurs [Bpm]
dts = [Bpm] -> [Bpm]
forall a. [a] -> [a]
reverse ([Bpm] -> [Bpm]) -> [Bpm] -> [Bpm]
forall a b. (a -> b) -> a -> b
$ (Bpm, [Bpm]) -> [Bpm]
forall a b. (a, b) -> b
snd ((Bpm, [Bpm]) -> [Bpm]) -> (Bpm, [Bpm]) -> [Bpm]
forall a b. (a -> b) -> a -> b
$ ((Bpm, [Bpm]) -> Bpm -> (Bpm, [Bpm]))
-> (Bpm, [Bpm]) -> [Bpm] -> (Bpm, [Bpm])
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\(Bpm
counter, [Bpm]
res) Bpm
a -> (Bpm
a Bpm -> Bpm -> Bpm
forall a. Num a => a -> a -> a
+ Bpm
counter, Bpm
counterBpm -> [Bpm] -> [Bpm]
forall a. a -> [a] -> [a]
:[Bpm]
res)) (Bpm
0, []) [Bpm]
dts

genArp1 :: Arp1Fun -> Sig -> Sam -> Sam
genArp1 :: Arp1Fun -> Bpm -> Sam -> Sam
genArp1 Arp1Fun
arpFun Bpm
dt = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm Bpm
d Sig2
asig ->
  (D -> SE Sig2) -> Evt (Sco D) -> Sig2
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Evt (Sco a) -> b
sched (Sig2 -> D -> SE Sig2
arpInstr Sig2
asig) (Evt (Sco D) -> Sig2) -> Evt (Sco D) -> Sig2
forall a b. (a -> b) -> a -> b
$ Bpm -> Evt D -> Evt (Sco D)
forall a. Bpm -> Evt a -> Evt (Sco a)
withDur Bpm
d (Evt D -> Evt (Sco D)) -> Evt D -> Evt (Sco D)
forall a b. (a -> b) -> a -> b
$ Arp1Fun
arpFun Arp1Fun -> Arp1Fun
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Evt Unit
metroS Bpm
bpm Bpm
dt

-- | Plays ascending arpeggio of samples.
arpUp1 :: Chord -> Sig -> Sam -> Sam
arpUp1 :: [D] -> Bpm -> Sam -> Sam
arpUp1 = Arp1Fun -> Bpm -> Sam -> Sam
genArp1 (Arp1Fun -> Bpm -> Sam -> Sam)
-> ([D] -> Arp1Fun) -> [D] -> Bpm -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [D] -> Arp1Fun
forall a b. (Tuple a, Arg a) => [a] -> Evt b -> Evt a
cycleE

-- | Plays descending arpeggio of samples.
arpDown1 :: Chord -> Sig -> Sam -> Sam
arpDown1 :: [D] -> Bpm -> Sam -> Sam
arpDown1 [D]
ch = [D] -> Bpm -> Sam -> Sam
arpUp1 ([D] -> [D]
forall a. [a] -> [a]
reverse [D]
ch)

-- | Plays arpeggio of samles with random notes from the chord.
arpOneOf1 :: Chord -> Sig -> Sam -> Sam
arpOneOf1 :: [D] -> Bpm -> Sam -> Sam
arpOneOf1 = Arp1Fun -> Bpm -> Sam -> Sam
genArp1 (Arp1Fun -> Bpm -> Sam -> Sam)
-> ([D] -> Arp1Fun) -> [D] -> Bpm -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [D] -> Arp1Fun
forall a b. (Tuple a, Arg a) => [a] -> Evt b -> Evt a
oneOf

-- | Plays arpeggio of samles with random notes from the chord.
-- We can assign the frequencies of the notes.
arpFreqOf1 :: [Sig] -> Chord -> Sig -> Sam -> Sam
arpFreqOf1 :: [Bpm] -> [D] -> Bpm -> Sam -> Sam
arpFreqOf1 [Bpm]
freqs [D]
ch = Arp1Fun -> Bpm -> Sam -> Sam
genArp1 (Rnds D -> Arp1Fun
forall a b. (Tuple a, Arg a) => Rnds a -> Evt b -> Evt a
freqOf ([Bpm] -> [D] -> Rnds D
forall a b. [a] -> [b] -> [(a, b)]
zip [Bpm]
freqs [D]
ch))

genArp :: Arp1Fun -> [Sig] -> Sam -> Sam
genArp :: Arp1Fun -> [Bpm] -> Sam -> Sam
genArp Arp1Fun
arpFun [Bpm]
dts = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Bpm
bpm Bpm
d Sig2
asig -> (D -> SE Sig2) -> Evt (Sco D) -> Sig2
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Evt (Sco a) -> b
sched (Sig2 -> D -> SE Sig2
arpInstr Sig2
asig) (Evt (Sco D) -> Sig2) -> Evt (Sco D) -> Sig2
forall a b. (a -> b) -> a -> b
$ (D -> Sco D) -> Evt D -> Evt (Sco D)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bpm -> Bpm -> D -> Sco D
notes Bpm
bpm Bpm
d) (Evt D -> Evt (Sco D)) -> Evt D -> Evt (Sco D)
forall a b. (a -> b) -> a -> b
$ Arp1Fun
arpFun Arp1Fun -> Arp1Fun
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Evt Unit
metroS Bpm
bpm ([Bpm] -> Bpm
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Bpm]
dts)
  where notes :: Bpm -> Bpm -> D -> Sco D
notes Bpm
bpm Bpm
d D
pchScale = [Sco D] -> Sco D
forall a. Harmony a => [a] -> a
har ([Sco D] -> Sco D) -> [Sco D] -> Sco D
forall a b. (a -> b) -> a -> b
$ (Bpm -> Sco D) -> [Bpm] -> [Sco D]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Bpm
t -> Bpm -> Bpm -> D -> Sco D
forall t a. Num t => t -> t -> a -> Track t a
singleEvent (Bpm -> Bpm -> Bpm
toSec Bpm
bpm Bpm
t) Bpm
d D
pchScale) ([Bpm] -> [Sco D]) -> [Bpm] -> [Sco D]
forall a b. (a -> b) -> a -> b
$ [Bpm] -> [Bpm]
patDurs [Bpm]
dts

-- | Plays ascending arpeggio of samples.
arpUp :: Chord -> [Sig] -> Sam -> Sam
arpUp :: [D] -> [Bpm] -> Sam -> Sam
arpUp = Arp1Fun -> [Bpm] -> Sam -> Sam
genArp (Arp1Fun -> [Bpm] -> Sam -> Sam)
-> ([D] -> Arp1Fun) -> [D] -> [Bpm] -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [D] -> Arp1Fun
forall a b. (Tuple a, Arg a) => [a] -> Evt b -> Evt a
cycleE

-- | Plays descending arpeggio of samples.
arpDown :: Chord -> [Sig] -> Sam -> Sam
arpDown :: [D] -> [Bpm] -> Sam -> Sam
arpDown [D]
ch = [D] -> [Bpm] -> Sam -> Sam
arpUp ([D] -> [D]
forall a. [a] -> [a]
reverse [D]
ch)

-- | Plays arpeggio of samles with random notes from the chord.
arpOneOf :: Chord -> [Sig] -> Sam -> Sam
arpOneOf :: [D] -> [Bpm] -> Sam -> Sam
arpOneOf = Arp1Fun -> [Bpm] -> Sam -> Sam
genArp (Arp1Fun -> [Bpm] -> Sam -> Sam)
-> ([D] -> Arp1Fun) -> [D] -> [Bpm] -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [D] -> Arp1Fun
forall a b. (Tuple a, Arg a) => [a] -> Evt b -> Evt a
oneOf

-- | Plays arpeggio of samles with random notes from the chord.
-- We can assign the frequencies of the notes.
arpFreqOf :: [Sig] -> Chord -> [Sig] -> Sam -> Sam
arpFreqOf :: [Bpm] -> [D] -> [Bpm] -> Sam -> Sam
arpFreqOf [Bpm]
freqs [D]
ch = Arp1Fun -> [Bpm] -> Sam -> Sam
genArp (Rnds D -> Arp1Fun
forall a b. (Tuple a, Arg a) => Rnds a -> Evt b -> Evt a
freqOf (Rnds D -> Arp1Fun) -> Rnds D -> Arp1Fun
forall a b. (a -> b) -> a -> b
$ [Bpm] -> [D] -> Rnds D
forall a b. [a] -> [b] -> [(a, b)]
zip [Bpm]
freqs [D]
ch)

metroS :: Bpm -> Sig -> Evt Unit
metroS :: Bpm -> Bpm -> Evt Unit
metroS Bpm
bpm Bpm
dt = Bpm -> Evt Unit
metro (Bpm -> Bpm
forall a. Fractional a => a -> a
recip (Bpm -> Bpm) -> Bpm -> Bpm
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Bpm
toSec Bpm
bpm Bpm
dt)

-- | The pattern is influenced by the Brian Eno's work "Music fo Airports".
-- The argument is list of tripples:
--
-- > (delayTime, repeatPeriod, pitch)
--
-- It takes a Sample and plays it in the loop with given initial delay time.
-- The third cell in the tuple pitch is a value for scaling of the pitch in tones.
forAirports :: [(Sig, Sig, Sig)] -> Sam -> Sam
forAirports :: [(Bpm, Bpm, Bpm)] -> Sam -> Sam
forAirports [(Bpm, Bpm, Bpm)]
xs Sam
sample = [Sam] -> Sam
forall a. Fractional a => [a] -> a
mean ([Sam] -> Sam) -> [Sam] -> Sam
forall a b. (a -> b) -> a -> b
$ (((Bpm, Bpm, Bpm) -> Sam) -> [(Bpm, Bpm, Bpm)] -> [Sam])
-> [(Bpm, Bpm, Bpm)] -> ((Bpm, Bpm, Bpm) -> Sam) -> [Sam]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Bpm, Bpm, Bpm) -> Sam) -> [(Bpm, Bpm, Bpm)] -> [Sam]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Bpm, Bpm, Bpm)]
xs (((Bpm, Bpm, Bpm) -> Sam) -> [Sam])
-> ((Bpm, Bpm, Bpm) -> Sam) -> [Sam]
forall a b. (a -> b) -> a -> b
$
    \(Bpm
delTime, Bpm
loopTime, Bpm
note) -> DurOf Sam -> Sam -> Sam
forall a. Delay a => DurOf a -> a -> a
del DurOf Sam
Bpm
delTime (Sam -> Sam) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ [Bpm] -> Sam -> Sam
pat [Bpm
loopTime] (Bpm -> Sam -> Sam
atPch Bpm
note Sam
sample)

-- | The pattern is influenced by the Brian Eno's work "Music fo Airports".
-- It's more generic than pattern @forAirport@
-- The argument is list of tripples:
--
-- > (delayTime, repeatPeriod, Sample)
--
-- It takes a list of Samples and plays them in the loop with given initial delay time and repeat period.
genForAirports :: [(Sig, Sig, Sam)] -> Sam
genForAirports :: [(Bpm, Bpm, Sam)] -> Sam
genForAirports [(Bpm, Bpm, Sam)]
xs = [Sam] -> Sam
forall a. Fractional a => [a] -> a
mean ([Sam] -> Sam) -> [Sam] -> Sam
forall a b. (a -> b) -> a -> b
$ ((Bpm, Bpm, Sam) -> Sam) -> [(Bpm, Bpm, Sam)] -> [Sam]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Bpm
delTime, Bpm
loopTime, Sam
sample) -> DurOf Sam -> Sam -> Sam
forall a. Delay a => DurOf a -> a -> a
del DurOf Sam
Bpm
delTime (Sam -> Sam) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ [Bpm] -> Sam -> Sam
pat [Bpm
loopTime] Sam
sample) [(Bpm, Bpm, Sam)]
xs

arp1 :: (SigSpace a, Sigs a) => (D -> SE a) -> Sig -> Sig -> Int -> [D] -> a
arp1 :: (D -> SE a) -> Bpm -> Bpm -> Int -> [D] -> a
arp1 D -> SE a
instr Bpm
bpm Bpm
dt Int
n [D]
ch = ((D, D) -> SE a) -> Evt (Sco (D, D)) -> a
forall a b. (Arg a, Sigs b) => (a -> SE b) -> Evt (Sco a) -> b
sched (\(D
amp, D
cps) -> (a -> a) -> SE a -> SE a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bpm -> a -> a
forall a. SigSpace a => Bpm -> a -> a
mul (D -> Bpm
sig D
amp)) (SE a -> SE a) -> SE a -> SE a
forall a b. (a -> b) -> a -> b
$ D -> SE a
instr D
cps) (Evt (Sco (D, D)) -> a) -> Evt (Sco (D, D)) -> a
forall a b. (a -> b) -> a -> b
$
  Bpm -> Evt (D, D) -> Evt (Sco (D, D))
forall a. Bpm -> Evt a -> Evt (Sco a)
withDur (Bpm -> Bpm -> Bpm
toSec Bpm
bpm Bpm
dt) (Evt (D, D) -> Evt (Sco (D, D))) -> Evt (D, D) -> Evt (Sco (D, D))
forall a b. (a -> b) -> a -> b
$ PickFun
forall a b. (Tuple a, Arg a) => [a] -> Evt b -> Evt a
cycleE ([D] -> [D] -> [(D, D)]
forall a b. [a] -> [b] -> [(a, b)]
lcmList (D
1 D -> [D] -> [D]
forall a. a -> [a] -> [a]
: Int -> D -> [D]
forall a. Int -> a -> [a]
replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) D
0.7) [D]
ch) (Evt Unit -> Evt (D, D)) -> Evt Unit -> Evt (D, D)
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> Evt Unit
metroS Bpm
bpm Bpm
dt

-- | The arpeggiator for the sequence of chords.
--
-- > arpy instrument chordPeriod speedOfTheNote accentNumber chords
--
-- The first argument is an instrument that takes in a frequency of
-- the note in Hz. The second argument is the period of
-- chord change (in beats). The next argument is the speed
-- of the single note (in beats). The integer argument
-- is number of notes in the group. Every n'th note is louder.
-- The last argument is the sequence of chords. The chord is
-- the list of frequencies.
arpy :: (D -> SE Sig2) -> Sig -> Sig -> Int -> [[D]] -> Sam
arpy :: (D -> SE Sig2) -> Bpm -> Bpm -> Int -> [[D]] -> Sam
arpy D -> SE Sig2
instr Bpm
chordPeriod Bpm
speed Int
accentNum [[D]]
chords = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ do
  Bpm
bpm <- ReaderT Bpm SE Bpm
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
  S Sig2
res <- Sam -> ReaderT Bpm SE (S Sig2)
forall a. Sample a -> ReaderT Bpm SE (S a)
unSam (Sam -> ReaderT Bpm SE (S Sig2)) -> Sam -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sam -> Sam
forall a. Loop a => a -> a
loop (Sam -> Sam) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ [Sam] -> Sam
flow ([Sam] -> Sam) -> [Sam] -> Sam
forall a b. (a -> b) -> a -> b
$ ([D] -> Sam) -> [[D]] -> [Sam]
forall a b. (a -> b) -> [a] -> [b]
map (D -> D -> Sam -> Sam
linEnv D
0.05 D
0.05 (Sam -> Sam) -> ([D] -> Sam) -> [D] -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bpm -> Sig2 -> Sam
fromSig2 Bpm
chordPeriod (Sig2 -> Sam) -> ([D] -> Sig2) -> [D] -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (D -> SE Sig2) -> Bpm -> Bpm -> Int -> [D] -> Sig2
forall a.
(SigSpace a, Sigs a) =>
(D -> SE a) -> Bpm -> Bpm -> Int -> [D] -> a
arp1 D -> SE Sig2
instr Bpm
bpm Bpm
speed Int
accentNum) [[D]]
chords
  S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
res) Dur
InfDur

-- | Applies random panning to every sample playback.
atPanRnd :: Sam -> Sam
atPanRnd :: Sam -> Sam
atPanRnd = (Sig2 -> SE Sig2) -> Sam -> Sam
forall a b. (a -> SE b) -> Sample a -> Sample b
bindSam Sig2 -> SE Sig2
rndPan2

-- | Applies random amplitude scaling with gauss distribution with given radius (centered at 1).
atVolGauss :: D -> Sam -> Sam
atVolGauss :: D -> Sam -> Sam
atVolGauss D
k = (Sig2 -> SE Sig2) -> Sam -> Sam
forall a b. (a -> SE b) -> Sample a -> Sample b
bindSam (D -> Sig2 -> SE Sig2
forall a. SigSpace a => D -> a -> SE a
gaussVol D
k)

-- | Applies random amplitude scaling to every sample playback.
atVolRnd :: (D, D) -> Sam -> Sam
atVolRnd :: (D, D) -> Sam -> Sam
atVolRnd (D, D)
k = (Sig2 -> SE Sig2) -> Sam -> Sam
forall a b. (a -> SE b) -> Sample a -> Sample b
bindSam ((D, D) -> Sig2 -> SE Sig2
forall a. SigSpace a => (D, D) -> a -> SE a
rndVol (D, D)
k)

class ToSam a where
  toSam :: a -> Sam

limSam :: ToSam a => Sig -> a -> Sam
limSam :: Bpm -> a -> Sam
limSam Bpm
dt = DurOf Sam -> Sam -> Sam
forall a. Limit a => DurOf a -> a -> a
lim DurOf Sam
Bpm
dt (Sam -> Sam) -> (a -> Sam) -> a -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Sam
forall a. ToSam a => a -> Sam
toSam

instance ToSam Sig where
  toSam :: Bpm -> Sam
toSam Bpm
x = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (Bpm
x, Bpm
x) Dur
InfDur

instance ToSam Sig2 where
  toSam :: Sig2 -> Sam
toSam Sig2
x = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S Sig2
x Dur
InfDur

instance ToSam (SE Sig) where
  toSam :: SE Bpm -> Sam
toSam SE Bpm
x = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ do
    Bpm
y <- SE Bpm -> ReaderT Bpm SE Bpm
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift SE Bpm
x
    S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (Bpm
y, Bpm
y) Dur
InfDur

instance ToSam (SE Sig2) where
  toSam :: SE Sig2 -> Sam
toSam SE Sig2
x = ReaderT Bpm SE (S Sig2) -> Sam
forall a. ReaderT Bpm SE (S a) -> Sample a
Sam (ReaderT Bpm SE (S Sig2) -> Sam) -> ReaderT Bpm SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ do
    Sig2
y <- SE Sig2 -> ReaderT Bpm SE Sig2
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift SE Sig2
x
    S Sig2 -> ReaderT Bpm SE (S Sig2)
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Bpm SE (S Sig2))
-> S Sig2 -> ReaderT Bpm SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S Sig2
y Dur
InfDur

---------------------------------------------------------------
--- reading from RAM

-- | It's the same as loopRam but wrapped in Sam (see "Csound.Air.Wav").
ramLoop :: Fidelity -> TempoSig -> PitchSig -> String -> Sam
ramLoop :: D -> Bpm -> Bpm -> String -> Sam
ramLoop D
winSize Bpm
tempo Bpm
pitch String
file = Sig2 -> Sam
forall a. ToSam a => a -> Sam
toSam (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Bpm -> Bpm -> String -> Sig2
loopRam D
winSize Bpm
tempo Bpm
pitch String
file

-- | It's the same as readRam but wrapped in Sam (see "Csound.Air.Wav").
ramRead :: Fidelity -> TempoSig -> PitchSig -> String -> Sam
ramRead :: D -> Bpm -> Bpm -> String -> Sam
ramRead D
winSize Bpm
tempo Bpm
pitch String
file = Bpm -> Sig2 -> Sam
sig2 (D -> Bpm
sig (String -> D
lengthSnd String
file) Bpm -> Bpm -> Bpm
forall a. Fractional a => a -> a -> a
/ Bpm
tempo) (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Bpm -> Bpm -> String -> Sig2
readRam D
winSize Bpm
tempo Bpm
pitch String
file

-- | It's the same as loopSeg but wrapped in Sam (see "Csound.Air.Wav").
segLoop :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam
segLoop :: D -> Sig2 -> Bpm -> Bpm -> String -> Sam
segLoop D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file = Sig2 -> Sam
forall a. ToSam a => a -> Sam
toSam (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Bpm -> Bpm -> String -> Sig2
loopSeg D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file

-- | It's the same as readSeg but wrapped in Sam (see "Csound.Air.Wav").
segRead :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam
segRead :: D -> Sig2 -> Bpm -> Bpm -> String -> Sam
segRead D
winSize ds :: Sig2
ds@(Bpm
kmin, Bpm
kmax) Bpm
tempo Bpm
pitch String
file = Bpm -> Sig2 -> Sam
sig2 ((Bpm
kmax Bpm -> Bpm -> Bpm
forall a. Num a => a -> a -> a
- Bpm
kmin) Bpm -> Bpm -> Bpm
forall a. Fractional a => a -> a -> a
/ Bpm
tempo) (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Bpm -> Bpm -> String -> Sig2
readSeg D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file

-- | It's the same as loopRel but wrapped in Sam (see "Csound.Air.Wav").
relLoop :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam
relLoop :: D -> Sig2 -> Bpm -> Bpm -> String -> Sam
relLoop D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file = Sig2 -> Sam
forall a. ToSam a => a -> Sam
toSam (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Bpm -> Bpm -> String -> Sig2
loopRel D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file

-- | It's the same as readRel but wrapped in Sam (see "Csound.Air.Wav").
relRead :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam
relRead :: D -> Sig2 -> Bpm -> Bpm -> String -> Sam
relRead D
winSize ds :: Sig2
ds@(Bpm
kmin, Bpm
kmax) Bpm
tempo Bpm
pitch String
file = Bpm -> Sig2 -> Sam
sig2 ((Bpm
kmax Bpm -> Bpm -> Bpm
forall a. Num a => a -> a -> a
- Bpm
kmin) Bpm -> Bpm -> Bpm
forall a. Fractional a => a -> a -> a
/ Bpm
tempo) (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Bpm -> Bpm -> String -> Sig2
readRel D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file

-- | It's the same as loopRam1 but wrapped in Sam (see "Csound.Air.Wav").
ramLoop1 :: Fidelity -> TempoSig -> PitchSig -> String -> Sam
ramLoop1 :: D -> Bpm -> Bpm -> String -> Sam
ramLoop1 D
winSize Bpm
tempo Bpm
pitch String
file = Bpm -> Sam
forall a. ToSam a => a -> Sam
toSam (Bpm -> Sam) -> Bpm -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Bpm -> Bpm -> String -> Bpm
loopRam1 D
winSize Bpm
tempo Bpm
pitch String
file

-- | It's the same as readRam1 but wrapped in Sam (see "Csound.Air.Wav").
ramRead1 :: Fidelity -> TempoSig -> PitchSig -> String -> Sam
ramRead1 :: D -> Bpm -> Bpm -> String -> Sam
ramRead1 D
winSize Bpm
tempo Bpm
pitch String
file = Bpm -> Bpm -> Sam
sig1 (D -> Bpm
sig (String -> D
lengthSnd String
file) Bpm -> Bpm -> Bpm
forall a. Fractional a => a -> a -> a
/ Bpm
tempo) (Bpm -> Sam) -> Bpm -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Bpm -> Bpm -> String -> Bpm
readRam1 D
winSize Bpm
tempo Bpm
pitch String
file

-- | It's the same as loopSeg1 but wrapped in Sam (see "Csound.Air.Wav").
segLoop1 :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam
segLoop1 :: D -> Sig2 -> Bpm -> Bpm -> String -> Sam
segLoop1 D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file = Bpm -> Sam
forall a. ToSam a => a -> Sam
toSam (Bpm -> Sam) -> Bpm -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Bpm -> Bpm -> String -> Bpm
loopSeg1 D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file

-- | It's the same as readSeg1 but wrapped in Sam (see "Csound.Air.Wav").
segRead1 :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam
segRead1 :: D -> Sig2 -> Bpm -> Bpm -> String -> Sam
segRead1 D
winSize ds :: Sig2
ds@(Bpm
kmin, Bpm
kmax) Bpm
tempo Bpm
pitch String
file = Bpm -> Bpm -> Sam
sig1 ((Bpm
kmax Bpm -> Bpm -> Bpm
forall a. Num a => a -> a -> a
- Bpm
kmin) Bpm -> Bpm -> Bpm
forall a. Fractional a => a -> a -> a
/ Bpm
tempo) (Bpm -> Sam) -> Bpm -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Bpm -> Bpm -> String -> Bpm
readSeg1 D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file

-- | It's the same as loopRel1 but wrapped in Sam (see "Csound.Air.Wav").
relLoop1 :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam
relLoop1 :: D -> Sig2 -> Bpm -> Bpm -> String -> Sam
relLoop1 D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file = Bpm -> Sam
forall a. ToSam a => a -> Sam
toSam (Bpm -> Sam) -> Bpm -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Bpm -> Bpm -> String -> Bpm
loopRel1 D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file

-- | It's the same as readRel1 but wrapped in Sam (see "Csound.Air.Wav").
relRead1 :: Fidelity -> (Sig, Sig) -> TempoSig -> PitchSig -> String -> Sam
relRead1 :: D -> Sig2 -> Bpm -> Bpm -> String -> Sam
relRead1 D
winSize ds :: Sig2
ds@(Bpm
kmin, Bpm
kmax) Bpm
tempo Bpm
pitch String
file = Bpm -> Bpm -> Sam
sig1 ((Bpm
kmax Bpm -> Bpm -> Bpm
forall a. Num a => a -> a -> a
- Bpm
kmin) Bpm -> Bpm -> Bpm
forall a. Fractional a => a -> a -> a
/ Bpm
tempo) (Bpm -> Sam) -> Bpm -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Bpm -> Bpm -> String -> Bpm
readRel1 D
winSize Sig2
ds Bpm
tempo Bpm
pitch String
file

-----------------------
-- temposcale

wavScale :: Fidelity -> TempoSig -> PitchSig -> String -> Sam
wavScale :: D -> Bpm -> Bpm -> String -> Sam
wavScale D
winSize Bpm
tempo Bpm
pitch String
file = Sig2 -> Sam
forall a. ToSam a => a -> Sam
toSam (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Bpm -> Bpm -> String -> Sig2
scaleWav D
winSize Bpm
tempo Bpm
pitch String
file

wavScale1 :: Fidelity -> TempoSig -> PitchSig -> String -> Sam
wavScale1 :: D -> Bpm -> Bpm -> String -> Sam
wavScale1 D
winSize Bpm
tempo Bpm
pitch String
file = Bpm -> Sam
forall a. ToSam a => a -> Sam
toSam (Bpm -> Sam) -> Bpm -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Bpm -> Bpm -> String -> Bpm
scaleWav1 D
winSize Bpm
tempo Bpm
pitch String
file

drumScale :: TempoSig -> PitchSig -> String -> Sam
drumScale :: Bpm -> Bpm -> String -> Sam
drumScale Bpm
tempo Bpm
pitch String
file = Sig2 -> Sam
forall a. ToSam a => a -> Sam
toSam (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> String -> Sig2
scaleDrum Bpm
tempo Bpm
pitch String
file

drumScale1 :: TempoSig -> PitchSig -> String -> Sam
drumScale1 :: Bpm -> Bpm -> String -> Sam
drumScale1  Bpm
tempo Bpm
pitch String
file = Bpm -> Sam
forall a. ToSam a => a -> Sam
toSam (Bpm -> Sam) -> Bpm -> Sam
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> String -> Bpm
scaleDrum1 Bpm
tempo Bpm
pitch String
file

harmScale :: TempoSig -> PitchSig -> String -> Sam
harmScale :: Bpm -> Bpm -> String -> Sam
harmScale Bpm
tempo Bpm
pitch String
file = Sig2 -> Sam
forall a. ToSam a => a -> Sam
toSam (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> String -> Sig2
scaleHarm Bpm
tempo Bpm
pitch String
file

harmScale1 :: TempoSig -> PitchSig -> String -> Sam
harmScale1 :: Bpm -> Bpm -> String -> Sam
harmScale1  Bpm
tempo Bpm
pitch String
file = Bpm -> Sam
forall a. ToSam a => a -> Sam
toSam (Bpm -> Sam) -> Bpm -> Sam
forall a b. (a -> b) -> a -> b
$ Bpm -> Bpm -> String -> Bpm
scaleHarm1 Bpm
tempo Bpm
pitch String
file