-- | Common unit generator graphs.
module Sound.SC3.UGen.Bindings.Composite where

import Control.Monad {- base -}
import Data.List {- base -}
import qualified Data.List.Split as Split {- split -}
import Data.Maybe {- base -}

import Sound.SC3.Common.Enum
import Sound.SC3.Common.Envelope
import Sound.SC3.Common.Math
import Sound.SC3.Common.Math.Filter.BEQ
import Sound.SC3.Common.Math.Operator
import Sound.SC3.Common.Rate
import Sound.SC3.Common.UId

import Sound.SC3.UGen.Bindings.DB
import Sound.SC3.UGen.Bindings.HW
import Sound.SC3.UGen.Bindings.Monad
import Sound.SC3.UGen.Type
import Sound.SC3.UGen.UGen

-- | Generate a localBuf and use setBuf to initialise it.
asLocalBuf :: ID i => i -> [UGen] -> UGen
asLocalBuf :: i -> [UGen] -> UGen
asLocalBuf i
i [UGen]
xs =
    let b :: UGen
b = i -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen
localBuf i
i UGen
1 (Int -> UGen
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([UGen] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [UGen]
xs))
        s :: UGen
s = UGen -> [UGen] -> UGen -> UGen
setBuf' UGen
b [UGen]
xs UGen
0
    in UGen -> UGen -> UGen
mrg2 UGen
b UGen
s

-- | balance2 with MCE input.
balanceStereo :: UGen -> UGen -> UGen -> UGen
balanceStereo :: UGen -> UGen -> UGen -> UGen
balanceStereo UGen
sig UGen
pos UGen
level = let (UGen
x,UGen
y) = UGen -> (UGen, UGen)
unmce2 UGen
sig in UGen -> UGen -> UGen -> UGen -> UGen
balance2 UGen
x UGen
y UGen
pos UGen
level

-- | 24db/oct rolloff - 4th order resonant Low Pass Filter
bLowPass4 :: UGen -> UGen -> UGen -> UGen
bLowPass4 :: UGen -> UGen -> UGen -> UGen
bLowPass4 UGen
i UGen
f UGen
rq =
  let (UGen
a0, UGen
a1, UGen
a2, UGen
b1, UGen
b2) = UGen -> UGen -> UGen -> (UGen, UGen, UGen, UGen, UGen)
forall a. Floating a => a -> a -> a -> (a, a, a, a, a)
bLowPassCoef UGen
sampleRate UGen
f UGen
rq
      flt :: UGen -> UGen
flt UGen
z = UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
sos UGen
z UGen
a0 UGen
a1 UGen
a2 UGen
b1 UGen
b2
  in UGen -> UGen
flt (UGen -> UGen
flt UGen
i)

-- | 24db/oct rolloff - 4th order resonant Hi Pass Filter
bHiPass4 :: UGen -> UGen -> UGen -> UGen
bHiPass4 :: UGen -> UGen -> UGen -> UGen
bHiPass4 UGen
i UGen
f UGen
rq =
  let (UGen
a0, UGen
a1, UGen
a2, UGen
b1, UGen
b2) = UGen -> UGen -> UGen -> (UGen, UGen, UGen, UGen, UGen)
forall a. Floating a => a -> a -> a -> (a, a, a, a, a)
bHiPassCoef UGen
sampleRate UGen
f UGen
rq
      flt :: UGen -> UGen
flt UGen
z = UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
sos UGen
z UGen
a0 UGen
a1 UGen
a2 UGen
b1 UGen
b2
  in UGen -> UGen
flt (UGen -> UGen
flt UGen
i)

-- | Buffer reader (no interpolation).
bufRdN :: Int -> Rate -> UGen -> UGen -> Loop UGen -> UGen
bufRdN :: Int -> Rate -> UGen -> UGen -> Loop UGen -> UGen
bufRdN Int
n Rate
r UGen
b UGen
p Loop UGen
l = Int
-> Rate -> UGen -> UGen -> Loop UGen -> Interpolation UGen -> UGen
bufRd Int
n Rate
r UGen
b UGen
p Loop UGen
l Interpolation UGen
forall t. Interpolation t
NoInterpolation

-- | Buffer reader (linear interpolation).
bufRdL :: Int -> Rate -> UGen -> UGen -> Loop UGen -> UGen
bufRdL :: Int -> Rate -> UGen -> UGen -> Loop UGen -> UGen
bufRdL Int
n Rate
r UGen
b UGen
p Loop UGen
l = Int
-> Rate -> UGen -> UGen -> Loop UGen -> Interpolation UGen -> UGen
bufRd Int
n Rate
r UGen
b UGen
p Loop UGen
l Interpolation UGen
forall t. Interpolation t
LinearInterpolation

-- | Buffer reader (cubic interpolation).
bufRdC :: Int -> Rate -> UGen -> UGen -> Loop UGen -> UGen
bufRdC :: Int -> Rate -> UGen -> UGen -> Loop UGen -> UGen
bufRdC Int
n Rate
r UGen
b UGen
p Loop UGen
l = Int
-> Rate -> UGen -> UGen -> Loop UGen -> Interpolation UGen -> UGen
bufRd Int
n Rate
r UGen
b UGen
p Loop UGen
l Interpolation UGen
forall t. Interpolation t
CubicInterpolation

-- | Triggers when a value changes
changed :: UGen -> UGen -> UGen
changed :: UGen -> UGen -> UGen
changed UGen
input UGen
threshold = UGen -> UGen
forall a. Num a => a -> a
abs (UGen -> UGen
hpz1 UGen
input) UGen -> UGen -> UGen
forall a. OrdE a => a -> a -> a
`greater_than` UGen
threshold

-- | 'mce' variant of 'lchoose'.
choose :: ID m => m -> UGen -> UGen
choose :: m -> UGen -> UGen
choose m
e = m -> [UGen] -> UGen
forall m. ID m => m -> [UGen] -> UGen
lchoose m
e ([UGen] -> UGen) -> (UGen -> [UGen]) -> UGen -> UGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UGen -> [UGen]
mceChannels

-- | 'liftUId' of 'choose'.
chooseM :: UId m => UGen -> m UGen
chooseM :: UGen -> m UGen
chooseM = (Int -> UGen -> UGen) -> UGen -> m UGen
forall (m :: * -> *) a b. UId m => (Int -> Fn1 a b) -> Fn1 a (m b)
liftUId1 Int -> UGen -> UGen
forall m. ID m => m -> UGen -> UGen
choose

-- | 'clearBuf' of 'localBuf'.
clearLocalBuf :: ID a => a -> UGen -> UGen -> UGen
clearLocalBuf :: a -> UGen -> UGen -> UGen
clearLocalBuf a
z UGen
nc UGen
nf = UGen -> UGen
clearBuf (a -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen
localBuf a
z UGen
nc UGen
nf)

-- | Demand rate (:) function.
dcons :: ID m => (m,m,m) -> UGen -> UGen -> UGen
dcons :: (m, m, m) -> UGen -> UGen -> UGen
dcons (m
z0,m
z1,m
z2) UGen
x UGen
xs =
    let i :: UGen
i = m -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen
dseq m
z0 UGen
1 (UGen -> UGen -> UGen
mce2 UGen
0 UGen
1)
        a :: UGen
a = m -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen
dseq m
z1 UGen
1 (UGen -> UGen -> UGen
mce2 UGen
x UGen
xs)
    in m -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen
dswitch m
z2 UGen
i UGen
a

-- | Demand rate (:) function.
dconsM :: (UId m) => UGen -> UGen -> m UGen
dconsM :: UGen -> UGen -> m UGen
dconsM UGen
x UGen
xs = do
  UGen
i <- UGen -> UGen -> m UGen
forall (m :: * -> *). UId m => UGen -> UGen -> m UGen
dseqM UGen
1 (UGen -> UGen -> UGen
mce2 UGen
0 UGen
1)
  UGen
a <- UGen -> UGen -> m UGen
forall (m :: * -> *). UId m => UGen -> UGen -> m UGen
dseqM UGen
1 (UGen -> UGen -> UGen
mce2 UGen
x UGen
xs)
  UGen -> UGen -> m UGen
forall (m :: * -> *). UId m => UGen -> UGen -> m UGen
dswitchM UGen
i UGen
a

-- | Dynamic klang, dynamic sine oscillator bank
dynKlang :: Rate -> UGen -> UGen -> UGen -> UGen
dynKlang :: Rate -> UGen -> UGen -> UGen -> UGen
dynKlang Rate
r UGen
fs UGen
fo UGen
s =
    let gen :: [UGen] -> UGen
gen (UGen
f:UGen
a:UGen
ph:[UGen]
xs) = Rate -> UGen -> UGen -> UGen
sinOsc Rate
r (UGen
f UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
fs UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
fo) UGen
ph UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
a UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ [UGen] -> UGen
gen [UGen]
xs
        gen [UGen]
_ = UGen
0
    in [UGen] -> UGen
gen (UGen -> [UGen]
mceChannels UGen
s)

-- | Dynamic klank, set of non-fixed resonating filters.
dynKlank :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
dynKlank :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
dynKlank UGen
i UGen
fs UGen
fo UGen
ds UGen
s =
    let gen :: [UGen] -> UGen
gen (UGen
f:UGen
a:UGen
d:[UGen]
xs) = UGen -> UGen -> UGen -> UGen
ringz UGen
i (UGen
f UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
fs UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
fo) (UGen
d UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
ds) UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
a UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ [UGen] -> UGen
gen [UGen]
xs
        gen [UGen]
_ = UGen
0
    in [UGen] -> UGen
gen (UGen -> [UGen]
mceChannels UGen
s)

-- | 'linExp' with input range of (-1,1).
exprange :: UGen -> UGen -> UGen -> UGen
exprange :: UGen -> UGen -> UGen -> UGen
exprange UGen
l UGen
r UGen
s = UGen -> UGen -> UGen -> UGen -> UGen -> UGen
linExp UGen
s (-UGen
1) UGen
1 UGen
l UGen
r

-- | Variant of `exprange` with arguments to make writing post-fix nicer.
in_exprange :: UGen -> (UGen, UGen) -> UGen
in_exprange :: UGen -> (UGen, UGen) -> UGen
in_exprange UGen
s (UGen
l,UGen
r) = UGen -> UGen -> UGen -> UGen
exprange UGen
l UGen
r UGen
s

-- | Variant FFT constructor with default values for hop size (0.5),
-- window type (0), active status (1) and window size (0).
fft' :: UGen -> UGen -> UGen
fft' :: UGen -> UGen -> UGen
fft' UGen
buf UGen
i = UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
fft UGen
buf UGen
i UGen
0.5 UGen
0 UGen
1 UGen
0

-- | 'fft' variant that allocates 'localBuf'.
--
-- > let c = ffta 'α' 2048 (soundIn 0) 0.5 0 1 0
-- > in audition (out 0 (ifft c 0 0))
ffta :: ID i => i -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
ffta :: i -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
ffta i
z UGen
nf UGen
i UGen
h UGen
wt UGen
a UGen
ws =
    let b :: UGen
b = i -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen
localBuf i
z UGen
1 UGen
nf
    in UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
fft UGen
b UGen
i UGen
h UGen
wt UGen
a UGen
ws

-- | Sum of 'numInputBuses' and 'numOutputBuses'.
firstPrivateBus :: UGen
firstPrivateBus :: UGen
firstPrivateBus = UGen
numInputBuses UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
numOutputBuses

-- | Frequency shifter, in terms of 'hilbert' (see also 'freqShift').
freqShift_hilbert :: UGen -> UGen -> UGen -> UGen
freqShift_hilbert :: UGen -> UGen -> UGen -> UGen
freqShift_hilbert UGen
i UGen
f UGen
p =
    let o :: UGen
o = Rate -> UGen -> UGen -> UGen
sinOsc Rate
AR UGen
f ([UGen] -> UGen
mce [UGen
p UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
0.5 UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
forall a. Floating a => a
pi, UGen
p])
        h :: UGen
h = UGen -> UGen
hilbert UGen
i
    in UGen -> UGen
mix (UGen
h UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
o)

{- | UGen function to re-trigger an EnvGen envelope.
     Inputs are /gate/ (as set at EnvGen) and /reset/.
     The four state logic is: (1,0)->1 (1,1)->-1 (0,1)->0 (0,0)->0.
     If the gate input to EnvGen.kr is -1 the envelope ramps to zero in one control period.
     The reset input sequence 0,1,0 when the gate is open produces (1,-1,1), which resets the envelope.

> map (uncurry gateReset) [(1,0),(1,1),(0,1),(0,0)] == [1,-1,0,0]
-}
gateReset :: Num a => a -> a -> a
gateReset :: a -> a -> a
gateReset a
gt a
tr = a
gt a -> a -> a
forall a. Num a => a -> a -> a
- (a
gt a -> a -> a
forall a. Num a => a -> a -> a
* a
tr a -> a -> a
forall a. Num a => a -> a -> a
* a
2)

-- | Variant of 'hilbert' using FFT (with a delay) for better results.
-- Buffer should be 2048 or 1024.
-- 2048 = better results, more delay.
-- 1024 = less delay, little choppier results.
hilbertFIR :: UGen -> UGen -> UGen
hilbertFIR :: UGen -> UGen -> UGen
hilbertFIR UGen
s UGen
b =
  let c0 :: UGen
c0 = UGen -> UGen -> UGen
fft' UGen
b UGen
s
      c1 :: UGen
c1 = UGen -> UGen
pv_PhaseShift90 UGen
c0
      delay :: UGen
delay = Rate -> UGen -> UGen
bufDur Rate
KR UGen
b
  in UGen -> UGen -> UGen
mce2 (UGen -> UGen -> UGen -> UGen
delayN UGen
s UGen
delay UGen
delay) (UGen -> UGen
ifft' UGen
c1)

-- | Variant ifft with default value for window type.
ifft' :: UGen -> UGen
ifft' :: UGen -> UGen
ifft' UGen
buf = UGen -> UGen -> UGen -> UGen
ifft UGen
buf UGen
0 UGen
0

{-
-- | Linear interpolating variant on index.
indexL :: UGen -> UGen -> UGen
indexL b i =
    let x = index b i
        y = index b (i + 1)
    in linLin (frac i) 0 1 x y
-}

-- | Generalised Klan(k/g) specification rule.  /f/ unwraps inputs, /g/ wraps output.
--
-- > let r = [220,0.2,0,219,0.1,1,221,0.1,2]
-- > in klanx_spec_f id id [220,219,221] [0.2,0.1,0.1] [0,1,2] == r
klanx_spec_f :: (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f :: (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f a -> [b]
f [b] -> c
g a
fr a
am a
z = [b] -> c
g (([[b]] -> [b]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[b]] -> [b]) -> ([[b]] -> [[b]]) -> [[b]] -> [b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[b]] -> [[b]]
forall a. [[a]] -> [[a]]
transpose) [a -> [b]
f a
fr,a -> [b]
f a
am,a -> [b]
f a
z])

-- | Format frequency, amplitude and decay time data as required for klank.
klangSpec :: [UGen] -> [UGen] -> [UGen] -> UGen
klangSpec :: [UGen] -> [UGen] -> [UGen] -> UGen
klangSpec = ([UGen] -> [UGen])
-> ([UGen] -> UGen) -> [UGen] -> [UGen] -> [UGen] -> UGen
forall a b c. (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f [UGen] -> [UGen]
forall a. a -> a
id [UGen] -> UGen
mce

-- | Variant of 'klangSpec' for non-UGen inputs.
klangSpec_k :: Real n => [n] -> [n] -> [n] -> UGen
klangSpec_k :: [n] -> [n] -> [n] -> UGen
klangSpec_k = ([n] -> [UGen]) -> ([UGen] -> UGen) -> [n] -> [n] -> [n] -> UGen
forall a b c. (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f ((n -> UGen) -> [n] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map n -> UGen
forall n. Real n => n -> UGen
constant) [UGen] -> UGen
mce

-- | Variant of 'klangSpec' for 'MCE' inputs.
klangSpec_mce :: UGen -> UGen -> UGen -> UGen
klangSpec_mce :: UGen -> UGen -> UGen -> UGen
klangSpec_mce = (UGen -> [UGen])
-> ([UGen] -> UGen) -> UGen -> UGen -> UGen -> UGen
forall a b c. (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f UGen -> [UGen]
mceChannels [UGen] -> UGen
mce

-- | Format frequency, amplitude and decay time data as required for klank.
klankSpec :: [UGen] -> [UGen] -> [UGen] -> UGen
klankSpec :: [UGen] -> [UGen] -> [UGen] -> UGen
klankSpec = ([UGen] -> [UGen])
-> ([UGen] -> UGen) -> [UGen] -> [UGen] -> [UGen] -> UGen
forall a b c. (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f [UGen] -> [UGen]
forall a. a -> a
id [UGen] -> UGen
mce

-- | Variant for non-UGen inputs.
klankSpec_k :: Real n => [n] -> [n] -> [n] -> UGen
klankSpec_k :: [n] -> [n] -> [n] -> UGen
klankSpec_k = ([n] -> [UGen]) -> ([UGen] -> UGen) -> [n] -> [n] -> [n] -> UGen
forall a b c. (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f ((n -> UGen) -> [n] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map n -> UGen
forall n. Real n => n -> UGen
constant) [UGen] -> UGen
mce

-- | Variant of 'klankSpec' for 'MCE' inputs.
klankSpec_mce :: UGen -> UGen -> UGen -> UGen
klankSpec_mce :: UGen -> UGen -> UGen -> UGen
klankSpec_mce = (UGen -> [UGen])
-> ([UGen] -> UGen) -> UGen -> UGen -> UGen -> UGen
forall a b c. (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f UGen -> [UGen]
mceChannels [UGen] -> UGen
mce

-- | Randomly select one of a list of UGens (initialisation rate).
lchoose :: ID m => m -> [UGen] -> UGen
lchoose :: m -> [UGen] -> UGen
lchoose m
e [UGen]
a = UGen -> UGen -> UGen
select (m -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen
iRand m
e UGen
0 (Int -> UGen
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([UGen] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [UGen]
a))) ([UGen] -> UGen
mce [UGen]
a)

-- | 'liftUId' of 'lchoose'.
lchooseM :: UId m => [UGen] -> m UGen
lchooseM :: [UGen] -> m UGen
lchooseM = (Int -> [UGen] -> UGen) -> [UGen] -> m UGen
forall (m :: * -> *) a b. UId m => (Int -> Fn1 a b) -> Fn1 a (m b)
liftUId1 Int -> [UGen] -> UGen
forall m. ID m => m -> [UGen] -> UGen
lchoose

-- | 'linExp' of (-1,1).
linExp_b :: UGen -> UGen -> UGen -> UGen
linExp_b :: UGen -> UGen -> UGen -> UGen
linExp_b UGen
i = UGen -> UGen -> UGen -> UGen -> UGen -> UGen
linExp UGen
i (-UGen
1) UGen
1

-- | 'linExp' of (0,1).
linExp_u :: UGen -> UGen -> UGen -> UGen
linExp_u :: UGen -> UGen -> UGen -> UGen
linExp_u UGen
i = UGen -> UGen -> UGen -> UGen -> UGen -> UGen
linExp UGen
i UGen
0 UGen
1

-- | Map from one linear range to another linear range.
linLin :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
linLin :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
linLin = (UGen -> UGen -> UGen -> UGen)
-> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
forall a. Fractional a => SC3_MulAdd a -> a -> a -> SC3_MulAdd a
linlin_ma UGen -> UGen -> UGen -> UGen
mulAdd

-- | 'linLin' where source is (0,1).
linLin_u :: UGen -> UGen -> UGen -> UGen
linLin_u :: UGen -> UGen -> UGen -> UGen
linLin_u UGen
i = UGen -> UGen -> UGen -> UGen -> UGen -> UGen
linLin UGen
i UGen
0 UGen
1

-- | 'linLin' where source is (-1,1).
linLin_b :: UGen -> UGen -> UGen -> UGen
linLin_b :: UGen -> UGen -> UGen -> UGen
linLin_b UGen
i = UGen -> UGen -> UGen -> UGen -> UGen -> UGen
linLin UGen
i (-UGen
1) UGen
1

-- | Variant with defaults of zero.
localIn' :: Int -> Rate -> UGen
localIn' :: Int -> Rate -> UGen
localIn' Int
nc Rate
r = Int -> Rate -> UGen -> UGen
localIn Int
nc Rate
r ([UGen] -> UGen
mce (Int -> UGen -> [UGen]
forall a. Int -> a -> [a]
replicate Int
nc UGen
0))

-- | Generate an 'envGen' UGen with @fadeTime@ and @gate@ controls.
--
-- > import Sound.SC3
-- > audition (out 0 (makeFadeEnv 1 * sinOsc AR 440 0 * 0.1))
-- > withSC3 (send (n_set1 (-1) "gate" 0))
makeFadeEnv :: Double -> UGen
makeFadeEnv :: Double -> UGen
makeFadeEnv Double
fadeTime =
    let dt :: UGen
dt = Rate -> String -> Double -> UGen
control Rate
KR String
"fadeTime" (Double -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
fadeTime)
        gate_ :: UGen
gate_ = Rate -> String -> Double -> UGen
control Rate
KR String
"gate" Double
1
        startVal :: UGen
startVal = UGen
dt UGen -> UGen -> UGen
forall a. OrdE a => a -> a -> a
`less_than_or_equal_to` UGen
0
        env :: Envelope UGen
env = [UGen]
-> [UGen]
-> [Envelope_Curve UGen]
-> Maybe Int
-> Maybe Int
-> UGen
-> Envelope UGen
forall a.
[a]
-> [a]
-> [Envelope_Curve a]
-> Maybe Int
-> Maybe Int
-> a
-> Envelope a
Envelope [UGen
startVal,UGen
1,UGen
0] [UGen
1,UGen
1] [Envelope_Curve UGen
forall a. Envelope_Curve a
EnvLin,Envelope_Curve UGen
forall a. Envelope_Curve a
EnvLin] (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1) Maybe Int
forall a. Maybe a
Nothing UGen
0
    in Rate
-> UGen
-> UGen
-> UGen
-> UGen
-> DoneAction UGen
-> Envelope UGen
-> UGen
envGen Rate
KR UGen
gate_ UGen
1 UGen
0 UGen
dt DoneAction UGen
forall t. DoneAction t
RemoveSynth Envelope UGen
env

-- | 'mce' of 'map' /f/ of 'id_seq' /n/.
mce_gen :: ID z => (Id -> UGen) -> Int -> z -> UGen
mce_gen :: (Int -> UGen) -> Int -> z -> UGen
mce_gen Int -> UGen
f Int
n = [UGen] -> UGen
mce ([UGen] -> UGen) -> (z -> [UGen]) -> z -> UGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> UGen) -> [Int] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map Int -> UGen
f ([Int] -> [UGen]) -> (z -> [Int]) -> z -> [UGen]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> z -> [Int]
forall a. ID a => Int -> a -> [Int]
id_seq Int
n

-- | Monad/applicative variant of mce_gen.
mce_genM :: Applicative f => f UGen -> Int -> f UGen
mce_genM :: f UGen -> Int -> f UGen
mce_genM f UGen
f Int
n = ([UGen] -> UGen) -> f [UGen] -> f UGen
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [UGen] -> UGen
mce (Int -> f UGen -> f [UGen]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n f UGen
f)

-- | Count 'mce' channels.
mceN :: UGen -> UGen
mceN :: UGen -> UGen
mceN = Int -> UGen
forall n. Real n => n -> UGen
constant (Int -> UGen) -> (UGen -> Int) -> UGen -> UGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [UGen] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([UGen] -> Int) -> (UGen -> [UGen]) -> UGen -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UGen -> [UGen]
mceChannels

-- | Collapse possible mce by summing.
mix :: UGen -> UGen
mix :: UGen -> UGen
mix = [UGen] -> UGen
sum_opt ([UGen] -> UGen) -> (UGen -> [UGen]) -> UGen -> UGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UGen -> [UGen]
mceChannels

-- | Mix divided by number of inputs.
mceMean :: UGen -> UGen
mceMean :: UGen -> UGen
mceMean UGen
e = let p :: [UGen]
p = UGen -> [UGen]
mceChannels UGen
e in [UGen] -> UGen
sum_opt [UGen]
p UGen -> UGen -> UGen
forall a. Fractional a => a -> a -> a
/ Int -> UGen
forall n. Real n => n -> UGen
constant ([UGen] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [UGen]
p)

-- | Mix variant, sum to n channels.
mixN :: Int -> UGen -> UGen
mixN :: Int -> UGen -> UGen
mixN Int
n UGen
u =
    let xs :: [[UGen]]
xs = [[UGen]] -> [[UGen]]
forall a. [[a]] -> [[a]]
transpose (Int -> [UGen] -> [[UGen]]
forall e. Int -> [e] -> [[e]]
Split.chunksOf Int
n (UGen -> [UGen]
mceChannels UGen
u))
    in [UGen] -> UGen
mce (([UGen] -> UGen) -> [[UGen]] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map [UGen] -> UGen
sum_opt [[UGen]]
xs)

-- | Construct an MCE array of UGens.
mceFill :: Integral n => Int -> (n -> UGen) -> UGen
mceFill :: Int -> (n -> UGen) -> UGen
mceFill Int
n n -> UGen
f = [UGen] -> UGen
mce ((n -> UGen) -> [n] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map n -> UGen
f [n
0 .. Int -> n
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n n -> n -> n
forall a. Num a => a -> a -> a
- n
1])

-- | Type specialised mceFill
mceFillInt :: Int -> (Int -> UGen) -> UGen
mceFillInt :: Int -> (Int -> UGen) -> UGen
mceFillInt = Int -> (Int -> UGen) -> UGen
forall n. Integral n => Int -> (n -> UGen) -> UGen
mceFill

-- | Construct a list of ID UGens.
listFill_z :: (Integral n, ID z, Enum z) => z -> Int -> (z -> n -> UGen) -> [UGen]
listFill_z :: z -> Int -> (z -> n -> UGen) -> [UGen]
listFill_z z
z Int
n z -> n -> UGen
f = (z -> n -> UGen) -> [z] -> [n] -> [UGen]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith z -> n -> UGen
f [z
z..] [n
0 .. Int -> n
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n n -> n -> n
forall a. Num a => a -> a -> a
- n
1]

-- | 'mce' of 'listFill_z'
mceFill_z :: (Integral n, ID z, Enum z) => z -> Int -> (z -> n -> UGen) -> UGen
mceFill_z :: z -> Int -> (z -> n -> UGen) -> UGen
mceFill_z z
z Int
n = [UGen] -> UGen
mce ([UGen] -> UGen)
-> ((z -> n -> UGen) -> [UGen]) -> (z -> n -> UGen) -> UGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. z -> Int -> (z -> n -> UGen) -> [UGen]
forall n z.
(Integral n, ID z, Enum z) =>
z -> Int -> (z -> n -> UGen) -> [UGen]
listFill_z z
z Int
n

-- | Construct and sum a set of UGens.
mixFill :: Integral n => Int -> (n -> UGen) -> UGen
mixFill :: Int -> (n -> UGen) -> UGen
mixFill Int
n = UGen -> UGen
mix (UGen -> UGen) -> ((n -> UGen) -> UGen) -> (n -> UGen) -> UGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (n -> UGen) -> UGen
forall n. Integral n => Int -> (n -> UGen) -> UGen
mceFill Int
n

-- | Type specialised mixFill
mixFillInt :: Int -> (Int -> UGen) -> UGen
mixFillInt :: Int -> (Int -> UGen) -> UGen
mixFillInt = Int -> (Int -> UGen) -> UGen
forall n. Integral n => Int -> (n -> UGen) -> UGen
mixFill

-- | Type specialised mixFill
mixFillUGen :: Int -> (UGen -> UGen) -> UGen
mixFillUGen :: Int -> (UGen -> UGen) -> UGen
mixFillUGen = Int -> (UGen -> UGen) -> UGen
forall n. Integral n => Int -> (n -> UGen) -> UGen
mixFill

-- | Construct and sum a set of ID UGens.
mixFill_z :: (Integral n, ID z, Enum z) => z -> Int -> (z -> n -> UGen) -> UGen
mixFill_z :: z -> Int -> (z -> n -> UGen) -> UGen
mixFill_z z
z Int
n = UGen -> UGen
mix (UGen -> UGen)
-> ((z -> n -> UGen) -> UGen) -> (z -> n -> UGen) -> UGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. z -> Int -> (z -> n -> UGen) -> UGen
forall n z.
(Integral n, ID z, Enum z) =>
z -> Int -> (z -> n -> UGen) -> UGen
mceFill_z z
z Int
n

-- | Monad variant on mixFill.
mixFillM :: (Integral n,Monad m) => Int -> (n -> m UGen) -> m UGen
mixFillM :: Int -> (n -> m UGen) -> m UGen
mixFillM Int
n n -> m UGen
f = ([UGen] -> UGen) -> m [UGen] -> m UGen
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [UGen] -> UGen
sum_opt ((n -> m UGen) -> [n] -> m [UGen]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM n -> m UGen
f [n
0 .. Int -> n
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n n -> n -> n
forall a. Num a => a -> a -> a
- n
1])

-- | Apply the ID UGen processor /f/ /k/ times in sequence to /i/, ie. for k=4 /f (f (f (f i)))/.
useq_z :: (ID z, Enum z) => z -> Int -> (z -> UGen -> UGen) -> UGen -> UGen
useq_z :: z -> Int -> (z -> UGen -> UGen) -> UGen -> UGen
useq_z z
z Int
k z -> UGen -> UGen
f UGen
i = if Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 then UGen
i else z -> Int -> (z -> UGen -> UGen) -> UGen -> UGen
forall z.
(ID z, Enum z) =>
z -> Int -> (z -> UGen -> UGen) -> UGen -> UGen
useq_z (z -> z
forall a. Enum a => a -> a
succ z
z) (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) z -> UGen -> UGen
f (z -> UGen -> UGen
f z
z UGen
i)

-- | Variant that is randomly pressed.
mouseButton' :: Rate -> UGen -> UGen -> UGen -> UGen
mouseButton' :: Rate -> UGen -> UGen -> UGen -> UGen
mouseButton' Rate
rt UGen
l UGen
r UGen
tm =
    let o :: UGen
o = Char -> Rate -> UGen -> UGen
forall a. ID a => a -> Rate -> UGen -> UGen
lfClipNoise Char
'z' Rate
rt UGen
1
    in UGen -> UGen -> UGen
lag (UGen -> UGen -> UGen -> UGen -> UGen -> UGen
linLin UGen
o (-UGen
1) UGen
1 UGen
l UGen
r) UGen
tm

-- | Randomised mouse UGen (see also 'mouseX'' and 'mouseY'').
mouseR :: ID a => a -> Rate -> UGen -> UGen -> Warp UGen -> UGen -> UGen
mouseR :: a -> Rate -> UGen -> UGen -> Warp UGen -> UGen -> UGen
mouseR a
z Rate
rt UGen
l UGen
r Warp UGen
ty UGen
tm =
  let f :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
f = case Warp UGen
ty of
            Warp UGen
Linear -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
linLin
            Warp UGen
Exponential -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
linExp
            Warp UGen
_ -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
forall a. HasCallStack => a
undefined
  in UGen -> UGen -> UGen
lag (UGen -> UGen -> UGen -> UGen -> UGen -> UGen
f (a -> Rate -> UGen -> UGen
forall a. ID a => a -> Rate -> UGen -> UGen
lfNoise1 a
z Rate
rt UGen
1) (-UGen
1) UGen
1 UGen
l UGen
r) UGen
tm

-- | Variant that randomly traverses the mouseX space.
mouseX' :: Rate -> UGen -> UGen -> Warp UGen -> UGen -> UGen
mouseX' :: Rate -> UGen -> UGen -> Warp UGen -> UGen -> UGen
mouseX' = Char -> Rate -> UGen -> UGen -> Warp UGen -> UGen -> UGen
forall a.
ID a =>
a -> Rate -> UGen -> UGen -> Warp UGen -> UGen -> UGen
mouseR Char
'x'

-- | Variant that randomly traverses the mouseY space.
mouseY' :: Rate -> UGen -> UGen -> Warp UGen -> UGen -> UGen
mouseY' :: Rate -> UGen -> UGen -> Warp UGen -> UGen -> UGen
mouseY' = Char -> Rate -> UGen -> UGen -> Warp UGen -> UGen -> UGen
forall a.
ID a =>
a -> Rate -> UGen -> UGen -> Warp UGen -> UGen -> UGen
mouseR Char
'y'

-- | Translate onset type string to constant UGen value.
onsetType :: Num a => String -> a
onsetType :: String -> a
onsetType String
s =
    let t :: [String]
t = [String
"power", String
"magsum", String
"complex", String
"rcomplex", String
"phase", String
"wphase", String
"mkl"]
    in Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
3 (String -> [String] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
elemIndex String
s [String]
t))

-- | Onset detector with default values for minor parameters.
onsets' :: UGen -> UGen -> UGen -> UGen
onsets' :: UGen -> UGen -> UGen -> UGen
onsets' UGen
c UGen
t UGen
o = UGen
-> UGen
-> UGen
-> UGen
-> UGen
-> UGen
-> UGen
-> UGen
-> UGen
-> UGen
onsets UGen
c UGen
t UGen
o UGen
1 UGen
0.1 UGen
10 UGen
11 UGen
1 UGen
0

-- | Format magnitude and phase data data as required for packFFT.
packFFTSpec :: [UGen] -> [UGen] -> UGen
packFFTSpec :: [UGen] -> [UGen] -> UGen
packFFTSpec [UGen]
m [UGen]
p =
    let interleave :: [a] -> [a] -> [a]
interleave [a]
x = [[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[a]] -> [a]) -> ([a] -> [[a]]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a -> [a]) -> [a] -> [a] -> [[a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\a
a a
b -> [a
a,a
b]) [a]
x
    in [UGen] -> UGen
mce ([UGen] -> [UGen] -> [UGen]
forall a. [a] -> [a] -> [a]
interleave [UGen]
m [UGen]
p)

-- | Calculate size of accumulation buffer given FFT and IR sizes.
partConv_calcAccumSize :: Int -> Int -> Int
partConv_calcAccumSize :: Int -> Int -> Int
partConv_calcAccumSize Int
fft_size Int
ir_length =
    let partition_size :: Int
partition_size = Int
fft_size Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2
        num_partitions :: Int
num_partitions = (Int
ir_length Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
partition_size) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
    in Int
fft_size Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
num_partitions

-- | PM oscillator.
-- cf = carrier frequency, mf = modulation frequency, pm = pm-index = 0.0, mp = mod-phase = 0.0
pmOsc :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
pmOsc :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
pmOsc Rate
r UGen
cf UGen
mf UGen
pm UGen
mp = Rate -> UGen -> UGen -> UGen
sinOsc Rate
r UGen
cf (Rate -> UGen -> UGen -> UGen
sinOsc Rate
r UGen
mf UGen
mp UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
pm)

-- | Variant of 'poll' that generates an 'mrg' value with the input
-- signal at left, and that allows a constant /frequency/ input in
-- place of a trigger.
poll' :: UGen -> UGen -> UGen -> UGen -> UGen
poll' :: UGen -> UGen -> UGen -> UGen -> UGen
poll' UGen
t UGen
i UGen
l UGen
tr =
    let t' :: UGen
t' = if UGen -> Bool
isConstant UGen
t then Rate -> UGen -> UGen -> UGen
impulse Rate
KR UGen
t UGen
0 else UGen
t
    in [UGen] -> UGen
mrg [UGen
i,UGen -> UGen -> UGen -> UGen -> UGen
poll UGen
t' UGen
i UGen
l UGen
tr]

-- | Variant of 'in'' offset so zero if the first private bus.
privateIn :: Int -> Rate -> UGen -> UGen
privateIn :: Int -> Rate -> UGen -> UGen
privateIn Int
nc Rate
rt UGen
k = Int -> Rate -> UGen -> UGen
in' Int
nc Rate
rt (UGen
k UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
firstPrivateBus)

-- | Variant of 'out' offset so zero if the first private bus.
privateOut :: UGen -> UGen -> UGen
privateOut :: UGen -> UGen -> UGen
privateOut UGen
k = UGen -> UGen -> UGen
out (UGen
k UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
firstPrivateBus)

-- | Apply function /f/ to each bin of an @FFT@ chain, /f/ receives
-- magnitude, phase and index and returns a (magnitude,phase).
pvcollect :: UGen -> Int -> (UGen -> UGen -> Int -> (UGen, UGen)) -> Int -> Int -> UGen -> UGen
pvcollect :: UGen
-> Int
-> (UGen -> UGen -> Int -> (UGen, UGen))
-> Int
-> Int
-> UGen
-> UGen
pvcollect UGen
c Int
nf UGen -> UGen -> Int -> (UGen, UGen)
f Int
from Int
to UGen
z =
    let m :: [UGen]
m = UGen -> Int -> Int -> Int -> UGen -> [UGen]
unpackFFT UGen
c Int
nf Int
from Int
to UGen
0
        p :: [UGen]
p = UGen -> Int -> Int -> Int -> UGen -> [UGen]
unpackFFT UGen
c Int
nf Int
from Int
to UGen
1
        i :: [Int]
i = [Int
from .. Int
to]
        e :: [(UGen, UGen)]
e = (UGen -> UGen -> Int -> (UGen, UGen))
-> [UGen] -> [UGen] -> [Int] -> [(UGen, UGen)]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 UGen -> UGen -> Int -> (UGen, UGen)
f [UGen]
m [UGen]
p [Int]
i
        mp :: UGen
mp = ([UGen] -> [UGen] -> UGen) -> ([UGen], [UGen]) -> UGen
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [UGen] -> [UGen] -> UGen
packFFTSpec ([(UGen, UGen)] -> ([UGen], [UGen])
forall a b. [(a, b)] -> ([a], [b])
unzip [(UGen, UGen)]
e)
    in UGen -> Int -> Int -> Int -> UGen -> UGen -> UGen
packFFT UGen
c Int
nf Int
from Int
to UGen
z UGen
mp

-- | /dur/ and /hop/ are in seconds, /frameSize/ and /sampleRate/ in
-- frames, though the latter maybe fractional.
--
-- > pv_calcPVRecSize 4.2832879818594 1024 0.25 48000.0 == 823299
pv_calcPVRecSize :: Double -> Int -> Double -> Double -> Int
pv_calcPVRecSize :: Double -> Int -> Double -> Double -> Int
pv_calcPVRecSize Double
dur Int
frame_size Double
hop Double
sample_rate =
    let frame_size' :: Double
frame_size' = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
frame_size
        raw_size :: Int
raw_size = Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
ceiling ((Double
dur Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
sample_rate) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
frame_size') Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
frame_size
    in Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
raw_size Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Fractional a => a -> a
recip Double
hop Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
3)

-- | 'rand' with left edge set to zero.
rand0 :: ID a => a -> UGen -> UGen
rand0 :: a -> UGen -> UGen
rand0 a
z = a -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen
rand a
z UGen
0

-- | 'UId' form of 'rand0'.
rand0M :: UId m => UGen -> m UGen
rand0M :: UGen -> m UGen
rand0M = UGen -> UGen -> m UGen
forall (m :: * -> *). UId m => UGen -> UGen -> m UGen
randM UGen
0

-- | 'rand' with left edge set to negative /n/.
rand2 :: ID a => a -> UGen -> UGen
rand2 :: a -> UGen -> UGen
rand2 a
z UGen
n = a -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen
rand a
z (UGen -> UGen
forall a. Num a => a -> a
negate UGen
n) UGen
n

-- | 'UId' form of 'rand2'.
rand2M :: UId m => UGen -> m UGen
rand2M :: UGen -> m UGen
rand2M UGen
n = UGen -> UGen -> m UGen
forall (m :: * -> *). UId m => UGen -> UGen -> m UGen
randM (UGen -> UGen
forall a. Num a => a -> a
negate UGen
n) UGen
n

-- | rotate2 with MCE input.
rotateStereo :: UGen -> UGen -> UGen
rotateStereo :: UGen -> UGen -> UGen
rotateStereo UGen
sig UGen
pos = let (UGen
x,UGen
y) = UGen -> (UGen, UGen)
unmce2 UGen
sig in UGen -> UGen -> UGen -> UGen
rotate2 UGen
x UGen
y UGen
pos

-- | RMS variant of 'runningSum'.
runningSumRMS :: UGen -> UGen -> UGen
runningSumRMS :: UGen -> UGen -> UGen
runningSumRMS UGen
z UGen
n = UGen -> UGen
forall a. Floating a => a -> a
sqrt (UGen -> UGen -> UGen
runningSum (UGen
z UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
z) UGen
n UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen -> UGen
forall a. Fractional a => a -> a
recip UGen
n)

-- | Mix one output from many sources
selectX :: UGen -> UGen -> UGen
selectX :: UGen -> UGen -> UGen
selectX UGen
ix UGen
xs =
    let s0 :: UGen
s0 = UGen -> UGen -> UGen
select (UGen -> UGen -> UGen
roundTo UGen
ix UGen
2) UGen
xs
        s1 :: UGen
s1 = UGen -> UGen -> UGen
select (UGen -> UGen -> UGen
forall a. BinaryOp a => a -> a -> a
trunc UGen
ix UGen
2 UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
1) UGen
xs
    in UGen -> UGen -> UGen -> UGen -> UGen
xFade2 UGen
s0 UGen
s1 (UGen -> UGen -> UGen
forall a. BinaryOp a => a -> a -> a
fold2 (UGen
ix UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
2 UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
- UGen
1) UGen
1) UGen
1

-- | Set local buffer values.
setBuf' :: UGen -> [UGen] -> UGen -> UGen
setBuf' :: UGen -> [UGen] -> UGen -> UGen
setBuf' UGen
b [UGen]
xs UGen
o = UGen -> UGen -> UGen -> UGen -> UGen
setBuf UGen
b UGen
o (Int -> UGen
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([UGen] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [UGen]
xs)) ([UGen] -> UGen
mce [UGen]
xs)

-- | Silence.
silent :: Int -> UGen
silent :: Int -> UGen
silent Int
n = let s :: UGen
s = Rate -> UGen -> UGen
dc Rate
AR UGen
0 in [UGen] -> UGen
mce (Int -> UGen -> [UGen]
forall a. Int -> a -> [a]
replicate Int
n UGen
s)

{- | Zero indexed audio input buses.
     Optimises case of consecutive UGens.

> soundIn (mce2 0 1) == in' 2 AR numOutputBuses
> soundIn (mce2 0 2) == in' 1 AR (numOutputBuses + mce2 0 2)

-}
soundIn :: UGen -> UGen
soundIn :: UGen -> UGen
soundIn UGen
u =
    let r :: UGen
r = Int -> Rate -> UGen -> UGen
in' Int
1 Rate
AR (UGen
numOutputBuses UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
u)
    in case UGen
u of
         MCE_U MCE UGen
m ->
             let n :: [UGen]
n = MCE UGen -> [UGen]
mceProxies MCE UGen
m
             in if (UGen -> Bool) -> [UGen] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (UGen -> UGen -> Bool
forall a. Eq a => a -> a -> Bool
==UGen
1) ((UGen -> UGen -> UGen) -> [UGen] -> [UGen] -> [UGen]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (-) ([UGen] -> [UGen]
forall a. [a] -> [a]
tail [UGen]
n) [UGen]
n)
                then Int -> Rate -> UGen -> UGen
in' ([UGen] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [UGen]
n) Rate
AR (UGen
numOutputBuses UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ [UGen] -> UGen
forall a. [a] -> a
head [UGen]
n)
                else UGen
r
         UGen
_ -> UGen
r

-- | Pan a set of channels across the stereo field.
--
-- > input, spread:1, level:1, center:0, levelComp:true
splay :: UGen -> UGen -> UGen -> UGen -> Bool -> UGen
splay :: UGen -> UGen -> UGen -> UGen -> Bool -> UGen
splay UGen
i UGen
s UGen
l UGen
c Bool
lc =
    let n :: UGen
n = UGen -> UGen -> UGen
forall a. Ord a => a -> a -> a
max UGen
2 (Int -> UGen
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
1 (UGen -> Maybe Int
mceDegree UGen
i)))
        m :: UGen
m = UGen
n UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
- UGen
1
        p :: [UGen]
p = (UGen -> UGen) -> [UGen] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map ((UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ (-UGen
1.0)) (UGen -> UGen) -> (UGen -> UGen) -> UGen -> UGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* (UGen
2 UGen -> UGen -> UGen
forall a. Fractional a => a -> a -> a
/ UGen
m))) [UGen
0 .. UGen
m]
        a :: UGen
a = if Bool
lc then UGen -> UGen
forall a. Floating a => a -> a
sqrt (UGen
1 UGen -> UGen -> UGen
forall a. Fractional a => a -> a -> a
/ UGen
n) else UGen
1
    in UGen -> UGen
mix (UGen -> UGen -> UGen -> UGen
pan2 UGen
i (UGen
s UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* [UGen] -> UGen
mce [UGen]
p UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
c) UGen
1) UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
l UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
a

-- | Optimised UGen sum function.
sum_opt :: [UGen] -> UGen
sum_opt :: [UGen] -> UGen
sum_opt = (UGen -> UGen -> UGen -> UGen)
-> (UGen -> UGen -> UGen -> UGen -> UGen) -> [UGen] -> UGen
forall t.
Num t =>
(t -> t -> t -> t) -> (t -> t -> t -> t -> t) -> [t] -> t
sum_opt_f UGen -> UGen -> UGen -> UGen
sum3 UGen -> UGen -> UGen -> UGen -> UGen
sum4

-- | Single tap into a delayline.  AR only.
tap :: Int -> Rate -> UGen -> UGen -> UGen
tap :: Int -> Rate -> UGen -> UGen -> UGen
tap Int
numChannels Rate
rt UGen
bufnum UGen
delaytime =
    let n :: UGen
n = UGen
delaytime UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen -> UGen
forall a. Num a => a -> a
negate UGen
sampleRate
    in Int
-> Rate
-> UGen
-> UGen
-> UGen
-> UGen
-> Loop UGen
-> DoneAction UGen
-> UGen
playBuf Int
numChannels Rate
rt UGen
bufnum UGen
1 UGen
0 UGen
n Loop UGen
forall t. Loop t
Loop DoneAction UGen
forall t. DoneAction t
DoNothing

-- | Randomly select one of several inputs on trigger.
tChoose :: ID m => m -> UGen -> UGen -> UGen
tChoose :: m -> UGen -> UGen -> UGen
tChoose m
z UGen
t UGen
a = UGen -> UGen -> UGen
select (m -> UGen -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen -> UGen
tiRand m
z UGen
0 (UGen -> UGen
mceN UGen
a UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
- UGen
1) UGen
t) UGen
a

-- | Randomly select one of several inputs.
tChooseM :: (UId m) => UGen -> UGen -> m UGen
tChooseM :: UGen -> UGen -> m UGen
tChooseM UGen
t UGen
a = do
  UGen
r <- UGen -> UGen -> UGen -> m UGen
forall (m :: * -> *). UId m => UGen -> UGen -> UGen -> m UGen
tiRandM UGen
0 (Int -> UGen
forall n. Real n => n -> UGen
constant ([UGen] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (UGen -> [UGen]
mceChannels UGen
a) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) UGen
t
  UGen -> m UGen
forall (m :: * -> *) a. Monad m => a -> m a
return (UGen -> UGen -> UGen
select UGen
r UGen
a)

-- | Triggered Line, implemented in terms of EnvGen.
tLine :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
tLine :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
tLine Rate
rt UGen
start UGen
end UGen
dur UGen
trig_ =
  let p :: Envelope UGen
p = [(UGen, UGen)]
-> UGen -> UGen -> Envelope_Curve UGen -> Envelope UGen
forall n.
Num n =>
[(n, n)] -> n -> n -> Envelope_Curve n -> Envelope n
envCoord [(UGen
0,UGen
0),(UGen
0,UGen
start),(UGen
dur,UGen
end)] UGen
1 UGen
1 Envelope_Curve UGen
forall a. Envelope_Curve a
EnvLin
  in Rate
-> UGen
-> UGen
-> UGen
-> UGen
-> DoneAction UGen
-> Envelope UGen
-> UGen
envGen Rate
rt UGen
trig_ UGen
1 UGen
0 UGen
1 DoneAction UGen
forall t. DoneAction t
DoNothing Envelope UGen
p

-- | Triggered xLine, implemented in terms of EnvGen.
tXLine :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
tXLine :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
tXLine Rate
rt UGen
start UGen
end UGen
dur UGen
trig_ =
  let p :: Envelope UGen
p = [(UGen, UGen)]
-> UGen -> UGen -> Envelope_Curve UGen -> Envelope UGen
forall n.
Num n =>
[(n, n)] -> n -> n -> Envelope_Curve n -> Envelope n
envCoord [(UGen
0,UGen
0),(UGen
0,UGen
start),(UGen
dur,UGen
end)] UGen
1 UGen
1 Envelope_Curve UGen
forall a. Envelope_Curve a
EnvExp
  in Rate
-> UGen
-> UGen
-> UGen
-> UGen
-> DoneAction UGen
-> Envelope UGen
-> UGen
envGen Rate
rt UGen
trig_ UGen
1 UGen
0 UGen
1 DoneAction UGen
forall t. DoneAction t
DoNothing Envelope UGen
p

-- | Triangle wave as sum of /n/ sines.
-- For partial n, amplitude is (1 / square n) and phase is pi at every other odd partial.
triAS :: Int -> UGen -> UGen
triAS :: Int -> UGen -> UGen
triAS Int
n UGen
f0 =
    let mk_freq :: a -> UGen
mk_freq a
i = UGen
f0 UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* a -> UGen
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i
        mk_amp :: a -> p
mk_amp a
i = if a -> Bool
forall a. Integral a => a -> Bool
even a
i then p
0 else p
1 p -> p -> p
forall a. Fractional a => a -> a -> a
/ a -> p
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
i a -> a -> a
forall a. Num a => a -> a -> a
* a
i)
        mk_ph :: a -> p
mk_ph a
i = if a
i a -> a -> a
forall a. Num a => a -> a -> a
+ a
1 a -> a -> a
forall a. Integral a => a -> a -> a
`mod` a
4 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 then p
forall a. Floating a => a
pi else p
0
        m :: [Int]
m = [Int
1,Int
3 .. Int
n]
        param :: [(UGen, UGen, UGen)]
param = [UGen] -> [UGen] -> [UGen] -> [(UGen, UGen, UGen)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 ((Int -> UGen) -> [Int] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map Int -> UGen
forall a. Integral a => a -> UGen
mk_freq [Int]
m) ((Int -> UGen) -> [Int] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map Int -> UGen
forall a p. (Integral a, Floating p) => a -> p
mk_ph [Int]
m) ((Int -> UGen) -> [Int] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map Int -> UGen
forall a p. (Integral a, Fractional p) => a -> p
mk_amp [Int]
m)
    in [UGen] -> UGen
sum_opt (((UGen, UGen, UGen) -> UGen) -> [(UGen, UGen, UGen)] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map (\(UGen
fr,UGen
ph,UGen
am) -> Rate -> UGen -> UGen -> UGen
sinOsc Rate
AR UGen
fr UGen
ph UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
am) [(UGen, UGen, UGen)]
param)

-- | Randomly select one of several inputs on trigger (weighted).
tWChoose :: ID m => m -> UGen -> UGen -> UGen -> UGen -> UGen
tWChoose :: m -> UGen -> UGen -> UGen -> UGen -> UGen
tWChoose m
z UGen
t UGen
a UGen
w UGen
n =
    let i :: UGen
i = m -> UGen -> UGen -> UGen -> UGen
forall a. ID a => a -> UGen -> UGen -> UGen -> UGen
tWindex m
z UGen
t UGen
n UGen
w
    in UGen -> UGen -> UGen
select UGen
i UGen
a

-- | Randomly select one of several inputs (weighted).
tWChooseM :: (UId m) => UGen -> UGen -> UGen -> UGen -> m UGen
tWChooseM :: UGen -> UGen -> UGen -> UGen -> m UGen
tWChooseM UGen
t UGen
a UGen
w UGen
n = do
  UGen
i <- UGen -> UGen -> UGen -> m UGen
forall (m :: * -> *). UId m => UGen -> UGen -> UGen -> m UGen
tWindexM UGen
t UGen
n UGen
w
  UGen -> m UGen
forall (m :: * -> *) a. Monad m => a -> m a
return (UGen -> UGen -> UGen
select UGen
i UGen
a)

-- | Unpack an FFT chain into separate demand-rate FFT bin streams.
unpackFFT :: UGen -> Int -> Int -> Int -> UGen -> [UGen]
unpackFFT :: UGen -> Int -> Int -> Int -> UGen -> [UGen]
unpackFFT UGen
c Int
nf Int
from Int
to UGen
w = (Int -> UGen) -> [Int] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map (\Int
i -> UGen -> UGen -> UGen -> UGen -> UGen
unpack1FFT UGen
c (Int -> UGen
forall n. Real n => n -> UGen
constant Int
nf) (Int -> UGen
forall n. Real n => n -> UGen
constant Int
i) UGen
w) [Int
from .. Int
to]

-- | VarLag in terms of envGen.  Note: in SC3 curvature and warp are separate arguments.
varLag_env :: UGen -> UGen -> Envelope_Curve UGen -> Maybe UGen -> UGen
varLag_env :: UGen -> UGen -> Envelope_Curve UGen -> Maybe UGen -> UGen
varLag_env UGen
in_ UGen
time Envelope_Curve UGen
warp Maybe UGen
start =
  let rt :: Rate
rt = UGen -> Rate
rateOf UGen
in_
      start_ :: UGen
start_ = UGen -> Maybe UGen -> UGen
forall a. a -> Maybe a -> a
fromMaybe UGen
in_ Maybe UGen
start
      e :: Envelope UGen
e = [UGen]
-> [UGen]
-> [Envelope_Curve UGen]
-> Maybe Int
-> Maybe Int
-> UGen
-> Envelope UGen
forall a.
[a]
-> [a]
-> [Envelope_Curve a]
-> Maybe Int
-> Maybe Int
-> a
-> Envelope a
Envelope [UGen
start_,UGen
in_] [UGen
time] [Envelope_Curve UGen
warp] Maybe Int
forall a. Maybe a
Nothing Maybe Int
forall a. Maybe a
Nothing UGen
0
      -- e[6] = curve; e[7] = curvature;
      time_ch :: UGen
time_ch = if UGen -> Rate
rateOf UGen
time Rate -> Rate -> Bool
forall a. Eq a => a -> a -> Bool
== Rate
IR then UGen
0 else UGen -> UGen -> UGen
changed UGen
time UGen
0
      tr :: UGen
tr = UGen -> UGen -> UGen
changed UGen
in_ UGen
0 UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
time_ch UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ Rate -> UGen -> UGen -> UGen
impulse Rate
rt UGen
0 UGen
0
  in Rate
-> UGen
-> UGen
-> UGen
-> UGen
-> DoneAction UGen
-> Envelope UGen
-> UGen
envGen Rate
rt UGen
tr UGen
1 UGen
0 UGen
1 DoneAction UGen
forall t. DoneAction t
DoNothing Envelope UGen
e

{- | If @z@ isn't a sink node route to an @out@ node writing to @bus@.
     If @fadeTime@ is given multiply by 'makeFadeEnv'.

> import Sound.SC3 {- hsc3 -}
> audition (wrapOut (Just 1) (sinOsc AR 440 0 * 0.1))
> import Sound.OSC {- hosc -}
> withSC3 (sendMessage (n_set1 (-1) "gate" 0))
-}
wrapOut :: Maybe Double -> UGen -> UGen
wrapOut :: Maybe Double -> UGen -> UGen
wrapOut Maybe Double
fadeTime UGen
z =
  if UGen -> Bool
isSink UGen
z
  then UGen
z
  else UGen -> UGen -> UGen
out (Rate -> String -> Double -> UGen
control Rate
KR String
"out" Double
0) (UGen -> (Double -> UGen) -> Maybe Double -> UGen
forall b a. b -> (a -> b) -> Maybe a -> b
maybe UGen
z ((UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen
z) (UGen -> UGen) -> (Double -> UGen) -> Double -> UGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> UGen
makeFadeEnv) Maybe Double
fadeTime)

-- * wslib

-- | Cross-fading version of 'playBuf'.
playBufCF :: Int -> UGen -> UGen -> UGen -> UGen -> Loop UGen -> UGen -> Int -> UGen
playBufCF :: Int
-> UGen -> UGen -> UGen -> UGen -> Loop UGen -> UGen -> Int -> UGen
playBufCF Int
nc UGen
bufnum UGen
rate UGen
trigger UGen
startPos Loop UGen
loop UGen
lag' Int
n =
    let trigger' :: UGen
trigger' = if UGen -> Rate
rateOf UGen
trigger Rate -> Rate -> Bool
forall a. Eq a => a -> a -> Bool
== Rate
DR
                   then Rate -> UGen -> UGen -> DoneAction UGen -> UGen -> UGen -> UGen
tDuty Rate
AR UGen
trigger UGen
0 DoneAction UGen
forall t. DoneAction t
DoNothing UGen
1 UGen
0
                   else UGen
trigger
        index' :: UGen
index' = UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
stepper UGen
trigger' UGen
0 UGen
0 (Int -> UGen
forall n. Real n => n -> UGen
constant Int
n UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
- UGen
1) UGen
1 UGen
0
        on :: [UGen]
on = (UGen -> UGen) -> [UGen] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map
             (\UGen
i -> UGen -> UGen -> UGen -> UGen
inRange UGen
index' (UGen
i UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
- UGen
0.5) (UGen
i UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
+ UGen
0.5))
             [UGen
0 .. Int -> UGen
forall n. Real n => n -> UGen
constant Int
n UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
- UGen
1]
        rate' :: [UGen]
rate' = case UGen -> Rate
rateOf UGen
rate of
                  Rate
DR -> (UGen -> UGen) -> [UGen] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map (\UGen
on' -> UGen -> UGen -> UGen -> UGen
demand UGen
on' UGen
0 UGen
rate) [UGen]
on
                  Rate
KR -> (UGen -> UGen) -> [UGen] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map (UGen -> UGen -> UGen
gate UGen
rate) [UGen]
on
                  Rate
AR -> (UGen -> UGen) -> [UGen] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map (UGen -> UGen -> UGen
gate UGen
rate) [UGen]
on
                  Rate
IR -> (UGen -> UGen) -> [UGen] -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map (UGen -> UGen -> UGen
forall a b. a -> b -> a
const UGen
rate) [UGen]
on
        startPos' :: UGen
startPos' = if UGen -> Rate
rateOf UGen
startPos Rate -> Rate -> Bool
forall a. Eq a => a -> a -> Bool
== Rate
DR
                    then UGen -> UGen -> UGen -> UGen
demand UGen
trigger' UGen
0 UGen
startPos
                    else UGen
startPos
        lag'' :: UGen
lag'' = UGen
1 UGen -> UGen -> UGen
forall a. Fractional a => a -> a -> a
/ UGen
lag'
        s :: [UGen]
s = (UGen -> UGen -> UGen) -> [UGen] -> [UGen] -> [UGen]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
            (\UGen
on' UGen
r -> let p :: UGen
p = Int
-> Rate
-> UGen
-> UGen
-> UGen
-> UGen
-> Loop UGen
-> DoneAction UGen
-> UGen
playBuf Int
nc Rate
AR UGen
bufnum UGen
r UGen
on' UGen
startPos' Loop UGen
loop DoneAction UGen
forall t. DoneAction t
DoNothing
                       in UGen
p UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
* UGen -> UGen
forall a. Floating a => a -> a
sqrt (UGen -> UGen -> UGen -> UGen
slew UGen
on' UGen
lag'' UGen
lag''))
            [UGen]
on [UGen]
rate'
    in [UGen] -> UGen
sum_opt [UGen]
s

-- * adc

-- | An oscillator that reads through a table once.
osc1 :: Rate -> UGen -> UGen -> DoneAction UGen -> UGen
osc1 :: Rate -> UGen -> UGen -> DoneAction UGen -> UGen
osc1 Rate
rt UGen
buf UGen
dur DoneAction UGen
doneAction =
    let ph :: UGen
ph = Rate -> UGen -> UGen -> UGen -> DoneAction UGen -> UGen
line Rate
rt UGen
0 (Rate -> UGen -> UGen
bufFrames Rate
IR UGen
buf UGen -> UGen -> UGen
forall a. Num a => a -> a -> a
- UGen
1) UGen
dur DoneAction UGen
doneAction
    in Int
-> Rate -> UGen -> UGen -> Loop UGen -> Interpolation UGen -> UGen
bufRd Int
1 Rate
rt UGen
buf UGen
ph Loop UGen
forall t. Loop t
NoLoop Interpolation UGen
forall t. Interpolation t
LinearInterpolation