- 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 methods for time/duration dependent mapping.
There are methods
tmap - for time dependent mapping,
dmap - for duration dependent mapping and
tdmap - for time/duration dependent mapping.
class Dur t => TemporalFunctor f where tmap :: (t -> a -> b) -> f a -> f b dmap :: (t -> a -> b) -> f a -> f b tdmap :: (t -> t -> a -> b) -> f a -> f b
Score can be thought of as an event that happens in some time
and lasts for some time
d. Thus note carries three parametters value
a, start time
and duration time
TemporalFunctor provides different mappings over time parameters.
First argument of
tmap function means function from start time of
note and note's value
a to new value
example : fadeOut
instr :: Irate -> SignalOut instr vol = out $ oscilA  vol (num 440) $ gen10 4096  sco = fmap instr $ tmap (\t v -> double (5 - t) * v) $ loop 5 $ note 1 1000
First argument of dmap's function means function from duration
t and value itself
a to new value
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 = dmap instr $ line [note 0.5 v1, note 0.5 v0, rest 1, note 2 v1]
stretch t (dmap instr sco) =/= dmap instr (stretch t sco)
sco of fadeOut example can be rewritten as
sco = fmap instr $ tmapRel (\t v -> double (1 - t) * v ) $ loop 5 $ note 1 5000
radiohead - weird fishes (intro), see src