- exmpEventList :: EventList Double Irate
- exmpScore :: Score String
- exmpScoFunctor :: MediaUnit Dur () SignalOut
- exmpScoMonad :: MediaUnit Dur () Irate
- exmpScoTemporal :: Dur
- exmpScoStretchable :: MediaUnit Dur () Irate
- exmpScoArrangeable :: Score String
- exmpScoTemporalFunctor :: Score SignalOut
- main :: IO ()
Score is tree structure that represents music. Lists contain notes and nodes
contain information about how subtrees relate to each other in time.
Subtrees can be sequential or parallel.
csd function takes in
Double is type of time-marks.
Score is a Functor, Monad, Temporal, Stretchable, Arrangeable and TemporalFunctor
It makes possible to represent csound's instrument as
a function from note representation to
To play on instrument means to apply instrument to
of its notes.
-- oscillator instrument instr :: Irate -> SignalOut instr x = out $ oscilA  (num 1000) (cpspch x) $ gen10 4096  exmpScoFunctor = fmap instr $ line $ map (note 1) [d 0, f 0, a 0, d 1]
Gives way to more structured composition.
return a makes note of
a that lasts for 1 sec.
ma >>= f is better understood by its
ma >>= f = joinScore $ fmap f ma joinScore :: Score (Score a) -> Score a
is a tree. Nodes represent sequent/parallel
composition and leaves represent value
a or rest that lasts
for some time
joinScore takes in
Score that contains some more
Score 's in its leaves, and builds one tree by substituting
values of Scores by Scores. Note that while substituting it stretches
Score by duration of value.
type ChordType = [Irate] majC, minC :: ChordType majC = [0, 0.04, 0.07] -- in csound 0.01 is one half-tone minC = [0, 0.03, 0.07] arpeggi :: (Irate, ChordType) -> Score Irate arpeggi baseNote chordType = line $ map return (pchs ++ pchs) where pchs = map ((+ baseNote) . (chordType !! )) [0, 1, 2, 1, 2, 1] harmony = line $ map return [(e 0, minC), (a (-1), minC), (d 0, majC), (g 0, majC), (c 0, majC), (f 0, minC), (b (-1), majC), (e 0, minC)] sco = harmony >>= arpeggi
There are two methods defined on
none :: Dur -> a -- construct rest dur :: a -> Dur -- ask for duration
Stretching things in time domain with
stretch :: Dur -> a -> a
Constructing things in sequent '(+:+)' and parallel ways '(=:=)'
There is class called
TemporalFunctor with method
First argument of tmap's function means function from duration
t and value itself
a to new value
class Dur t => TemporalFunctor f where tmap :: (t -> a -> b) -> f a -> f b
It allows to construct instruments that can rely on note duration.
instr :: Dur -> Irate -> SignalOut instr t vol = out $ (env t <*> ) $ fst $ se1 $ unirandA vol where env t | t < 1 = lineK 1 idur 0 | otherwise = exponK 1 idur 0 v1 = 1.5 * v0 v0 = 5000 sco = tmap instr $ line [note 0.5 v1, note 0.5 v0, rest 1, note 2 v1]
stretch t (tmap instr sco) =/= tmap instr (stretch t sco)
radiohead - weird fishes (intro), see src