{-# 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 = (Sig -> S Sig2 -> S Sig2) -> Sam -> Sam
tfmS ((Sig -> S Sig2 -> S Sig2) -> Sam -> Sam)
-> (Sig -> S Sig2 -> S Sig2) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Sig
bpm S Sig2
x ->
    let absDt :: Sig
absDt = Sig -> Sig -> Sig
toSec Sig
bpm Sig
DurOf Sam
dt
        asig :: Sig2
asig  = Sig -> Sig2 -> Sig2
forall a. Sigs a => Sig -> a -> a
delaySnd Sig
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   = Sig -> Dur -> Dur
addDur Sig
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 = asig, samDur = dur }

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

instance Limit Sam where
  lim :: DurOf Sam -> Sam -> Sam
lim DurOf Sam
d = (Sig -> S Sig2 -> S Sig2) -> Sam -> Sam
tfmS ((Sig -> S Sig2 -> S Sig2) -> Sam -> Sam)
-> (Sig -> S Sig2 -> S Sig2) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Sig
bpm S Sig2
x ->
    let absD :: Sig
absD = Sig -> Sig -> Sig
toSec Sig
bpm Sig
DurOf Sam
d
    in  S Sig2
x { samSig = takeSnd absD $ samSig x
        , samDur = Dur 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
$ \Sig
_ Sig
d Sig2
asig -> Sig -> Sig2 -> Sig2
forall a. Sigs a => Sig -> a -> a
repeatSnd Sig
d Sig2
asig

instance Rest Sam where
  rest :: DurOf Sam -> Sam
rest DurOf Sam
dt = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
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
bpm -> Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S Sig2
0 (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ Sig -> Sig -> Sig
toSec Sig
bpm Sig
DurOf Sam
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 a b. (a -> b) -> Sample a -> Sample b
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 :: (Sig -> SE Sig) -> Sam -> AtOut Sig (SE Sig) Sam
at Sig -> SE Sig
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 a b. (a -> b) -> Sample a -> Sample b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Sig -> SE Sig) -> Sig2 -> AtOut Sig (SE Sig) Sig2
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig -> SE Sig
f) Sam
x

instance At Sig Sig2 Sam where
  type AtOut Sig Sig2 Sam = Sam
  at :: (Sig -> Sig2) -> Sam -> AtOut Sig Sig2 Sam
at Sig -> 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 (Sig
a, Sig
b) = Sig2
0.5 Sig2 -> Sig2 -> Sig2
forall a. Num a => a -> a -> a
* (Sig -> Sig2
f Sig
a Sig2 -> Sig2 -> Sig2
forall a. Num a => a -> a -> a
+ Sig -> Sig2
f Sig
b)

instance At Sig (SE Sig2) Sam where
  type AtOut Sig (SE Sig2) Sam = Sam
  at :: (Sig -> SE Sig2) -> Sam -> AtOut Sig (SE Sig2) Sam
at Sig -> 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 (Sig
a, Sig
b) = do
        Sig2
a' <- Sig -> SE Sig2
f Sig
a
        Sig2
b' <- Sig -> SE Sig2
f Sig
b
        Sig2 -> SE Sig2
forall a. a -> SE a
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 :: Sig -> (Sig2 -> Sig2) -> Sam -> AtOut Sig2 Sig2 Sam
mixAt Sig
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 -> Sig -> Sig2 -> Sig2 -> Sig2
forall a. (Num a, SigSpace a) => Sig -> a -> a -> a
cfd Sig
k Sig2
x (Sig2 -> Sig2
f Sig2
x)) Sam
sam

instance MixAt Sig2 (SE Sig2) Sam where
  mixAt :: Sig -> (Sig2 -> SE Sig2) -> Sam -> AtOut Sig2 (SE Sig2) Sam
mixAt Sig
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 a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> Sig2 -> Sig2 -> Sig2
forall a. (Num a, SigSpace a) => Sig -> a -> a -> a
cfd Sig
k Sig2
x) (Sig2 -> SE Sig2
f Sig2
x)) Sam
sam

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

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

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

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

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

-- | Constructs sample from limited mono signal (duration is in seconds)
sig1 :: Sig -> Sig -> Sam
sig1 :: Sig -> Sig -> Sam
sig1 Sig
dt Sig
a = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
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
_ -> Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (Sig
a, Sig
a) (Sig -> Dur
Dur Sig
dt)

-- | Constructs sample from limited stereo signal (duration is in seconds)
sig2 :: Sig -> Sig2 -> Sam
sig2 :: Sig -> Sig2 -> Sam
sig2 Sig
dt Sig2
a = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
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
_ -> Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S Sig2
a (Sig -> Dur
Dur Sig
dt)

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

-- | Constructs sample from limited stereo signal (duration is in BPMs)
fromSig2 :: Sig -> Sig2 -> Sam
fromSig2 :: Sig -> Sig2 -> Sam
fromSig2 Sig
dt = DurOf Sam -> Sam -> Sam
forall a. Limit a => DurOf a -> a -> a
lim Sig
DurOf Sam
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 Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig 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) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
sig (D -> Sig) -> D -> Sig
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 Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (Sig -> Sig2 -> Sig2
forall a. Sigs a => Sig -> a -> a
takeSnd (D -> Sig
sig D
len) (Sig2 -> Sig2) -> Sig2 -> Sig2
forall a b. (a -> b) -> a -> b
$ Sig -> String -> Sig2
loopWav (-Sig
1) String
fileName) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
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 Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (D -> D -> Sig -> String -> Sig2
readSegWav D
start D
end Sig
1 String
fileName) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
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 Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (D -> D -> Sig -> String -> Sig2
readSegWav D
start D
end (-Sig
1) String
fileName) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
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 = Sig -> D -> D -> D -> String -> Sam
genRndSeg Sig
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 = Sig -> D -> D -> D -> String -> Sam
genRndSeg (-Sig
1)

genRndSeg :: Sig -> D -> D -> D -> String -> Sam
genRndSeg :: Sig -> D -> D -> D -> String -> Sam
genRndSeg Sig
speed D
len D
start D
end String
fileName = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ SE (S Sig2) -> ReaderT Sig SE (S Sig2)
forall (m :: * -> *) a. Monad m => m a -> ReaderT Sig m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (SE (S Sig2) -> ReaderT Sig SE (S Sig2))
-> SE (S Sig2) -> ReaderT Sig 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 a. a -> SE a
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 -> Sig -> String -> Sig2
readSegWav D
a D
b Sig
speed String
fileName) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
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 -> Sig -> String -> Sam
ramWav LoopMode
loopMode Sig
speed String
fileName = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (LoopMode -> Sig -> String -> Sig2
ramSnd LoopMode
loopMode Sig
speed String
fileName) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
sig (D -> Sig) -> D -> Sig
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 -> Sig -> String -> Sam
ramWav1 LoopMode
loopMode Sig
speed String
fileName = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let x :: Sig
x = LoopMode -> Sig -> String -> Sig
ramSnd1 LoopMode
loopMode Sig
speed String
fileName in (Sig
x, Sig
x)) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
sig (D -> Sig) -> D -> Sig
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 Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let x :: Sig
x = String -> Sig
readSnd1 String
fileName in (Sig
x, Sig
x)) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
sig (D -> Sig) -> D -> Sig
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 Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let x :: Sig
x = Sig -> Sig -> Sig
forall a. Sigs a => Sig -> a -> a
takeSnd (D -> Sig
sig D
len) (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig -> String -> Sig
loopWav1 (-Sig
1) String
fileName in (Sig
x, Sig
x)) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
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 Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let x :: Sig
x = D -> D -> Sig -> String -> Sig
readSegWav1 D
start D
end Sig
1 String
fileName in (Sig
x, Sig
x)) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
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 Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (let x :: Sig
x = D -> D -> Sig -> String -> Sig
readSegWav1 D
start D
end (-Sig
1) String
fileName in (Sig
x, Sig
x)) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
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 = Sig -> D -> D -> D -> String -> Sam
genRndSeg1 Sig
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 = Sig -> D -> D -> D -> String -> Sam
genRndSeg1 (-Sig
1)

genRndSeg1 :: Sig -> D -> D -> D -> String -> Sam
genRndSeg1 :: Sig -> D -> D -> D -> String -> Sam
genRndSeg1 Sig
speed D
len D
start D
end String
fileName = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ SE (S Sig2) -> ReaderT Sig SE (S Sig2)
forall (m :: * -> *) a. Monad m => m a -> ReaderT Sig m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (SE (S Sig2) -> ReaderT Sig SE (S Sig2))
-> SE (S Sig2) -> ReaderT Sig 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 a. a -> SE a
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 :: Sig
y = D -> D -> Sig -> String -> Sig
readSegWav1 D
a D
b Sig
speed String
fileName in (Sig
y, Sig
y)) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ D -> Sig
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 :: Sig -> Sig -> Sig
toSec Sig
bpm Sig
a = Sig
a Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
60 Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ Sig
bpm

toSecD :: Bpm -> D -> D
toSecD :: Sig -> D -> D
toSecD Sig
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
/ (Sig -> D
ir Sig
bpm)

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

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

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

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

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

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

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

-- | Makes the sampler broader. It's reciprocal of str
--
-- > wide k = str (1 / k)
wide :: Sig -> Sam -> Sam
wide :: Sig -> Sam -> Sam
wide = Sig -> Sam -> Sam
DurOf Sam -> Sam -> Sam
forall a. Stretch a => DurOf a -> a -> a
str (Sig -> Sam -> Sam) -> (Sig -> Sig) -> Sig -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig
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 a. (a -> a -> a) -> [a] -> a
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 Sig SE (S Sig2)
ra) (Sam ReaderT Sig SE (S Sig2)
rb) = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ do
  S Sig2
a <- ReaderT Sig SE (S Sig2)
ra
  S Sig2
b <- ReaderT Sig 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 Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig 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 Sig
da, Dur Sig
db) -> Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (Sig2
sa Sig2 -> Sig2 -> Sig2
forall a. Num a => a -> a -> a
+ Sig -> Sig2 -> Sig2
forall a. Sigs a => Sig -> a -> a
delaySnd Sig
da Sig2
sb) (Sig -> Dur
Dur (Sig -> Dur) -> Sig -> Dur
forall a b. (a -> b) -> a -> b
$ Sig
da Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
+ Sig
db)
    (Dur
InfDur, Dur
_)      -> S Sig2
a
    (Dur Sig
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
+ Sig -> Sig2 -> Sig2
forall a. Sigs a => Sig -> a -> a
delaySnd Sig
da Sig2
sb) Dur
InfDur

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

genPick :: PickFun -> Sig -> [Sam] -> Sam
genPick :: PickFun -> Sig -> [Sam] -> Sam
genPick PickFun
pickFun Sig
dtSig [Sam]
as = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ do
  Sig
bpm <- ReaderT Sig SE Sig
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
  [S Sig2]
xs <- [ReaderT Sig SE (S Sig2)] -> ReaderT Sig SE [S Sig2]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ([ReaderT Sig SE (S Sig2)] -> ReaderT Sig SE [S Sig2])
-> [ReaderT Sig SE (S Sig2)] -> ReaderT Sig SE [S Sig2]
forall a b. (a -> b) -> a -> b
$ (Sam -> ReaderT Sig SE (S Sig2))
-> [Sam] -> [ReaderT Sig SE (S Sig2)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sam -> ReaderT Sig SE (S Sig2)
forall a. Sample a -> ReaderT Sig SE (S a)
unSam [Sam]
as
  let ds :: [D]
ds = (S Sig2 -> D) -> [S Sig2] -> [D]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> D
ir (Sig -> D) -> (S Sig2 -> Sig) -> S Sig2 -> D
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dur -> Sig
getDur (Dur -> Sig) -> (S Sig2 -> Dur) -> S Sig2 -> Sig
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 a b. (a -> b) -> [a] -> [b]
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 Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig 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 a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig2 -> SE Sig2) -> Sig2 -> SE Sig2
forall a b. (a -> b) -> a -> b
$ [Sig2] -> Sig -> Sig2
forall a. Tuple a => [a] -> Sig -> a
atTuple [Sig2]
sigs (Sig -> Sig2) -> Sig -> Sig2
forall a b. (a -> b) -> a -> b
$ D -> Sig
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 a b. (a -> b) -> Evt a -> Evt b
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 -> Sig
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 a b. (a -> b) -> [a] -> [b]
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
$ Sig -> Sig -> Evt Unit
metroS Sig
bpm Sig
dtSig) Dur
InfDur
  where
    getDur :: Dur -> Sig
getDur Dur
x = case Dur
x of
      Dur
InfDur -> -Sig
1
      Dur Sig
d  -> Sig
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 :: Sig -> [Sam] -> Sam
pick = PickFun -> Sig -> [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 :: Sig -> [(Sig, Sam)] -> Sam
pickBy Sig
dt [(Sig, Sam)]
as = PickFun -> Sig -> [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
$ [Sig] -> [(D, D)] -> Rnds (D, D)
forall a b. [a] -> [b] -> [(a, b)]
zip (((Sig, Sam) -> Sig) -> [(Sig, Sam)] -> [Sig]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig, Sam) -> Sig
forall a b. (a, b) -> a
fst [(Sig, Sam)]
as) [(D, D)]
ds) Sig
dt (((Sig, Sam) -> Sam) -> [(Sig, Sam)] -> [Sam]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig, Sam) -> Sam
forall a b. (a, b) -> b
snd [(Sig, 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 = (Sig -> S Sig2 -> S Sig2) -> Sam -> Sam
tfmS ((Sig -> S Sig2 -> S Sig2) -> Sam -> Sam)
-> (Sig -> S Sig2 -> S Sig2) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Sig
bpm S Sig2
a ->
  let absStart :: D
absStart = Sig -> D -> D
toSecD Sig
bpm D
start
      absEnd :: D
absEnd   = Sig -> D -> D
toSecD Sig
bpm D
end
  in  S Sig2
a { samSig = mul (env (samDur a) absStart absEnd) $ samSig 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] -> Sig
linseg [D
0, D
start, D
1]
  Dur Sig
d  -> [D] -> Sig
linseg [D
0, D
start, D
1, D -> D -> D
forall a. (IfB a, OrdB a) => a -> a -> a
maxB D
0 (Sig -> D
ir Sig
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] -> Sig
expseg [D
zero, D
start, D
1]
      Dur Sig
d  -> [D] -> Sig
expseg [D
zero, D
start, D
1, D -> D -> D
forall a. (IfB a, OrdB a) => a -> a -> a
maxB D
0 (Sig -> D
ir Sig
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 -> Sig) -> Sam -> Sam
genEnv1 D -> Sig
envFun = (S Sig2 -> Sig2) -> Sam -> Sam
tfmBy S Sig2 -> Sig2
f
  where
    f :: S Sig2 -> Sig2
f S Sig2
a = (Sig -> Sig2 -> Sig2) -> Sig2 -> Sig -> Sig2
forall a b c. (a -> b -> c) -> b -> a -> c
flip Sig -> Sig2 -> Sig2
forall a. SigSpace a => Sig -> a -> a
mul (S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
a) (Sig -> Sig2) -> Sig -> Sig2
forall a b. (a -> b) -> a -> b
$ case S Sig2 -> Dur
forall a. S a -> Dur
samDur S Sig2
a of
      Dur
InfDur -> Sig
1
      Dur Sig
d  -> D -> Sig
envFun (Sig -> D
ir Sig
d)


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

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

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

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

-- | Fade out exponential envelope.
edecEnv :: Sam -> Sam
edecEnv :: Sam -> Sam
edecEnv = (D -> Sig) -> Sam -> Sam
genEnv1 ((D -> Sig) -> Sam -> Sam) -> (D -> Sig) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \D
d -> [D] -> Sig
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
. (Sig -> S Sig2 -> S Sig2) -> Sam -> Sam
tfmS Sig -> S Sig2 -> S Sig2
f
  where
    f :: Sig -> S Sig2 -> S Sig2
f Sig
bpm S Sig2
a = S Sig2
a { samSig = case samDur a of
      Dur
InfDur -> S Sig2 -> Sig2
forall a. S a -> a
samSig S Sig2
a
      Dur Sig
d  -> LoopFun
g Sig
bpm Sig
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 :: Sig -> Sam -> Sam
rep1 = [Sig] -> Sam -> Sam
rep ([Sig] -> Sam -> Sam) -> (Sig -> [Sig]) -> Sig -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> [Sig]
forall a. a -> [a]
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 :: Sig -> Sam -> Sam
pat1 = [Sig] -> Sam -> Sam
pat ([Sig] -> Sam -> Sam) -> (Sig -> [Sig]) -> Sig -> Sam -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> [Sig]
forall a. a -> [a]
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 :: [Sig] -> Sam -> Sam
rep [Sig]
dts = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Sig
bpm Sig
_d Sig2
asig -> (Unit -> SE Sig2) -> Evt (Track Sig 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 a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return Sig2
asig) (Evt (Track Sig Unit) -> Sig2) -> Evt (Track Sig Unit) -> Sig2
forall a b. (a -> b) -> a -> b
$ (Unit -> Track Sig Unit) -> Evt Unit -> Evt (Track Sig Unit)
forall a b. (a -> b) -> Evt a -> Evt b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Track Sig Unit -> Unit -> Track Sig Unit
forall a b. a -> b -> a
const (Track Sig Unit -> Unit -> Track Sig Unit)
-> Track Sig Unit -> Unit -> Track Sig Unit
forall a b. (a -> b) -> a -> b
$ Sig -> Track Sig Unit
notes Sig
bpm) (Evt Unit -> Evt (Track Sig Unit))
-> Evt Unit -> Evt (Track Sig Unit)
forall a b. (a -> b) -> a -> b
$ Sig -> Sig -> Evt Unit
metroS Sig
bpm ([Sig] -> Sig
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Sig]
dts)
  where notes :: Sig -> Track Sig Unit
notes Sig
bpm = [Track Sig Unit] -> Track Sig Unit
forall a. Harmony a => [a] -> a
har ([Track Sig Unit] -> Track Sig Unit)
-> [Track Sig Unit] -> Track Sig Unit
forall a b. (a -> b) -> a -> b
$ (Sig -> Sig -> Track Sig Unit)
-> [Sig] -> [Sig] -> [Track Sig Unit]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Sig
t Sig
dt-> Sig -> Sig -> Unit -> Track Sig Unit
forall t a. Num t => t -> t -> a -> Track t a
singleEvent (Sig -> Sig -> Sig
toSec Sig
bpm Sig
t) (Sig -> Sig -> Sig
toSec Sig
bpm Sig
dt) Unit
unit) ([Sig] -> [Sig]
patDurs [Sig]
dts) [Sig]
dts

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

rndSkipInstr :: (Tuple a, Num a) => Sig -> a -> SE a
rndSkipInstr :: forall a. (Tuple a, Num a) => Sig -> a -> SE a
rndSkipInstr Sig
probSig a
asig = do
  let prob :: D
prob = Sig -> D
ir Sig
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' :: Sig -> [D] -> [Sig] -> Sam -> Sam
rndPat' Sig
prob [D]
vols [Sig]
dts = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Sig
bpm Sig
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 a b. (a -> b) -> Evt a -> Evt b
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
$ Sig -> Sig -> Sco D
notes Sig
bpm Sig
d) (Evt Unit -> Evt (Sco D)) -> Evt Unit -> Evt (Sco D)
forall a b. (a -> b) -> a -> b
$ Sig -> Sig -> Evt Unit
metroS Sig
bpm ([Sig] -> Sig
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Sig]
dts')
  where
    notes :: Sig -> Sig -> Sco D
notes Sig
bpm Sig
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 -> Sig -> Sco D) -> [D] -> [Sig] -> [Sco D]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\D
v Sig
t -> Sig -> Sig -> D -> Sco D
forall t a. Num t => t -> t -> a -> Track t a
singleEvent (Sig -> Sig -> Sig
toSec Sig
bpm Sig
t) Sig
d D
v) [D]
vols' ([Sig] -> [Sco D]) -> [Sig] -> [Sco D]
forall a b. (a -> b) -> a -> b
$ [Sig] -> [Sig]
patDurs [Sig]
dts'
    instr :: Sig2 -> D -> SE Sig2
instr Sig2
asig D
v = Sig -> SE Sig2 -> SE Sig2
forall a. SigSpace a => Sig -> a -> a
mul (D -> Sig
sig D
v) (SE Sig2 -> SE Sig2) -> SE Sig2 -> SE Sig2
forall a b. (a -> b) -> a -> b
$ Sig -> Sig2 -> SE Sig2
forall a. (Tuple a, Num a) => Sig -> a -> SE a
rndSkipInstr Sig
prob Sig2
asig
    ([D]
vols', [Sig]
dts') = [(D, Sig)] -> ([D], [Sig])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(D, Sig)] -> ([D], [Sig])) -> [(D, Sig)] -> ([D], [Sig])
forall a b. (a -> b) -> a -> b
$ [D] -> [Sig] -> [(D, Sig)]
forall a b. [a] -> [b] -> [(a, b)]
lcmList [D]
vols [Sig]
dts


lcmList :: [a] -> [b] -> [(a, b)]
lcmList :: forall a b. [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. HasCallStack => [a] -> [a]
cycle [a]
as) ([b] -> [b]
forall a. HasCallStack => [a] -> [a]
cycle [b]
bs)
  where n :: Int
n = Int -> Int -> Int
forall a. Integral a => a -> a -> a
lcm ([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
as) ([b] -> Int
forall a. [a] -> 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 :: Sig -> Sam -> Sam
wall Sig
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 Sig
DurOf Sam
hdt Sam
b]
  where
    hdt :: Sig
hdt = Sig
0.5 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
dt
    f :: Sam -> Sam
f = Sig -> Sam -> Sam
pat1 Sig
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 Sig
DurOf Sam
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 a. a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig2 -> SE Sig2) -> Sig2 -> SE Sig2
forall a b. (a -> b) -> a -> b
$ (Sig -> Sig) -> Sig2 -> Sig2
forall a. SigSpace a => (Sig -> Sig) -> a -> a
mapSig (Sig -> Sig -> Sig
scalePitch (D -> Sig
sig D
k)) Sig2
asig

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

genArp1 :: Arp1Fun -> Sig -> Sam -> Sam
genArp1 :: Arp1Fun -> Sig -> Sam -> Sam
genArp1 Arp1Fun
arpFun Sig
dt = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Sig
bpm Sig
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
$ Sig -> Evt D -> Evt (Sco D)
forall a. Sig -> Evt a -> Evt (Sco a)
withDur Sig
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
$ Sig -> Sig -> Evt Unit
metroS Sig
bpm Sig
dt

-- | Plays ascending arpeggio of samples.
arpUp1 :: Chord -> Sig -> Sam -> Sam
arpUp1 :: [D] -> Sig -> Sam -> Sam
arpUp1 = Arp1Fun -> Sig -> Sam -> Sam
genArp1 (Arp1Fun -> Sig -> Sam -> Sam)
-> ([D] -> Arp1Fun) -> [D] -> Sig -> 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] -> Sig -> Sam -> Sam
arpDown1 [D]
ch = [D] -> Sig -> 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] -> Sig -> Sam -> Sam
arpOneOf1 = Arp1Fun -> Sig -> Sam -> Sam
genArp1 (Arp1Fun -> Sig -> Sam -> Sam)
-> ([D] -> Arp1Fun) -> [D] -> Sig -> 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 :: [Sig] -> [D] -> Sig -> Sam -> Sam
arpFreqOf1 [Sig]
freqs [D]
ch = Arp1Fun -> Sig -> Sam -> Sam
genArp1 (Rnds D -> Arp1Fun
forall a b. (Tuple a, Arg a) => Rnds a -> Evt b -> Evt a
freqOf ([Sig] -> [D] -> Rnds D
forall a b. [a] -> [b] -> [(a, b)]
zip [Sig]
freqs [D]
ch))

genArp :: Arp1Fun -> [Sig] -> Sam -> Sam
genArp :: Arp1Fun -> [Sig] -> Sam -> Sam
genArp Arp1Fun
arpFun [Sig]
dts = LoopFun -> Sam -> Sam
genLoop (LoopFun -> Sam -> Sam) -> LoopFun -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ \Sig
bpm Sig
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 a b. (a -> b) -> Evt a -> Evt b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> Sig -> D -> Sco D
notes Sig
bpm Sig
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
$ Sig -> Sig -> Evt Unit
metroS Sig
bpm ([Sig] -> Sig
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Sig]
dts)
  where notes :: Sig -> Sig -> D -> Sco D
notes Sig
bpm Sig
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
$ (Sig -> Sco D) -> [Sig] -> [Sco D]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Sig
t -> Sig -> Sig -> D -> Sco D
forall t a. Num t => t -> t -> a -> Track t a
singleEvent (Sig -> Sig -> Sig
toSec Sig
bpm Sig
t) Sig
d D
pchScale) ([Sig] -> [Sco D]) -> [Sig] -> [Sco D]
forall a b. (a -> b) -> a -> b
$ [Sig] -> [Sig]
patDurs [Sig]
dts

-- | Plays ascending arpeggio of samples.
arpUp :: Chord -> [Sig] -> Sam -> Sam
arpUp :: [D] -> [Sig] -> Sam -> Sam
arpUp = Arp1Fun -> [Sig] -> Sam -> Sam
genArp (Arp1Fun -> [Sig] -> Sam -> Sam)
-> ([D] -> Arp1Fun) -> [D] -> [Sig] -> 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] -> [Sig] -> Sam -> Sam
arpDown [D]
ch = [D] -> [Sig] -> 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] -> [Sig] -> Sam -> Sam
arpOneOf = Arp1Fun -> [Sig] -> Sam -> Sam
genArp (Arp1Fun -> [Sig] -> Sam -> Sam)
-> ([D] -> Arp1Fun) -> [D] -> [Sig] -> 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 :: [Sig] -> [D] -> [Sig] -> Sam -> Sam
arpFreqOf [Sig]
freqs [D]
ch = Arp1Fun -> [Sig] -> 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
$ [Sig] -> [D] -> Rnds D
forall a b. [a] -> [b] -> [(a, b)]
zip [Sig]
freqs [D]
ch)

metroS :: Bpm -> Sig -> Evt Unit
metroS :: Sig -> Sig -> Evt Unit
metroS Sig
bpm Sig
dt = Sig -> Evt Unit
metro (Sig -> Sig
forall a. Fractional a => a -> a
recip (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig -> Sig -> Sig
toSec Sig
bpm Sig
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 :: [(Sig, Sig, Sig)] -> Sam -> Sam
forAirports [(Sig, Sig, Sig)]
xs Sam
sample = [Sam] -> Sam
forall a. Fractional a => [a] -> a
mean ([Sam] -> Sam) -> [Sam] -> Sam
forall a b. (a -> b) -> a -> b
$ (((Sig, Sig, Sig) -> Sam) -> [(Sig, Sig, Sig)] -> [Sam])
-> [(Sig, Sig, Sig)] -> ((Sig, Sig, Sig) -> Sam) -> [Sam]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Sig, Sig, Sig) -> Sam) -> [(Sig, Sig, Sig)] -> [Sam]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Sig, Sig, Sig)]
xs (((Sig, Sig, Sig) -> Sam) -> [Sam])
-> ((Sig, Sig, Sig) -> Sam) -> [Sam]
forall a b. (a -> b) -> a -> b
$
    \(Sig
delTime, Sig
loopTime, Sig
note) -> DurOf Sam -> Sam -> Sam
forall a. Delay a => DurOf a -> a -> a
del Sig
DurOf Sam
delTime (Sam -> Sam) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ [Sig] -> Sam -> Sam
pat [Sig
loopTime] (Sig -> Sam -> Sam
atPch Sig
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 :: [(Sig, Sig, Sam)] -> Sam
genForAirports [(Sig, Sig, Sam)]
xs = [Sam] -> Sam
forall a. Fractional a => [a] -> a
mean ([Sam] -> Sam) -> [Sam] -> Sam
forall a b. (a -> b) -> a -> b
$ ((Sig, Sig, Sam) -> Sam) -> [(Sig, Sig, Sam)] -> [Sam]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Sig
delTime, Sig
loopTime, Sam
sample) -> DurOf Sam -> Sam -> Sam
forall a. Delay a => DurOf a -> a -> a
del Sig
DurOf Sam
delTime (Sam -> Sam) -> Sam -> Sam
forall a b. (a -> b) -> a -> b
$ [Sig] -> Sam -> Sam
pat [Sig
loopTime] Sam
sample) [(Sig, Sig, Sam)]
xs

arp1 :: (SigSpace a, Sigs a) => (D -> SE a) -> Sig -> Sig -> Int -> [D] -> a
arp1 :: forall a.
(SigSpace a, Sigs a) =>
(D -> SE a) -> Sig -> Sig -> Int -> [D] -> a
arp1 D -> SE a
instr Sig
bpm Sig
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 a b. (a -> b) -> SE a -> SE b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> a -> a
forall a. SigSpace a => Sig -> a -> a
mul (D -> Sig
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
$
  Sig -> Evt (D, D) -> Evt (Sco (D, D))
forall a. Sig -> Evt a -> Evt (Sco a)
withDur (Sig -> Sig -> Sig
toSec Sig
bpm Sig
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
$ Sig -> Sig -> Evt Unit
metroS Sig
bpm Sig
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) -> Sig -> Sig -> Int -> [[D]] -> Sam
arpy D -> SE Sig2
instr Sig
chordPeriod Sig
speed Int
accentNum [[D]]
chords = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ do
  Sig
bpm <- ReaderT Sig SE Sig
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
  S Sig2
res <- Sam -> ReaderT Sig SE (S Sig2)
forall a. Sample a -> ReaderT Sig SE (S a)
unSam (Sam -> ReaderT Sig SE (S Sig2)) -> Sam -> ReaderT Sig 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
. Sig -> Sig2 -> Sam
fromSig2 Sig
chordPeriod (Sig2 -> Sam) -> ([D] -> Sig2) -> [D] -> Sam
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (D -> SE Sig2) -> Sig -> Sig -> Int -> [D] -> Sig2
forall a.
(SigSpace a, Sigs a) =>
(D -> SE a) -> Sig -> Sig -> Int -> [D] -> a
arp1 D -> SE Sig2
instr Sig
bpm Sig
speed Int
accentNum) [[D]]
chords
  S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig 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 :: forall a. ToSam a => Sig -> a -> Sam
limSam Sig
dt = DurOf Sam -> Sam -> Sam
forall a. Limit a => DurOf a -> a -> a
lim Sig
DurOf Sam
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 :: Sig -> Sam
toSam Sig
x = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig SE (S Sig2)
forall a b. (a -> b) -> a -> b
$ Sig2 -> Dur -> S Sig2
forall a. a -> Dur -> S a
S (Sig
x, Sig
x) Dur
InfDur

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

instance ToSam (SE Sig2) where
  toSam :: SE Sig2 -> Sam
toSam SE Sig2
x = ReaderT Sig SE (S Sig2) -> Sam
forall a. ReaderT Sig SE (S a) -> Sample a
Sam (ReaderT Sig SE (S Sig2) -> Sam) -> ReaderT Sig SE (S Sig2) -> Sam
forall a b. (a -> b) -> a -> b
$ do
    Sig2
y <- SE Sig2 -> ReaderT Sig SE Sig2
forall (m :: * -> *) a. Monad m => m a -> ReaderT Sig m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift SE Sig2
x
    S Sig2 -> ReaderT Sig SE (S Sig2)
forall a. a -> ReaderT Sig SE a
forall (m :: * -> *) a. Monad m => a -> m a
return (S Sig2 -> ReaderT Sig SE (S Sig2))
-> S Sig2 -> ReaderT Sig 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 -> Sig -> Sig -> String -> Sam
ramLoop D
winSize Sig
tempo Sig
pitch String
file = Sig2 -> Sam
forall a. ToSam a => a -> Sam
toSam (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig -> Sig -> String -> Sig2
loopRam D
winSize Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
ramRead D
winSize Sig
tempo Sig
pitch String
file = Sig -> Sig2 -> Sam
sig2 (D -> Sig
sig (String -> D
lengthSnd String
file) Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ Sig
tempo) (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig -> Sig -> String -> Sig2
readRam D
winSize Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
segLoop D
winSize Sig2
ds Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sig2
loopSeg D
winSize Sig2
ds Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
segRead D
winSize ds :: Sig2
ds@(Sig
kmin, Sig
kmax) Sig
tempo Sig
pitch String
file = Sig -> Sig2 -> Sam
sig2 ((Sig
kmax Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
- Sig
kmin) Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ Sig
tempo) (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Sig -> Sig -> String -> Sig2
readSeg D
winSize Sig2
ds Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
relLoop D
winSize Sig2
ds Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sig2
loopRel D
winSize Sig2
ds Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
relRead D
winSize ds :: Sig2
ds@(Sig
kmin, Sig
kmax) Sig
tempo Sig
pitch String
file = Sig -> Sig2 -> Sam
sig2 ((Sig
kmax Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
- Sig
kmin) Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ Sig
tempo) (Sig2 -> Sam) -> Sig2 -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Sig -> Sig -> String -> Sig2
readRel D
winSize Sig2
ds Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
ramLoop1 D
winSize Sig
tempo Sig
pitch String
file = Sig -> Sam
forall a. ToSam a => a -> Sam
toSam (Sig -> Sam) -> Sig -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig -> Sig -> String -> Sig
loopRam1 D
winSize Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
ramRead1 D
winSize Sig
tempo Sig
pitch String
file = Sig -> Sig -> Sam
sig1 (D -> Sig
sig (String -> D
lengthSnd String
file) Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ Sig
tempo) (Sig -> Sam) -> Sig -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig -> Sig -> String -> Sig
readRam1 D
winSize Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
segLoop1 D
winSize Sig2
ds Sig
tempo Sig
pitch String
file = Sig -> Sam
forall a. ToSam a => a -> Sam
toSam (Sig -> Sam) -> Sig -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Sig -> Sig -> String -> Sig
loopSeg1 D
winSize Sig2
ds Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
segRead1 D
winSize ds :: Sig2
ds@(Sig
kmin, Sig
kmax) Sig
tempo Sig
pitch String
file = Sig -> Sig -> Sam
sig1 ((Sig
kmax Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
- Sig
kmin) Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ Sig
tempo) (Sig -> Sam) -> Sig -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Sig -> Sig -> String -> Sig
readSeg1 D
winSize Sig2
ds Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
relLoop1 D
winSize Sig2
ds Sig
tempo Sig
pitch String
file = Sig -> Sam
forall a. ToSam a => a -> Sam
toSam (Sig -> Sam) -> Sig -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Sig -> Sig -> String -> Sig
loopRel1 D
winSize Sig2
ds Sig
tempo Sig
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 -> Sig -> Sig -> String -> Sam
relRead1 D
winSize ds :: Sig2
ds@(Sig
kmin, Sig
kmax) Sig
tempo Sig
pitch String
file = Sig -> Sig -> Sam
sig1 ((Sig
kmax Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
- Sig
kmin) Sig -> Sig -> Sig
forall a. Fractional a => a -> a -> a
/ Sig
tempo) (Sig -> Sam) -> Sig -> Sam
forall a b. (a -> b) -> a -> b
$ D -> Sig2 -> Sig -> Sig -> String -> Sig
readRel1 D
winSize Sig2
ds Sig
tempo Sig
pitch String
file

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

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

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

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

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

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

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