-- | Common unit generator graphs.
module Sound.Sc3.Ugen.Bindings.Composite where

import Data.List {- base -}
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.Common.Unsafe

import Sound.Sc3.Ugen.Bindings.Db
import Sound.Sc3.Ugen.Bindings.Hw
import Sound.Sc3.Ugen.Math
import Sound.Sc3.Ugen.Mce
import Sound.Sc3.Ugen.Types
import Sound.Sc3.Ugen.Util

-- | Generate a localBuf and use setBuf to initialise it.
asLocalBufId :: ID i => i -> [Ugen] -> Ugen
asLocalBufId :: forall i. ID i => i -> [Ugen] -> Ugen
asLocalBufId i
z [Ugen]
xs =
    let b :: Ugen
b = forall a. ID a => a -> Ugen -> Ugen -> Ugen
localBufId i
z Ugen
1 (forall a b. (Integral a, Num b) => a -> b
fromIntegral (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

asLocalBufM :: Uid m => [Ugen] -> m Ugen
asLocalBufM :: forall (m :: * -> *). Uid m => [Ugen] -> m Ugen
asLocalBufM = forall (m :: * -> *) a b. Uid m => (Int -> Fn1 a b) -> Fn1 a (m b)
liftUid1 forall i. ID i => i -> [Ugen] -> Ugen
asLocalBufId

asLocalBuf :: [Ugen] -> Ugen
asLocalBuf :: [Ugen] -> Ugen
asLocalBuf = forall a r. (a -> IO r) -> a -> r
liftUnsafe1 forall (m :: * -> *). Uid m => [Ugen] -> m Ugen
asLocalBufM

-- | 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) = 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) = 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 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 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 forall t. Interpolation t
CubicInterpolation

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

-- | 'mce' variant of 'lchoose'.
chooseId :: ID m => m -> Ugen -> Ugen
chooseId :: forall m. ID m => m -> Ugen -> Ugen
chooseId m
z = forall i. ID i => i -> [Ugen] -> Ugen
lchooseId m
z forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ugen -> [Ugen]
mceChannels

-- | 'liftUid' of 'choose'.
chooseM :: Uid m => Ugen -> m Ugen
chooseM :: forall (m :: * -> *). Uid m => Ugen -> m Ugen
chooseM = forall (m :: * -> *) a b. Uid m => (Int -> Fn1 a b) -> Fn1 a (m b)
liftUid1 forall m. ID m => m -> Ugen -> Ugen
chooseId

choose :: Ugen -> Ugen
choose :: Ugen -> Ugen
choose = forall a r. (a -> IO r) -> a -> r
liftUnsafe1 forall (m :: * -> *). Uid m => Ugen -> m Ugen
chooseM

-- | 'clearBuf' of 'localBuf'.
clearLocalBufId :: ID a => a -> Ugen -> Ugen -> Ugen
clearLocalBufId :: forall a. ID a => a -> Ugen -> Ugen -> Ugen
clearLocalBufId a
z Ugen
nc Ugen
nf = Ugen -> Ugen
clearBuf (forall a. ID a => a -> Ugen -> Ugen -> Ugen
localBufId a
z Ugen
nc Ugen
nf)

clearLocalBufM :: Uid m => Ugen -> Ugen -> m Ugen
clearLocalBufM :: forall (m :: * -> *). Uid m => Ugen -> Ugen -> m Ugen
clearLocalBufM = forall (m :: * -> *) a b c.
Uid m =>
(Int -> Fn2 a b c) -> Fn2 a b (m c)
liftUid2 forall a. ID a => a -> Ugen -> Ugen -> Ugen
clearLocalBufId

clearLocalBuf :: Ugen -> Ugen -> Ugen
clearLocalBuf :: Ugen -> Ugen -> Ugen
clearLocalBuf = forall a b r. (a -> b -> IO r) -> a -> b -> r
liftUnsafe2 forall (m :: * -> *). Uid m => Ugen -> Ugen -> m Ugen
clearLocalBufM

-- | Demand rate (:) function.
dconsId :: ID m => (m,m,m) -> Ugen -> Ugen -> Ugen
dconsId :: forall m. ID m => (m, m, m) -> Ugen -> Ugen -> Ugen
dconsId (m
z0,m
z1,m
z2) Ugen
x Ugen
xs =
    let i :: Ugen
i = forall a. ID a => a -> Ugen -> Ugen -> Ugen
dseqId m
z0 Ugen
1 (Ugen -> Ugen -> Ugen
mce2 Ugen
0 Ugen
1)
        a :: Ugen
a = forall a. ID a => a -> Ugen -> Ugen -> Ugen
dseqId m
z1 Ugen
1 (Ugen -> Ugen -> Ugen
mce2 Ugen
x Ugen
xs)
    in forall a. ID a => a -> Ugen -> Ugen -> Ugen
dswitchId m
z2 Ugen
i Ugen
a

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

dcons :: Ugen -> Ugen -> Ugen
dcons :: Ugen -> Ugen -> Ugen
dcons = forall a b r. (a -> b -> IO r) -> a -> b -> r
liftUnsafe2 forall (m :: * -> *). Uid m => Ugen -> Ugen -> m Ugen
dconsM

-- | 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 forall a. Num a => a -> a -> a
* Ugen
fs forall a. Num a => a -> a -> a
+ Ugen
fo) Ugen
ph forall a. Num a => a -> a -> a
* Ugen
a 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 forall a. Num a => a -> a -> a
* Ugen
fs forall a. Num a => a -> a -> a
+ Ugen
fo) (Ugen
d forall a. Num a => a -> a -> a
* Ugen
ds) forall a. Num a => a -> a -> a
* Ugen
a 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))
fftAllocId :: ID i => i -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen
fftAllocId :: forall i.
ID i =>
i -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen
fftAllocId i
z Ugen
nf Ugen
i Ugen
h Ugen
wt Ugen
a Ugen
ws =
    let b :: Ugen
b = forall a. ID a => a -> Ugen -> Ugen -> Ugen
localBufId 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

fftAllocM :: Uid m => Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> m Ugen
fftAllocM :: forall (m :: * -> *).
Uid m =>
Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> m Ugen
fftAllocM = forall (m :: * -> *) a b c d e f g.
Uid m =>
(Int -> Fn6 a b c d e f g) -> Fn6 a b c d e f (m g)
liftUid6 forall i.
ID i =>
i -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen
fftAllocId

fftAlloc :: Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen
fftAlloc :: Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen
fftAlloc = forall a b c d e f r.
(a -> b -> c -> d -> e -> f -> IO r)
-> a -> b -> c -> d -> e -> f -> r
liftUnsafe6 forall (m :: * -> *).
Uid m =>
Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> m Ugen
fftAllocM

-- | Sum of 'numInputBuses' and 'numOutputBuses'.
firstPrivateBus :: Ugen
firstPrivateBus :: Ugen
firstPrivateBus = Ugen
numInputBuses 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 forall a. Num a => a -> a -> a
+ Ugen
0.5 forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi, Ugen
p])
        h :: Ugen
h = Ugen -> Ugen
hilbert Ugen
i
    in Ugen -> Ugen
mix (Ugen
h 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 :: forall a. Num a => a -> a -> a
gateReset a
gt a
tr = a
gt forall a. Num a => a -> a -> a
- (a
gt forall a. Num a => a -> a -> a
* a
tr 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 :: forall a b c. (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 ((forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall a b c. (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f 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 :: forall n. Real n => [n] -> [n] -> [n] -> Ugen
klangSpec_k = forall a b c. (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f (forall a b. (a -> b) -> [a] -> [b]
map 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 = 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 = forall a b c. (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f forall a. a -> a
id [Ugen] -> Ugen
mce

-- | Variant for non-Ugen inputs.
klankSpec_k :: Real n => [n] -> [n] -> [n] -> Ugen
klankSpec_k :: forall n. Real n => [n] -> [n] -> [n] -> Ugen
klankSpec_k = forall a b c. (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
klanx_spec_f (forall a b. (a -> b) -> [a] -> [b]
map 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 = 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).
lchooseId :: ID m => m -> [Ugen] -> Ugen
lchooseId :: forall i. ID i => i -> [Ugen] -> Ugen
lchooseId m
z [Ugen]
a = Ugen -> Ugen -> Ugen
select (forall a. ID a => a -> Ugen -> Ugen -> Ugen
iRandId m
z Ugen
0 (forall a b. (Integral a, Num b) => a -> b
fromIntegral (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 :: forall (m :: * -> *). Uid m => [Ugen] -> m Ugen
lchooseM = forall (m :: * -> *) a b. Uid m => (Int -> Fn1 a b) -> Fn1 a (m b)
liftUid1 forall i. ID i => i -> [Ugen] -> Ugen
lchooseId

lchoose :: [Ugen] -> Ugen
lchoose :: [Ugen] -> Ugen
lchoose = forall a r. (a -> IO r) -> a -> r
liftUnsafe1 forall (m :: * -> *). Uid m => [Ugen] -> m Ugen
lchooseM

-- | '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 = 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 (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" (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 forall a. OrdE a => a -> a -> a
`less_than_or_equal_to` Ugen
0
        env :: Envelope Ugen
env = 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] [forall a. Envelope_Curve a
EnvLin,forall a. Envelope_Curve a
EnvLin] (forall a. a -> Maybe a
Just Int
1) 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 forall t. DoneAction t
RemoveSynth Envelope Ugen
env

-- | Variant that is randomly pressed.
mouseButtonRand :: Rate -> Ugen -> Ugen -> Ugen -> Ugen
mouseButtonRand :: Rate -> Ugen -> Ugen -> Ugen -> Ugen
mouseButtonRand Rate
rt Ugen
l Ugen
r Ugen
tm =
    let o :: Ugen
o = forall a. ID a => a -> Rate -> Ugen -> Ugen
lfClipNoiseId 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'').
mouseRandId :: ID a => a -> Rate -> Ugen -> Ugen -> Warp Ugen -> Ugen -> Ugen
mouseRandId :: forall a.
ID a =>
a -> Rate -> Ugen -> Ugen -> Warp Ugen -> Ugen -> Ugen
mouseRandId 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
_ -> forall a. HasCallStack => a
undefined
  in Ugen -> Ugen -> Ugen
lag (Ugen -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen
f (forall a. ID a => a -> Rate -> Ugen -> Ugen
lfNoise1Id a
z Rate
rt Ugen
1) (-Ugen
1) Ugen
1 Ugen
l Ugen
r) Ugen
tm

mouseRandM :: Uid m => Rate -> Ugen -> Ugen -> Warp Ugen -> Ugen -> m Ugen
mouseRandM :: forall (m :: * -> *).
Uid m =>
Rate -> Ugen -> Ugen -> Warp Ugen -> Ugen -> m Ugen
mouseRandM = forall (m :: * -> *) a b c d e f.
Uid m =>
(Int -> Fn5 a b c d e f) -> Fn5 a b c d e (m f)
liftUid5 forall a.
ID a =>
a -> Rate -> Ugen -> Ugen -> Warp Ugen -> Ugen -> Ugen
mouseRandId

mouseRand :: Rate -> Ugen -> Ugen -> Warp Ugen -> Ugen -> Ugen
mouseRand :: Rate -> Ugen -> Ugen -> Warp Ugen -> Ugen -> Ugen
mouseRand = forall a b c d e r.
(a -> b -> c -> d -> e -> IO r) -> a -> b -> c -> d -> e -> r
liftUnsafe5 forall (m :: * -> *).
Uid m =>
Rate -> Ugen -> Ugen -> Warp Ugen -> Ugen -> m Ugen
mouseRandM

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

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

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

-- | Onset detector with default values for minor parameters.
onsetsDefault :: Ugen -> Ugen -> Ugen -> Ugen
onsetsDefault :: Ugen -> Ugen -> Ugen -> Ugen
onsetsDefault 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 = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 (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 forall a. Integral a => a -> a -> a
`div` Int
2
        num_partitions :: Int
num_partitions = (Int
ir_length forall a. Integral a => a -> a -> a
`div` Int
partition_size) forall a. Num a => a -> a -> a
+ Int
1
    in Int
fft_size 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 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.
pollExt :: Ugen -> Ugen -> Ugen -> Ugen -> Ugen
pollExt :: Ugen -> Ugen -> Ugen -> Ugen -> Ugen
pollExt Ugen
optTrig Ugen
in_ Ugen
label_ Ugen
trigId =
    let tr :: Ugen
tr = if Ugen -> Bool
isConstant Ugen
optTrig then Rate -> Ugen -> Ugen -> Ugen
impulse Rate
kr Ugen
optTrig Ugen
0 else Ugen
optTrig
    in [Ugen] -> Ugen
mrg [Ugen
in_,Ugen -> Ugen -> Ugen -> Ugen -> Ugen
poll Ugen
tr Ugen
in_ Ugen
label_ Ugen
trigId]

-- | 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 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 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 = 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 = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [Ugen] -> [Ugen] -> Ugen
packFFTSpec (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' = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
frame_size
        raw_size :: Int
raw_size = forall a b. (RealFrac a, Integral b) => a -> b
ceiling ((Double
dur forall a. Num a => a -> a -> a
* Double
sample_rate) forall a. Fractional a => a -> a -> a
/ Double
frame_size') forall a. Num a => a -> a -> a
* Int
frame_size
    in forall a b. (RealFrac a, Integral b) => a -> b
ceiling (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
raw_size forall a. Num a => a -> a -> a
* forall a. Fractional a => a -> a
recip Double
hop forall a. Num a => a -> a -> a
+ Double
3)

-- | 'rand' with left edge set to zero.
rand0Id :: ID a => a -> Ugen -> Ugen
rand0Id :: forall m. ID m => m -> Ugen -> Ugen
rand0Id a
z = forall a. ID a => a -> Ugen -> Ugen -> Ugen
randId a
z Ugen
0

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

rand0 :: Ugen -> Ugen
rand0 :: Ugen -> Ugen
rand0 = forall a r. (a -> IO r) -> a -> r
liftUnsafe1 forall (m :: * -> *). Uid m => Ugen -> m Ugen
rand0M

{- | 'rand' with left edge set to negative /n/.
     Note rand2 is also a UnaryOp Ugen, however hsc3 does not store Ids for operators.
-}
rand2Id :: ID a => a -> Ugen -> Ugen
rand2Id :: forall m. ID m => m -> Ugen -> Ugen
rand2Id a
z Ugen
n = forall a. ID a => a -> Ugen -> Ugen -> Ugen
randId a
z (forall a. Num a => a -> a
negate Ugen
n) Ugen
n

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

rand2 :: Ugen -> Ugen
rand2 :: Ugen -> Ugen
rand2 = forall a r. (a -> IO r) -> a -> r
liftUnsafe1 forall (m :: * -> *). Uid m => Ugen -> m Ugen
rand2M

-- | 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 = forall a. Floating a => a -> a
sqrt (Ugen -> Ugen -> Ugen
runningSum (Ugen
z forall a. Num a => a -> a -> a
* Ugen
z) Ugen
n forall a. Num a => a -> a -> a
* 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 (forall a. BinaryOp a => a -> a -> a
trunc Ugen
ix Ugen
2 forall a. Num a => a -> a -> a
+ Ugen
1) Ugen
xs
    in Ugen -> Ugen -> Ugen -> Ugen -> Ugen
xFade2 Ugen
s0 Ugen
s1 (forall a. BinaryOp a => a -> a -> a
fold2 (Ugen
ix forall a. Num a => a -> a -> a
* Ugen
2 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
Sound.Sc3.Ugen.Bindings.Db.setBuf Ugen
b Ugen
o (forall a b. (Integral a, Num b) => a -> b
fromIntegral (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 (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 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 forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Eq a => a -> a -> Bool
==Ugen
1) (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (-) (forall a. [a] -> [a]
tail [Ugen]
n) [Ugen]
n)
                then Int -> Rate -> Ugen -> Ugen
in' (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ugen]
n) Rate
ar (Ugen
numOutputBuses forall a. Num a => a -> a -> a
+ 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 = forall a. Ord a => a -> a -> a
max Ugen
2 (forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. a -> Maybe a -> a
fromMaybe Int
1 (Ugen -> Maybe Int
mceDegree Ugen
i)))
        m :: Ugen
m = Ugen
n forall a. Num a => a -> a -> a
- Ugen
1
        p :: [Ugen]
p = forall a b. (a -> b) -> [a] -> [b]
map ((forall a. Num a => a -> a -> a
+ (-Ugen
1.0)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Num a => a -> a -> a
* (Ugen
2 forall a. Fractional a => a -> a -> a
/ Ugen
m))) [Ugen
0 .. Ugen
m]
        a :: Ugen
a = if Bool
lc then forall a. Floating a => a -> a
sqrt (Ugen
1 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 forall a. Num a => a -> a -> a
* [Ugen] -> Ugen
mce [Ugen]
p forall a. Num a => a -> a -> a
+ Ugen
c) Ugen
1) forall a. Num a => a -> a -> a
* Ugen
l forall a. Num a => a -> a -> a
* Ugen
a

-- | 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 forall a. Num a => a -> a -> a
* 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 forall t. Loop t
Loop forall t. DoneAction t
DoNothing

-- | Randomly select one of several inputs on trigger.
tChooseId :: ID m => m -> Ugen -> Ugen -> Ugen
tChooseId :: forall a. ID a => a -> Ugen -> Ugen -> Ugen
tChooseId m
z Ugen
t Ugen
a = Ugen -> Ugen -> Ugen
select (forall a. ID a => a -> Ugen -> Ugen -> Ugen -> Ugen
tiRandId m
z Ugen
0 (Ugen -> Ugen
mceSize Ugen
a 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 :: forall (m :: * -> *). Uid m => Ugen -> Ugen -> m Ugen
tChooseM Ugen
t Ugen
a = do
  Ugen
r <- forall (m :: * -> *). Uid m => Ugen -> Ugen -> Ugen -> m Ugen
tiRandM Ugen
0 (forall n. Real n => n -> Ugen
constant (forall (t :: * -> *) a. Foldable t => t a -> Int
length (Ugen -> [Ugen]
mceChannels Ugen
a) forall a. Num a => a -> a -> a
- Int
1)) Ugen
t
  forall (m :: * -> *) a. Monad m => a -> m a
return (Ugen -> Ugen -> Ugen
select Ugen
r Ugen
a)

tChoose :: Ugen -> Ugen -> Ugen
tChoose :: Ugen -> Ugen -> Ugen
tChoose = forall a b r. (a -> b -> IO r) -> a -> b -> r
liftUnsafe2 forall (m :: * -> *). Uid m => Ugen -> Ugen -> m Ugen
tChooseM

-- | 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 = 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 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 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 = 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 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 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 forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i
        mk_amp :: a -> a
mk_amp a
i = if forall a. Integral a => a -> Bool
even a
i then a
0 else a
1 forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
i forall a. Num a => a -> a -> a
* a
i)
        mk_ph :: a -> a
mk_ph a
i = if a
i forall a. Num a => a -> a -> a
+ a
1 forall a. Integral a => a -> a -> a
`mod` a
4 forall a. Eq a => a -> a -> Bool
== a
0 then forall a. Floating a => a
pi else a
0
        m :: [Int]
m = [Int
1,Int
3 .. Int
n]
        param :: [(Ugen, Ugen, Ugen)]
param = forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 (forall a b. (a -> b) -> [a] -> [b]
map forall {a}. Integral a => a -> Ugen
mk_freq [Int]
m) (forall a b. (a -> b) -> [a] -> [b]
map forall {a} {a}. (Integral a, Floating a) => a -> a
mk_ph [Int]
m) (forall a b. (a -> b) -> [a] -> [b]
map forall {a} {a}. (Integral a, Fractional a) => a -> a
mk_amp [Int]
m)
    in [Ugen] -> Ugen
sum_opt (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 forall a. Num a => a -> a -> a
* Ugen
am) [(Ugen, Ugen, Ugen)]
param)

-- | Randomly select one of several inputs on trigger (weighted).
tWChooseId :: ID m => m -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen
tWChooseId :: forall m. ID m => m -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen
tWChooseId m
z Ugen
t Ugen
a Ugen
w Ugen
n =
    let i :: Ugen
i = forall a. ID a => a -> Ugen -> Ugen -> Ugen -> Ugen
tWindexId 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 :: forall (m :: * -> *).
Uid m =>
Ugen -> Ugen -> Ugen -> Ugen -> m Ugen
tWChooseM Ugen
t Ugen
a Ugen
w Ugen
n = do
  Ugen
i <- forall (m :: * -> *). Uid m => Ugen -> Ugen -> Ugen -> m Ugen
tWindexM Ugen
t Ugen
n Ugen
w
  forall (m :: * -> *) a. Monad m => a -> m a
return (Ugen -> Ugen -> Ugen
select Ugen
i Ugen
a)

tWChoose :: Ugen -> Ugen -> Ugen -> Ugen -> Ugen
tWChoose :: Ugen -> Ugen -> Ugen -> Ugen -> Ugen
tWChoose = forall a b c d r.
(a -> b -> c -> d -> IO r) -> a -> b -> c -> d -> r
liftUnsafe4 forall (m :: * -> *).
Uid m =>
Ugen -> Ugen -> Ugen -> Ugen -> m Ugen
tWChooseM

-- | 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 = forall a b. (a -> b) -> [a] -> [b]
map (\Int
i -> Ugen -> Ugen -> Ugen -> Ugen -> Ugen
unpack1FFT Ugen
c (forall n. Real n => n -> Ugen
constant Int
nf) (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_ = forall a. a -> Maybe a -> a
fromMaybe Ugen
in_ Maybe Ugen
start
      e :: Envelope Ugen
e = 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] forall a. Maybe a
Nothing forall a. Maybe a
Nothing Ugen
0
      -- e[6] = curve; e[7] = curvature;
      time_ch :: Ugen
time_ch = if Ugen -> Rate
rateOf Ugen
time forall a. Eq a => a -> a -> Bool
== Rate
InitialisationRate then Ugen
0 else Ugen -> Ugen -> Ugen
changed Ugen
time Ugen
0
      tr :: Ugen
tr = Ugen -> Ugen -> Ugen
changed Ugen
in_ Ugen
0 forall a. Num a => a -> a -> a
+ Ugen
time_ch 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 forall t. DoneAction t
DoNothing Envelope Ugen
e

{- | k channel white noise.

> whiteNoiseN 2 ar * 0.1
-}
whiteNoiseMN :: Uid m => Int -> Rate -> m Ugen
whiteNoiseMN :: forall (m :: * -> *). Uid m => Int -> Rate -> m Ugen
whiteNoiseMN Int
k Rate
r = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Ugen] -> Ugen
mce (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\Int
_ -> forall (m :: * -> *). Uid m => Rate -> m Ugen
whiteNoiseM Rate
r) [Int
1 .. Int
k])

whiteNoiseN :: Int -> Rate -> Ugen
whiteNoiseN :: Int -> Rate -> Ugen
whiteNoiseN Int
k = forall a r. (a -> IO r) -> a -> r
liftUnsafe1 (forall (m :: * -> *). Uid m => Int -> Rate -> m Ugen
whiteNoiseMN Int
k)

{- | 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) (forall b a. b -> (a -> b) -> Maybe a -> b
maybe Ugen
z ((forall a. Num a => a -> a -> a
* Ugen
z) 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 forall a. Eq a => a -> a -> Bool
== Rate
DemandRate
                   then Rate -> Ugen -> Ugen -> DoneAction Ugen -> Ugen -> Ugen -> Ugen
tDuty Rate
ar Ugen
trigger Ugen
0 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 (forall n. Real n => n -> Ugen
constant Int
n forall a. Num a => a -> a -> a
- Ugen
1) Ugen
1 Ugen
0
        on :: [Ugen]
on = forall a b. (a -> b) -> [a] -> [b]
map
             (\Ugen
i -> Ugen -> Ugen -> Ugen -> Ugen
inRange Ugen
index' (Ugen
i forall a. Num a => a -> a -> a
- Ugen
0.5) (Ugen
i forall a. Num a => a -> a -> a
+ Ugen
0.5))
             [Ugen
0 .. forall n. Real n => n -> Ugen
constant Int
n forall a. Num a => a -> a -> a
- Ugen
1]
        rate' :: [Ugen]
rate' = case Ugen -> Rate
rateOf Ugen
rate of
                  Rate
DemandRate -> forall a b. (a -> b) -> [a] -> [b]
map (\Ugen
on' -> Ugen -> Ugen -> Ugen -> Ugen
demand Ugen
on' Ugen
0 Ugen
rate) [Ugen]
on
                  Rate
ControlRate -> forall a b. (a -> b) -> [a] -> [b]
map (Ugen -> Ugen -> Ugen
gate Ugen
rate) [Ugen]
on
                  Rate
AudioRate -> forall a b. (a -> b) -> [a] -> [b]
map (Ugen -> Ugen -> Ugen
gate Ugen
rate) [Ugen]
on
                  Rate
InitialisationRate -> forall a b. (a -> b) -> [a] -> [b]
map (forall a b. a -> b -> a
const Ugen
rate) [Ugen]
on
        startPos' :: Ugen
startPos' = if Ugen -> Rate
rateOf Ugen
startPos forall a. Eq a => a -> a -> Bool
== Rate
DemandRate
                    then Ugen -> Ugen -> Ugen -> Ugen
demand Ugen
trigger' Ugen
0 Ugen
startPos
                    else Ugen
startPos
        lag'' :: Ugen
lag'' = Ugen
1 forall a. Fractional a => a -> a -> a
/ Ugen
lag'
        s :: [Ugen]
s = 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 forall t. DoneAction t
DoNothing
                       in Ugen
p forall a. Num a => a -> a -> a
* 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 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 forall t. Loop t
NoLoop forall t. Interpolation t
LinearInterpolation