-- | Basic waveforms that are used most often.
-- A waveform function takes in a time varied frequency (in Hz).
module Csound.Air.Wave (
    Wave,

   -- * Bipolar
    osc, oscBy, saw, isaw, pulse, sqr, pw, tri, ramp, blosc,

    -- ** With phase control
    osc', oscBy', saw', isaw', pulse', sqr', pw', tri', ramp', blosc',

    -- ** With random phase
    rndOsc, rndOscBy, rndSaw, rndIsaw, rndPulse, rndSqr, rndPw, rndTri, rndRamp, rndBlosc,
    rndPhs,

    -- ** Raw analog waves (no band limiting)
    -- | Analogue-like waves with no band-limiting. Can be useful for LFOs.
    rawTri, rawSaw, rawSqr, rawPw, rawTri', rawSaw', rawSqr', rawPw', rndRawTri, rndRawSaw, rndRawSqr, rndRawPw,

    -- * Unipolar
    unipolar, bipolar, uosc, uoscBy, usaw, uisaw, upulse, usqr, upw, utri, uramp, ublosc,

    -- ** With phase control
    uosc', uoscBy', usaw', uisaw', upulse', usqr', upw', utri', uramp', ublosc',

    -- ** With random phase
    urndOsc, urndOscBy, urndSaw, urndIsaw, urndPulse, urndSqr, urndPw, urndTri, urndRamp, urndBlosc,

    -- ** Raw analog waves (no band limiting)
    -- | Analogue-like waves with no band-limiting. Can be useful for LFOs.
    urawTri, urawSaw, urawSqr, urawPw, urawTri', urawSaw', urawSqr', urawPw', urndRawTri, urndRawSaw, urndRawSqr, urndRawPw,

    -- * Noise
    rndh, urndh, rndi, urndi, white, pink, brown,

    -- * Frequency modulation
    fosc,

    -- * Low frequency oscillators
    Lfo, lfo,

    -- * Detune
    detune,

    -- * Unision
    multiHz, multiCent, multiRnd, multiGauss, multiRndSE, multiGaussSE,

    -- * Random splines
    urspline, birspline,

    -- * Buzzes
    buz, gbuz, buz', gbuz'
) where

import Csound.Typed
import Csound.Typed.Opcode hiding (lfo)
import Csound.Tab(sine, cosine, triTab, pwTab, sawTab, sqrTab)

type Wave = Sig -> SE Sig

-- | A pure tone (sine wave).
osc :: Sig -> Sig
osc :: Sig -> Sig
osc Sig
cps = Sig -> Sig -> Tab -> Sig
oscil3 Sig
1 Sig
cps Tab
sine

-- | A pure tone (sine wave) with initial phase (the first argiment).
osc' :: D -> Sig -> Sig
osc' :: D -> Sig -> Sig
osc' D
phase Sig
cps = Sig -> Sig -> Tab -> Sig
oscil3 Sig
1 Sig
cps Tab
sine Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
phase

-- | An oscillator with user provided waveform.
oscBy :: Tab -> Sig -> Sig
oscBy :: Tab -> Sig -> Sig
oscBy Tab
tb Sig
cps = Sig -> Sig -> Tab -> Sig
oscil3 Sig
1 Sig
cps Tab
tb

-- | An oscillator with user provided waveform with initial phase (the second argiment).
oscBy' :: Tab -> D -> Sig -> Sig
oscBy' :: Tab -> D -> Sig -> Sig
oscBy' Tab
tb D
phase Sig
cps = Sig -> Sig -> Tab -> Sig
oscil3 Sig
1 Sig
cps Tab
tb Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
phase

-- unipolar waveforms

-- | Turns a bipolar sound (ranges from -1 to 1) to unipolar (ranges from 0 to 1)
unipolar :: Sig -> Sig
unipolar :: Sig -> Sig
unipolar Sig
a = Sig
0.5 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
+ Sig
0.5 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
a

-- | Turns an unipolar sound (ranges from 0 to 1) to bipolar (ranges from -1 to 1)
bipolar :: Sig -> Sig
bipolar :: Sig -> Sig
bipolar Sig
a = Sig
2 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
a Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
- Sig
1

-- | Unipolar pure tone.
uosc :: Sig -> Sig
uosc :: Sig -> Sig
uosc = Sig -> Sig
unipolar (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig
osc

-- | Unipolar 'Csound.Air.oscBy'.
uoscBy :: Tab -> Sig -> Sig
uoscBy :: Tab -> Sig -> Sig
uoscBy Tab
tb = Sig -> Sig
unipolar (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tab -> Sig -> Sig
oscBy Tab
tb

-- | Unipolar sawtooth.
usaw :: Sig -> Sig
usaw :: Sig -> Sig
usaw = Sig -> Sig
unipolar (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig
saw

-- | Unipolar integrated sawtooth.
uisaw :: Sig -> Sig
uisaw :: Sig -> Sig
uisaw = Sig -> Sig
unipolar (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig
isaw

-- | Unipolar square wave.
usqr :: Sig -> Sig
usqr :: Sig -> Sig
usqr = Sig -> Sig
unipolar (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig
sqr

-- | Unipolar triangle wave.
utri :: Sig -> Sig
utri :: Sig -> Sig
utri = Sig -> Sig
unipolar (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig
tri

-- | Unipolar pulse.
upulse :: Sig -> Sig
upulse :: Sig -> Sig
upulse = Sig -> Sig
unipolar (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig
pulse

-- | Unipolar band-limited oscillator.
ublosc :: Tab -> Sig -> Sig
ublosc :: Tab -> Sig -> Sig
ublosc Tab
tb = Sig -> Sig
unipolar (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tab -> Sig -> Sig
blosc Tab
tb

-- | Unipolar random splines.
-- It generates the splines with unipolar output (ranges from 0 to 1).
-- Arguments affect the frequency for generation of new values.
--
-- > urspline cpsMin cpsMax
urspline :: Sig -> Sig -> SE Sig
urspline :: Sig -> Sig -> SE Sig
urspline Sig
cpsMin Sig
cpsMax = Sig -> Sig -> Sig -> Sig -> SE Sig
rspline Sig
0 Sig
1 Sig
cpsMin Sig
cpsMax

-- | Bipolar random splines.
-- It generates the splines with bipolar output (ranges from -1 to 1).
-- Arguments affect the frequency for generation of new values.
--
-- > birspline cpsMin cpsMax
birspline :: Sig -> Sig -> SE Sig
birspline :: Sig -> Sig -> SE Sig
birspline Sig
cpsMin Sig
cpsMax = Sig -> Sig -> Sig -> Sig -> SE Sig
rspline (-Sig
1) Sig
1 Sig
cpsMin Sig
cpsMax

-----------------------

-- | Frequency modulation
--
-- > fosc carrierFreq modulatorFreq modIndex cps
fosc :: Sig -> Sig -> Sig -> Sig -> Sig
fosc :: Sig -> Sig -> Sig -> Sig -> Sig
fosc Sig
car Sig
modFreq Sig
ndx Sig
cps = Sig -> Sig -> Sig -> Sig -> Sig -> Tab -> Sig
foscili Sig
1 Sig
cps Sig
car Sig
modFreq Sig
ndx Tab
sine

-- | Pulse width modulation (width range is 0 to 1)
--
-- > pw dutyCycle cps
pw :: Sig -> Sig -> Sig
pw :: Sig -> Sig -> Sig
pw Sig
duty Sig
cps = Sig -> Sig -> Sig
vco2 Sig
1 Sig
cps Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
2 Sig -> Sig -> Sig
forall a. Tuple a => a -> Sig -> a
`withSig` Sig
duty

-- | Pulse width modulation (width range is 0 to 1)
--
-- > pw' dutyCycle phase cps
pw' :: Sig -> D -> Sig -> Sig
pw' :: Sig -> D -> Sig -> Sig
pw' Sig
duty D
phase Sig
cps = Sig -> Sig -> Sig
vco2 Sig
1 Sig
cps Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
2 Sig -> Sig -> Sig
forall a. Tuple a => a -> Sig -> a
`withSig` Sig
duty Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
phase

-- | Triangle wave with ramp factor (factor's range is 0 to 1)
--
-- > ramp factor cps
ramp :: Sig -> Sig -> Sig
ramp :: Sig -> Sig -> Sig
ramp Sig
duty Sig
cps = Sig -> Sig -> Sig
vco2 Sig
1 Sig
cps Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
4 Sig -> Sig -> Sig
forall a. Tuple a => a -> Sig -> a
`withSig` (Sig -> Sig -> Sig -> Sig
forall a. SigSpace a => Sig -> Sig -> a -> a
uon Sig
0.01 Sig
0.99 (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig
duty)

-- | Triangle wave with ramp factor (factor's range is 0 to 1)
--
-- > ramp' factor phase cps
ramp' :: Sig -> D -> Sig -> Sig
ramp' :: Sig -> D -> Sig -> Sig
ramp' Sig
duty D
phase Sig
cps = Sig -> Sig -> Sig
vco2 Sig
1 Sig
cps Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
4 Sig -> Sig -> Sig
forall a. Tuple a => a -> Sig -> a
`withSig` (Sig -> Sig -> Sig -> Sig
forall a. SigSpace a => Sig -> Sig -> a -> a
uon Sig
0.01 Sig
0.99 (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig
duty) Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
phase

-- | Unipolar pulse width modulation wave.
upw :: Sig -> Sig -> Sig
upw :: Sig -> Sig -> Sig
upw Sig
duty Sig
cps = Sig -> Sig
unipolar (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig -> Sig -> Sig
pw Sig
duty Sig
cps

-- | Unipolar triangle wave with ram factor.
uramp :: Sig -> Sig -> Sig
uramp :: Sig -> Sig -> Sig
uramp Sig
duty Sig
cps = Sig -> Sig
unipolar (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig -> Sig -> Sig
ramp Sig
duty Sig
cps

--------------------------------------------------------------------------
-- unipolar oscils with phase control

unipolar' :: (D -> Sig -> Sig) -> (D -> Sig -> Sig)
unipolar' :: (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' D -> Sig -> Sig
f D
phs Sig
cps = Sig -> Sig
unipolar (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ D -> Sig -> Sig
f D
phs Sig
cps

uosc', utri', usqr', usaw', upulse', uisaw' :: D -> Sig -> Sig
uoscBy', ublosc' :: Tab -> D -> Sig -> Sig
uramp', upw' :: Sig -> D -> Sig -> Sig

uosc' :: D -> Sig -> Sig
uosc' = (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' D -> Sig -> Sig
osc'
uoscBy' :: Tab -> D -> Sig -> Sig
uoscBy' Tab
a = (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' (Tab -> D -> Sig -> Sig
oscBy' Tab
a)
usaw' :: D -> Sig -> Sig
usaw' = (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' D -> Sig -> Sig
saw'
uisaw' :: D -> Sig -> Sig
uisaw' = (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' D -> Sig -> Sig
isaw'
upulse' :: D -> Sig -> Sig
upulse' = (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' D -> Sig -> Sig
pulse'
usqr' :: D -> Sig -> Sig
usqr' = (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' D -> Sig -> Sig
sqr'
upw' :: Sig -> D -> Sig -> Sig
upw' Sig
a = (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' (Sig -> D -> Sig -> Sig
pw' Sig
a)
utri' :: D -> Sig -> Sig
utri' = (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' D -> Sig -> Sig
tri'
uramp' :: Sig -> D -> Sig -> Sig
uramp' Sig
a = (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' (Sig -> D -> Sig -> Sig
ramp' Sig
a)
ublosc' :: Tab -> D -> Sig -> Sig
ublosc' Tab
a = (D -> Sig -> Sig) -> D -> Sig -> Sig
unipolar' (Tab -> D -> Sig -> Sig
blosc' Tab
a)

--------------------------------------------------------------------------
-- random phase

-- | Generic random smoothTypephase oscil
rndPhs :: (D -> Sig -> Sig) -> (Sig -> SE Sig)
rndPhs :: (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
f Sig
cps = (D -> Sig) -> SE D -> SE Sig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\D
x -> D -> Sig -> Sig
f D
x Sig
cps) (SE D -> SE Sig) -> SE D -> SE Sig
forall a b. (a -> b) -> a -> b
$ D -> SE D
forall a. SigOrD a => a -> SE a
rnd D
1

rndOsc, rndTri, rndSqr, rndSaw, rndIsaw, rndPulse :: Sig -> SE Sig
rndOscBy, rndBlosc :: Tab -> Sig -> SE Sig
rndRamp, rndPw :: Sig -> Sig -> SE Sig

rndOsc :: Sig -> SE Sig
rndOsc = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
osc'
rndOscBy :: Tab -> Sig -> SE Sig
rndOscBy Tab
a = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs (Tab -> D -> Sig -> Sig
oscBy' Tab
a)
rndSaw :: Sig -> SE Sig
rndSaw = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
saw'
rndIsaw :: Sig -> SE Sig
rndIsaw = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
isaw'
rndPulse :: Sig -> SE Sig
rndPulse = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
pulse'
rndSqr :: Sig -> SE Sig
rndSqr = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
sqr'
rndPw :: Sig -> Sig -> SE Sig
rndPw Sig
a = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs (Sig -> D -> Sig -> Sig
pw' Sig
a)
rndTri :: Sig -> SE Sig
rndTri = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
tri'
rndRamp :: Sig -> Sig -> SE Sig
rndRamp Sig
a = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs (Sig -> D -> Sig -> Sig
ramp' Sig
a)
rndBlosc :: Tab -> Sig -> SE Sig
rndBlosc Tab
a = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs (Tab -> D -> Sig -> Sig
blosc' Tab
a)

--------------------------------------------------------------------------
-- unipolar random phase

urndOsc, urndTri, urndSqr, urndSaw, urndIsaw, urndPulse :: Sig -> SE Sig
urndOscBy, urndBlosc :: Tab -> Sig -> SE Sig
urndRamp, urndPw :: Sig -> Sig -> SE Sig

urndOsc :: Sig -> SE Sig
urndOsc = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
uosc'
urndOscBy :: Tab -> Sig -> SE Sig
urndOscBy Tab
a = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs (Tab -> D -> Sig -> Sig
uoscBy' Tab
a)
urndSaw :: Sig -> SE Sig
urndSaw = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
usaw'
urndIsaw :: Sig -> SE Sig
urndIsaw = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
uisaw'
urndPulse :: Sig -> SE Sig
urndPulse = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
upulse'
urndSqr :: Sig -> SE Sig
urndSqr = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
usqr'
urndPw :: Sig -> Sig -> SE Sig
urndPw Sig
a = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs (Sig -> D -> Sig -> Sig
upw' Sig
a)
urndTri :: Sig -> SE Sig
urndTri = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs D -> Sig -> Sig
utri'
urndRamp :: Sig -> Sig -> SE Sig
urndRamp Sig
a = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs (Sig -> D -> Sig -> Sig
uramp' Sig
a)
urndBlosc :: Tab -> Sig -> SE Sig
urndBlosc Tab
a = (D -> Sig -> Sig) -> Sig -> SE Sig
rndPhs (Tab -> D -> Sig -> Sig
ublosc' Tab
a)


--------------------------------------------------------------------------
-- noise

-- | Constant random signal. It updates random numbers with given frequency.
--
-- > constRnd freq
rndh :: Sig -> SE Sig
rndh :: Sig -> SE Sig
rndh = Sig -> Sig -> SE Sig
randh Sig
1

-- | Linear random signal. It updates random numbers with given frequency.
--
-- > rndi freq
rndi :: Sig -> SE Sig
rndi :: Sig -> SE Sig
rndi = Sig -> Sig -> SE Sig
randi Sig
1

-- | Unipolar @rndh@
urndh :: Sig -> SE Sig
urndh :: Sig -> SE Sig
urndh = (Sig -> Sig) -> SE Sig -> SE Sig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sig -> Sig
unipolar (SE Sig -> SE Sig) -> (Sig -> SE Sig) -> Sig -> SE Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> SE Sig
rndh

-- | Unipolar @rndi@
urndi :: Sig -> SE Sig
urndi :: Sig -> SE Sig
urndi = (Sig -> Sig) -> SE Sig -> SE Sig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sig -> Sig
unipolar (SE Sig -> SE Sig) -> (Sig -> SE Sig) -> Sig -> SE Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> SE Sig
rndi

-- | White noise.
white :: SE Sig
white :: SE Sig
white = Sig -> Sig -> SE Sig
noise Sig
1 Sig
0

-- | Pink noise.
pink :: SE Sig
pink :: SE Sig
pink = Sig -> SE Sig
pinkish Sig
1

-- | Brownian noise
brown :: SE Sig
brown :: SE Sig
brown = (Sig -> Sig) -> SE Sig -> SE Sig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> Sig
dcblock (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig
integ (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
0.1)) SE Sig
white

--------------------------------------------------------------------------
-- lfo

-- | Low frequency oscillator
type Lfo = Sig

-- | Low frequency oscillator
--
-- > lfo shape depth rate
lfo :: (Sig -> Sig) -> Sig -> Sig -> Sig
lfo :: (Sig -> Sig) -> Sig -> Sig -> Sig
lfo Sig -> Sig
shape Sig
depth Sig
rate = Sig
depth Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig -> Sig
shape Sig
rate

--------------------------------------------------------------------------

-- | Scales the oscillator by frequency.
-- That's how we can rise the pitch by 2 semitones and 15 cents:
--
-- > detune (semitone 2 * cent 15) osc
detune :: Sig -> (Sig -> a) -> (Sig -> a)
detune :: Sig -> (Sig -> a) -> Sig -> a
detune Sig
k Sig -> a
f Sig
cps = Sig -> a
f (Sig
k Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
cps)

--------------------------------------------------------------------------

linRange :: Integral a => a -> Sig -> [Sig]
linRange :: a -> Sig -> [Sig]
linRange a
n Sig
amount = (Double -> Sig) -> [Double] -> [Sig]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> Sig
amount Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* D -> Sig
sig (D
2 D -> D -> D
forall a. Num a => a -> a -> a
* Double -> D
double Double
x D -> D -> D
forall a. Num a => a -> a -> a
- D
1)) [Double
0, (Double
1 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ a -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n) .. Double
1]

-- | Unision by Hertz. It creates n oscillators that are playing
-- the same pitch slightly detuned. The oscillatos's pitch is evenly distributed in Hz.
--
-- > multiHz numberOfUnits amountHz wave
multiHz :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> a)
multiHz :: Int -> Sig -> (Sig -> a) -> Sig -> a
multiHz Int
n Sig
amount Sig -> a
f Sig
cps = [a] -> a
forall a. Fractional a => [a] -> a
mean ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ (Sig -> a) -> [Sig] -> [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> a
f (Sig -> a) -> (Sig -> Sig) -> Sig -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sig
cps Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
+ )) ([Sig] -> [a]) -> [Sig] -> [a]
forall a b. (a -> b) -> a -> b
$ Int -> Sig -> [Sig]
forall a. Integral a => a -> Sig -> [Sig]
linRange Int
n Sig
amount

-- | Unision by Cents. It creates n oscillators that are playing
-- the same pitch slightly detuned. The oscillatos's pitch is evenly distributed in cents.
--
-- > multiCent numberOfUnits amountCent wave
multiCent :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> a)
multiCent :: Int -> Sig -> (Sig -> a) -> Sig -> a
multiCent Int
n Sig
amount Sig -> a
f Sig
cps = [a] -> a
forall a. Fractional a => [a] -> a
mean ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ (Sig -> a) -> [Sig] -> [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> a
f (Sig -> a) -> (Sig -> Sig) -> Sig -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sig
cps Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* ) (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig
forall a. SigOrD a => a -> a
cent) ([Sig] -> [a]) -> [Sig] -> [a]
forall a b. (a -> b) -> a -> b
$ Int -> Sig -> [Sig]
forall a. Integral a => a -> Sig -> [Sig]
linRange Int
n Sig
amount

-- | Oscillators are detuned randomly in the given interval.
--
-- > multiRnd numberOfUnits amountCent wave
multiRnd :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> SE a)
multiRnd :: Int -> Sig -> (Sig -> a) -> Sig -> SE a
multiRnd = SE D -> Int -> Sig -> (Sig -> a) -> Sig -> SE a
forall a.
Fractional a =>
SE D -> Int -> Sig -> (Sig -> a) -> Sig -> SE a
genMultiRnd (D -> SE D
forall a. SigOrD a => a -> SE a
rnd D
1)

-- | Oscillators are detuned randomly with Gauss distribution in the given interval.
--
-- > multiGauss numberOfUnits amountCent wave
multiGauss :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> SE a)
multiGauss :: Int -> Sig -> (Sig -> a) -> Sig -> SE a
multiGauss = SE D -> Int -> Sig -> (Sig -> a) -> Sig -> SE a
forall a.
Fractional a =>
SE D -> Int -> Sig -> (Sig -> a) -> Sig -> SE a
genMultiRnd ((Sig -> D) -> SE Sig -> SE D
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((D -> D -> D
forall a. Num a => a -> a -> a
+ D
0.5) (D -> D) -> (Sig -> D) -> Sig -> D
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> D
ir) (SE Sig -> SE D) -> SE Sig -> SE D
forall a b. (a -> b) -> a -> b
$ Sig -> SE Sig
gauss Sig
0.5)

genMultiRnd :: Fractional a => (SE D) -> Int -> Sig -> (Sig -> a) -> (Sig -> SE a)
genMultiRnd :: SE D -> Int -> Sig -> (Sig -> a) -> Sig -> SE a
genMultiRnd SE D
gen Int
n Sig
amount Sig -> a
f Sig
cps = ([a] -> a) -> SE [a] -> SE a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [a] -> a
forall a. Fractional a => [a] -> a
mean (SE [a] -> SE a) -> SE [a] -> SE a
forall a b. (a -> b) -> a -> b
$ (() -> SE a) -> [()] -> SE [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SE a -> () -> SE a
forall a b. a -> b -> a
const SE a
go) ([()] -> SE [a]) -> [()] -> SE [a]
forall a b. (a -> b) -> a -> b
$ Int -> () -> [()]
forall a. Int -> a -> [a]
replicate Int
n ()
    where go :: SE a
go = (D -> a) -> SE D -> SE a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\D
dx -> Sig -> a
f (Sig -> a) -> Sig -> a
forall a b. (a -> b) -> a -> b
$ Sig
cps Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
+ Sig
amount Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* (D -> Sig
sig (D -> Sig) -> D -> Sig
forall a b. (a -> b) -> a -> b
$ D
2 D -> D -> D
forall a. Num a => a -> a -> a
* D
dx D -> D -> D
forall a. Num a => a -> a -> a
- D
1)) SE D
gen

-- | Oscillators are detuned randomly in the given interval.
-- Useful for waves that return a signals with Side Effects.
--
-- > multiRnd numberOfUnits amountCent wave
multiRndSE :: Fractional a => Int -> Sig -> (Sig -> SE a) -> (Sig -> SE a)
multiRndSE :: Int -> Sig -> (Sig -> SE a) -> Sig -> SE a
multiRndSE = SE D -> Int -> Sig -> (Sig -> SE a) -> Sig -> SE a
forall a.
Fractional a =>
SE D -> Int -> Sig -> (Sig -> SE a) -> Sig -> SE a
genMultiRndSE (D -> SE D
forall a. SigOrD a => a -> SE a
rnd D
1)

-- | Oscillators are detuned randomly with Gauss distribution in the given interval.
-- Useful for waves that return a signals with Side Effects.
--
-- > multiGauss numberOfUnits amountCent wave
multiGaussSE :: Fractional a => Int -> Sig -> (Sig -> SE a) -> (Sig -> SE a)
multiGaussSE :: Int -> Sig -> (Sig -> SE a) -> Sig -> SE a
multiGaussSE = SE D -> Int -> Sig -> (Sig -> SE a) -> Sig -> SE a
forall a.
Fractional a =>
SE D -> Int -> Sig -> (Sig -> SE a) -> Sig -> SE a
genMultiRndSE ((Sig -> D) -> SE Sig -> SE D
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((D -> D -> D
forall a. Num a => a -> a -> a
+ D
0.5) (D -> D) -> (Sig -> D) -> Sig -> D
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> D
ir) (SE Sig -> SE D) -> SE Sig -> SE D
forall a b. (a -> b) -> a -> b
$ Sig -> SE Sig
gauss Sig
0.5)

genMultiRndSE :: Fractional a => (SE D) -> Int -> Sig -> (Sig -> SE a) -> (Sig -> SE a)
genMultiRndSE :: SE D -> Int -> Sig -> (Sig -> SE a) -> Sig -> SE a
genMultiRndSE SE D
gen Int
n Sig
amount Sig -> SE a
f Sig
cps = ([a] -> a) -> SE [a] -> SE a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [a] -> a
forall a. Fractional a => [a] -> a
mean (SE [a] -> SE a) -> SE [a] -> SE a
forall a b. (a -> b) -> a -> b
$ (() -> SE a) -> [()] -> SE [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SE a -> () -> SE a
forall a b. a -> b -> a
const SE a
go) ([()] -> SE [a]) -> [()] -> SE [a]
forall a b. (a -> b) -> a -> b
$ Int -> () -> [()]
forall a. Int -> a -> [a]
replicate Int
n ()
    where go :: SE a
go = (\D
dx -> Sig -> SE a
f (Sig -> SE a) -> Sig -> SE a
forall a b. (a -> b) -> a -> b
$ Sig
cps Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig -> Sig
forall a. SigOrD a => a -> a
cent (Sig
amount Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* (D -> Sig
sig (D -> Sig) -> D -> Sig
forall a b. (a -> b) -> a -> b
$ D
2 D -> D -> D
forall a. Num a => a -> a -> a
* D
dx D -> D -> D
forall a. Num a => a -> a -> a
- D
1))) (D -> SE a) -> SE D -> SE a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SE D
gen

-- | Mean value.
mean :: Fractional a => [a] -> a
mean :: [a] -> a
mean [a]
xs = [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [a]
xs a -> a -> a
forall a. Fractional a => a -> a -> a
/ (Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> a) -> Int -> a
forall a b. (a -> b) -> a -> b
$ [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs)

---------------------------------------------
-- buzzes

-- |  Output is a set of harmonically related sine partials.
--
-- > buz numOfHarmonics frequency
buz :: Sig -> Sig -> Sig
buz :: Sig -> Sig -> Sig
buz Sig
kh Sig
x = Sig -> Sig -> Sig -> Tab -> Sig
buzz Sig
1 Sig
x Sig
kh Tab
sine

-- | Buz with phase
buz' :: D -> Sig -> Sig -> Sig
buz' :: D -> Sig -> Sig -> Sig
buz' D
phs Sig
kh Sig
x = Sig -> Sig -> Sig
buz Sig
kh Sig
x Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
phs

-- |  Output is a set of harmonically related cosine partials.
--
-- > gbuz (minHarm, maxHarm) ratio frequency
gbuz :: (Sig, Sig) -> Sig -> Sig -> Sig
gbuz :: (Sig, Sig) -> Sig -> Sig -> Sig
gbuz (Sig
hmin, Sig
hmax) Sig
hratio Sig
x = Sig -> Sig -> Sig -> Sig -> Sig -> Tab -> Sig
gbuzz Sig
1 Sig
x Sig
hmax Sig
hmin Sig
hratio Tab
cosine

-- | Gbuz with phase
gbuz' :: D -> (Sig, Sig) -> Sig -> Sig -> Sig
gbuz' :: D -> (Sig, Sig) -> Sig -> Sig -> Sig
gbuz' D
phs (Sig, Sig)
hs Sig
hratio Sig
x = (Sig, Sig) -> Sig -> Sig -> Sig
gbuz (Sig, Sig)
hs Sig
hratio Sig
x Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
phs

---------------------------------------------
-- raw waveforms

-- bipolar

rawTri :: Sig -> Sig
rawTri :: Sig -> Sig
rawTri = Tab -> Sig -> Sig
oscBy Tab
triTab

rawSaw :: Sig -> Sig
rawSaw :: Sig -> Sig
rawSaw = Tab -> Sig -> Sig
oscBy Tab
sawTab

rawSqr :: Sig -> Sig
rawSqr :: Sig -> Sig
rawSqr = Tab -> Sig -> Sig
oscBy Tab
sqrTab

rawPw :: Double -> Sig -> Sig
rawPw :: Double -> Sig -> Sig
rawPw Double
duty = Tab -> Sig -> Sig
oscBy (Double -> Tab
pwTab Double
duty)

rawTri' :: D -> Sig -> Sig
rawTri' :: D -> Sig -> Sig
rawTri' = Tab -> D -> Sig -> Sig
oscBy' Tab
triTab

rawSaw' :: D -> Sig -> Sig
rawSaw' :: D -> Sig -> Sig
rawSaw' = Tab -> D -> Sig -> Sig
oscBy' Tab
sawTab

rawSqr' :: D -> Sig -> Sig
rawSqr' :: D -> Sig -> Sig
rawSqr' = Tab -> D -> Sig -> Sig
oscBy' Tab
sqrTab

rawPw' :: Double -> D -> Sig -> Sig
rawPw' :: Double -> D -> Sig -> Sig
rawPw' Double
duty = Tab -> D -> Sig -> Sig
oscBy' (Double -> Tab
pwTab Double
duty)

rndRawTri :: Sig -> SE Sig
rndRawTri :: Sig -> SE Sig
rndRawTri = Tab -> Sig -> SE Sig
rndOscBy Tab
triTab

rndRawSaw :: Sig -> SE Sig
rndRawSaw :: Sig -> SE Sig
rndRawSaw = Tab -> Sig -> SE Sig
rndOscBy Tab
sawTab

rndRawSqr :: Sig -> SE Sig
rndRawSqr :: Sig -> SE Sig
rndRawSqr = Tab -> Sig -> SE Sig
rndOscBy Tab
sqrTab

rndRawPw :: Double -> Sig -> SE Sig
rndRawPw :: Double -> Sig -> SE Sig
rndRawPw Double
duty = Tab -> Sig -> SE Sig
rndOscBy (Double -> Tab
pwTab Double
duty)

-- unipolar

urawTri :: Sig -> Sig
urawTri :: Sig -> Sig
urawTri = Tab -> Sig -> Sig
uoscBy Tab
triTab

urawSaw :: Sig -> Sig
urawSaw :: Sig -> Sig
urawSaw = Tab -> Sig -> Sig
uoscBy Tab
sawTab

urawSqr :: Sig -> Sig
urawSqr :: Sig -> Sig
urawSqr = Tab -> Sig -> Sig
uoscBy Tab
sqrTab

urawPw :: Double -> Sig -> Sig
urawPw :: Double -> Sig -> Sig
urawPw Double
duty = Tab -> Sig -> Sig
uoscBy (Double -> Tab
pwTab Double
duty)

urawTri' :: D -> Sig -> Sig
urawTri' :: D -> Sig -> Sig
urawTri' = Tab -> D -> Sig -> Sig
uoscBy' Tab
triTab

urawSaw' :: D -> Sig -> Sig
urawSaw' :: D -> Sig -> Sig
urawSaw' = Tab -> D -> Sig -> Sig
uoscBy' Tab
sawTab

urawSqr' :: D -> Sig -> Sig
urawSqr' :: D -> Sig -> Sig
urawSqr' = Tab -> D -> Sig -> Sig
uoscBy' Tab
sqrTab

urawPw' :: Double -> D -> Sig -> Sig
urawPw' :: Double -> D -> Sig -> Sig
urawPw' Double
duty = Tab -> D -> Sig -> Sig
uoscBy' (Double -> Tab
pwTab Double
duty)

urndRawTri :: Sig -> SE Sig
urndRawTri :: Sig -> SE Sig
urndRawTri = Tab -> Sig -> SE Sig
urndOscBy Tab
triTab

urndRawSaw :: Sig -> SE Sig
urndRawSaw :: Sig -> SE Sig
urndRawSaw = Tab -> Sig -> SE Sig
urndOscBy Tab
sawTab

urndRawSqr :: Sig -> SE Sig
urndRawSqr :: Sig -> SE Sig
urndRawSqr = Tab -> Sig -> SE Sig
urndOscBy Tab
sqrTab

urndRawPw :: Double -> Sig -> SE Sig
urndRawPw :: Double -> Sig -> SE Sig
urndRawPw Double
duty = Tab -> Sig -> SE Sig
urndOscBy (Double -> Tab
pwTab Double
duty)