module Csound.Air.Wave (
Wave,
osc, oscBy, saw, isaw, pulse, sqr, pw, tri, ramp, blosc,
osc', oscBy', saw', isaw', pulse', sqr', pw', tri', ramp', blosc',
rndOsc, rndOscBy, rndSaw, rndIsaw, rndPulse, rndSqr, rndPw, rndTri, rndRamp, rndBlosc,
rndPhs,
rawTri, rawSaw, rawSqr, rawPw, rawTri', rawSaw', rawSqr', rawPw', rndRawTri, rndRawSaw, rndRawSqr, rndRawPw,
unipolar, bipolar, uosc, uoscBy, usaw, uisaw, upulse, usqr, upw, utri, uramp, ublosc,
uosc', uoscBy', usaw', uisaw', upulse', usqr', upw', utri', uramp', ublosc',
urndOsc, urndOscBy, urndSaw, urndIsaw, urndPulse, urndSqr, urndPw, urndTri, urndRamp, urndBlosc,
urawTri, urawSaw, urawSqr, urawPw, urawTri', urawSaw', urawSqr', urawPw', urndRawTri, urndRawSaw, urndRawSqr, urndRawPw,
rndh, urndh, rndi, urndi, white, pink, brown,
fosc,
Lfo, lfo,
detune,
multiHz, multiCent, multiRnd, multiGauss, multiRndSE, multiGaussSE,
urspline, birspline,
buz, gbuz, buz', gbuz'
) where
import Csound.Typed
import Csound.Typed.Opcode hiding (lfo)
import Csound.Tab(setSize, elins, sine, cosine, sines4, triTab, pwTab, sawTab, sqrTab)
import Csound.SigSpace
type Wave = Sig -> SE Sig
osc :: Sig -> Sig
osc cps = oscil3 1 cps sine
osc' :: D -> Sig -> Sig
osc' phase cps = oscil3 1 cps sine `withD` phase
oscBy :: Tab -> Sig -> Sig
oscBy tb cps = oscil3 1 cps tb
oscBy' :: Tab -> D -> Sig -> Sig
oscBy' tb phase cps = oscil3 1 cps tb `withD` phase
unipolar :: Sig -> Sig
unipolar a = 0.5 + 0.5 * a
bipolar :: Sig -> Sig
bipolar a = 2 * a - 1
uosc :: Sig -> Sig
uosc = unipolar . osc
uoscBy :: Tab -> Sig -> Sig
uoscBy tb = unipolar . oscBy tb
usaw :: Sig -> Sig
usaw = unipolar . saw
uisaw :: Sig -> Sig
uisaw = unipolar . isaw
usqr :: Sig -> Sig
usqr = unipolar . sqr
utri :: Sig -> Sig
utri = unipolar . tri
upulse :: Sig -> Sig
upulse = unipolar . pulse
ublosc :: Tab -> Sig -> Sig
ublosc tb = unipolar . blosc tb
urspline :: Sig -> Sig -> SE Sig
urspline cpsMin cpsMax = rspline 0 1 cpsMin cpsMax
birspline :: Sig -> Sig -> SE Sig
birspline cpsMin cpsMax = rspline (-1) 1 cpsMin cpsMax
fosc :: Sig -> Sig -> Sig -> Sig -> Sig
fosc car mod ndx cps = foscili 1 cps car mod ndx sine
pw :: Sig -> Sig -> Sig
pw duty cps = vco2 1 cps `withD` 2 `withSig` duty
pw' :: Sig -> D -> Sig -> Sig
pw' duty phase cps = vco2 1 cps `withD` 2 `withSig` duty `withD` phase
ramp :: Sig -> Sig -> Sig
ramp duty cps = vco2 1 cps `withD` 4 `withSig` (uon 0.01 0.99 $ duty)
ramp' :: Sig -> D -> Sig -> Sig
ramp' duty phase cps = vco2 1 cps `withD` 4 `withSig` (uon 0.01 0.99 $ duty) `withD` phase
upw :: Sig -> Sig -> Sig
upw duty cps = unipolar $ pw duty cps
uramp :: Sig -> Sig -> Sig
uramp duty cps = unipolar $ ramp duty cps
unipolar' :: (D -> Sig -> Sig) -> (D -> Sig -> Sig)
unipolar' f phs cps = unipolar $ f phs cps
uosc' = unipolar' osc'
uoscBy' a = unipolar' (oscBy' a)
usaw' = unipolar' saw'
uisaw' = unipolar' isaw'
upulse' = unipolar' pulse'
usqr' = unipolar' sqr'
upw' a = unipolar' (pw' a)
utri' = unipolar' tri'
uramp' a = unipolar' (ramp' a)
ublosc' a = unipolar' (blosc' a)
rndPhs :: (D -> Sig -> Sig) -> (Sig -> SE Sig)
rndPhs f cps = fmap (\x -> f x cps) $ rnd 1
rndOsc = rndPhs osc'
rndOscBy a = rndPhs (oscBy' a)
rndSaw = rndPhs saw'
rndIsaw = rndPhs isaw'
rndPulse = rndPhs pulse'
rndSqr = rndPhs sqr'
rndPw a = rndPhs (pw' a)
rndTri = rndPhs tri'
rndRamp a = rndPhs (ramp' a)
rndBlosc a = rndPhs (blosc' a)
urndOsc = rndPhs uosc'
urndOscBy a = rndPhs (uoscBy' a)
urndSaw = rndPhs usaw'
urndIsaw = rndPhs uisaw'
urndPulse = rndPhs upulse'
urndSqr = rndPhs usqr'
urndPw a = rndPhs (upw' a)
urndTri = rndPhs utri'
urndRamp a = rndPhs (uramp' a)
urndBlosc a = rndPhs (ublosc' a)
rndh :: Sig -> SE Sig
rndh = randh 1
rndi :: Sig -> SE Sig
rndi = randi 1
urndh :: Sig -> SE Sig
urndh = fmap unipolar . rndh
urndi :: Sig -> SE Sig
urndi = fmap unipolar . rndi
white :: SE Sig
white = noise 1 0
pink :: SE Sig
pink = pinkish 1
brown :: SE Sig
brown = fmap (dcblock . integ . (* 0.1)) white
type Lfo = Sig
lfo :: (Sig -> Sig) -> Sig -> Sig -> Sig
lfo shape depth rate = depth * shape rate
detune :: Sig -> (Sig -> a) -> (Sig -> a)
detune k f cps = f (k * cps)
linRange n amount = fmap (\x -> amount * sig (2 * double x - 1)) [0, (1 / fromIntegral n) .. 1]
multiHz :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> a)
multiHz n amount f cps = mean $ fmap (f . (cps + )) $ linRange n amount
multiCent :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> a)
multiCent n amount f cps = mean $ fmap (f . (cps * ) . cent) $ linRange n amount
multiRnd :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> SE a)
multiRnd = genMultiRnd (rnd 1)
multiGauss :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> SE a)
multiGauss = genMultiRnd (fmap ((+ 0.5) . ir) $ gauss 0.5)
genMultiRnd :: Fractional a => (SE D) -> Int -> Sig -> (Sig -> a) -> (Sig -> SE a)
genMultiRnd gen n amount f cps = fmap mean $ mapM (const go) $ replicate n ()
where go = fmap (\dx -> f $ cps + amount * (sig $ 2 * dx - 1)) gen
multiRndSE :: Fractional a => Int -> Sig -> (Sig -> SE a) -> (Sig -> SE a)
multiRndSE = genMultiRndSE (rnd 1)
multiGaussSE :: Fractional a => Int -> Sig -> (Sig -> SE a) -> (Sig -> SE a)
multiGaussSE = genMultiRndSE (fmap ((+ 0.5) . ir) $ gauss 0.5)
genMultiRndSE :: Fractional a => (SE D) -> Int -> Sig -> (Sig -> SE a) -> (Sig -> SE a)
genMultiRndSE gen n amount f cps = fmap mean $ mapM (const go) $ replicate n ()
where go = (\dx -> f $ cps * cent (amount * (sig $ 2 * dx - 1))) =<< gen
mean :: Fractional a => [a] -> a
mean xs = sum xs / (fromIntegral $ length xs)
buz :: Sig -> Sig -> Sig
buz kh x = buzz 1 x kh sine
buz' :: D -> Sig -> Sig -> Sig
buz' phs kh x = buz kh x `withD` phs
gbuz :: (Sig, Sig) -> Sig -> Sig -> Sig
gbuz (hmin, hmax) hratio x = gbuzz 1 x hmax hmin hratio cosine
gbuz' :: D -> (Sig, Sig) -> Sig -> Sig -> Sig
gbuz' phs hs hratio x = gbuz hs hratio x `withD` phs
rawTri :: Sig -> Sig
rawTri = oscBy triTab
rawSaw :: Sig -> Sig
rawSaw = oscBy sawTab
rawSqr :: Sig -> Sig
rawSqr = oscBy sqrTab
rawPw :: Double -> Sig -> Sig
rawPw duty = oscBy (pwTab duty)
rawTri' :: D -> Sig -> Sig
rawTri' = oscBy' triTab
rawSaw' :: D -> Sig -> Sig
rawSaw' = oscBy' sawTab
rawSqr' :: D -> Sig -> Sig
rawSqr' = oscBy' sqrTab
rawPw' :: Double -> D -> Sig -> Sig
rawPw' duty = oscBy' (pwTab duty)
rndRawTri :: Sig -> SE Sig
rndRawTri = rndOscBy triTab
rndRawSaw :: Sig -> SE Sig
rndRawSaw = rndOscBy sawTab
rndRawSqr :: Sig -> SE Sig
rndRawSqr = rndOscBy sqrTab
rndRawPw :: Double -> Sig -> SE Sig
rndRawPw duty = rndOscBy (pwTab duty)
urawTri :: Sig -> Sig
urawTri = uoscBy triTab
urawSaw :: Sig -> Sig
urawSaw = uoscBy sawTab
urawSqr :: Sig -> Sig
urawSqr = uoscBy sqrTab
urawPw :: Double -> Sig -> Sig
urawPw duty = uoscBy (pwTab duty)
urawTri' :: D -> Sig -> Sig
urawTri' = uoscBy' triTab
urawSaw' :: D -> Sig -> Sig
urawSaw' = uoscBy' sawTab
urawSqr' :: D -> Sig -> Sig
urawSqr' = uoscBy' sqrTab
urawPw' :: Double -> D -> Sig -> Sig
urawPw' duty = uoscBy' (pwTab duty)
urndRawTri :: Sig -> SE Sig
urndRawTri = urndOscBy triTab
urndRawSaw :: Sig -> SE Sig
urndRawSaw = urndOscBy sawTab
urndRawSqr :: Sig -> SE Sig
urndRawSqr = urndOscBy sqrTab
urndRawPw :: Double -> Sig -> SE Sig
urndRawPw duty = urndOscBy (pwTab duty)