-- | csound instruments
module Orchestra
where
import CsoundExpr.Base
import qualified CsoundExpr.Opcodes as C
import Temporal.Music.Notation
import Temporal.Music.Notation.Local.Western
type Score' = Score NoteW
type CsdNote = (Amp, Cps)
type Amp = Irate
type Cps = Irate
-- | converts note representation to csound values
absCsdNote :: NoteW -> CsdNote
absCsdNote x = (double amp, double cps)
where (amp, cps) = absNote x
-- | converts note representation to csound values
absCsdDrum :: DrumW-> Amp
absCsdDrum = double . absDrum
ftsin = gen10 8192 [1]
-- csound instruments
bassDrum :: (Irate, Irate) -> SignalOut
bassDrum (amp, pch) = C.out $ C.oscilA [] env cps ftsin
where env = amp ^* C.exponA 1 0.2 0.001
cps = C.exponK pch 0.2 20
openHiHat :: Irate -> SignalOut
openHiHat amp = C.out $ C.buthp [] sig (num 7000)
where sig = fst $ se1 $ C.noise env (num 0)
env = amp ^* C.exponA 1 1.5 0.001
pluckInstr :: (Irate, Irate) -> SignalOut
pluckInstr (amp, pch) = outList [
C.out $ env <*> C.wgpluck2 0.75 amp pch (num 0.75) (num 0.5),
C.xtratim 1]
where env = C.linsegrK [0, idur * 0.05, 1, idur * 0.9, 1] 1 0
pipeOrgan :: CsdNote -> SignalOut
pipeOrgan (amp, cps) = C.out sig
where ft = ftsin
outch1 = num 1
outch2 = num 2
atk = num 10
op1f = cps
op2f = 2.01 * cps
op3f = 3.99 * cps
op4f = 8 * cps
op5f = 0.5 * cps
op7f = 16 * cps
dclick = C.linsegK [0, 0.001, amp, idur-0.002, amp, 0.001, 0]
amp1 = C.linsegK [0, 0.01, 1, idur-0.02, 1, 0.01, 0]
amp2 = C.linsegK [0, 0.05, 1, 0.1, 0.7, idur-0.16, 0.7, 0.01, 0]
amp3 = C.linsegK [0, 0.03, 0.8, 0.05, 0, 0.01, 0]
amp4 = C.linsegK [0, 0.1, 0.3, 0.1, 0.05, idur-0.3, 0.1, 0.1, 0]
op8 = C.oscilA [] amp4 op5f ft
p1 = op8 + 1
op1 = C.oscilA [] amp1 (op1f ^* p1) ft
op2 = C.oscilA [] amp2 (op2f ^* p1) ft
op3 = C.oscilA [] amp2 (op3f) ft
op4 = C.oscilA [] amp2 (op4f) ft
op5 = C.oscilA [] amp3 (op5f * 5) ft
op7 = C.oscilA [] amp2 (op7f) ft
sig = (dclick <*>) $ op1 + op2 + op3 + op3 + op4 + op5 + op7
-- instruments on notes
--
bassDrum', pipeOrgan', guitar :: Score NoteW -> Score SignalOut
openHiHat' :: Score DrumW -> Score SignalOut
bassDrum' = fmap (bassDrum . absCsdNote) . setDiapason (1e3, 1.5 * 1e4)
openHiHat' = fmap (openHiHat . absCsdDrum) . setDiapason (1e3, 1.0 * 1e4)
pipeOrgan' = fmap (pipeOrgan . absCsdNote) . setDiapason (1e2, 5*1e3)
guitar = fmap (pluckInstr . absCsdNote). setDiapason (1000, 1.5*1e4)
. lower 1