packages feed

csound-expression-0.3.1: examples/Orchestra.hs

-- | csound instruments
module Orchestra
where

import CsoundExpr.Base
import qualified CsoundExpr.Opcodes as C

import Temporal.Music.Notation
import Temporal.Music.Western  
import Temporal.Music.Western.TwelveTone 


type ScoreN = Score (NoteW Chromatic ())
type ScoreD = Score (DrumW ())

type CsdNote = (Amp, Cps)

type Amp = Irate
type Cps = Irate

-- | converts note representation to csound values
absCsdNote :: Seg a => NoteW a b -> CsdNote
absCsdNote x = (double amp, double cps)
    where (amp, cps) = absNote x

-- | converts note representation to csound values
absCsdDrum :: DrumW a -> 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 :: ScoreN -> Score SignalOut 
openHiHat' :: ScoreD -> 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