{-# LANGUAGE NoMonomorphismRestriction #-}
-- | Module defines two musical structures 'Note' and 'Drum' and provides
-- constructor-shortcuts for them. Value of type 'Note' contains
-- pitch and volume. Value of type 'Drum' is just 'Volume'
module Temporal.Music.Notation.Note(
-- * Types
Note(..), absNote, Drum(..), absDrum,
-- * Shortcuts
-- | Shortcuts for rests, notes and drums construction.
-- Naming conventions : name has two parts, first describes duration of
-- resulting score and second describes that result is rest, note or
-- drum note.
--
-- For name @xy@
--
-- First part @x@ can be [b | w | h | q | e | s | t | d[x] ]
--
-- @b@ means brewis (duration is 2)
--
-- @w@ means whole (duration is 1)
--
-- @h@ means half (duration is 1/2)
--
-- @q@ means quater (duration is 1/4)
--
-- @e@ means eighth (duration is 1/8)
--
-- @s@ means sixteenth (duration is 1/16)
--
-- @t@ means thirty second (duration is 1/32)
--
-- @d[x]@ means dotted [x] (stretch 1.5 $ x)
--
-- Second part @y@ can be [nr | n | d]
--
-- @nr@ means rest
--
-- @n@ means result contains 'Note'
--
-- @d@ means result contains 'Drum'
-- ** Rests
bnr, wnr, hnr, qnr, enr, snr, tnr,
dbnr, dwnr, dhnr, dqnr, denr, dsnr, dtnr,
-- ** Notes
--
-- | It is assumed here that for 'Note' most important information is
-- tone and shortcuts construct 'Note' values from 'Tone' 's,
-- other values are set to default values. It means that scale is
-- equaly tempered, bend is set to zero, volume level is set to
-- mediumLevel,
-- accent is set to zero and volume diapason is set to interval (1e-5, 1).
--
bn, wn, hn, qn, en, sn, tn,
dbn, dwn, dhn, dqn, den, dsn, dtn,
-- ** Drums
--
-- | It is assumed here that for 'Drum' most important information is
-- accent and shortcuts construct 'Drum' from 'Accent' 's, other
-- parameters are set to default values. It means that volume level
-- is mediumLevel and volume diapason is (1e-5, 1)
bd, wd, hd, qd, ed, sd, td,
dbd, dwd, dhd, dqd, ded, dsd, dtd
)
where
import Temporal.Music.Notation.Seg
import Temporal.Music.Notation.Pitch
import Temporal.Music.Notation.Volume
import Temporal.Music.Notation.Score (Dur, Score, note, rest, dot)
import Temporal.Music.Notation.Scales(eqts)
-- Note
-- | Value of type 'Note' contains pitch, volume and some specific
-- timbre information.
data Note nVol nPch a = Note
{ noteVolume :: Volume nVol
, notePitch :: Pitch nPch
, noteParam :: Maybe a
} deriving (Show, Eq)
-- volume instances
instance (Seg nVol, Seg nPch)
=> VolumeFunctor (Note nVol nPch a) where
mapVolume f n = n{ noteVolume = f $ noteVolume n }
instance (Seg nVol, Seg nPch)
=> LevelFunctor (Note nVol nPch a) where
mapLevel f n = n{ noteVolume = mapLevel f $ noteVolume n }
-- pitch instances
instance (Seg nVol, Seg nPch)
=> PitchFunctor (Note nVol nPch a) where
mapPitch f n = n{ notePitch = f $ notePitch n }
instance (Seg nVol, Seg nPch)
=> ToneFunctor (Note nVol nPch a) where
mapTone f n = n{ notePitch = mapTone f $ notePitch n }
-- | calculates 'absVolume' and 'absPitch' on notes
absNote :: (Seg nVol, Seg nPch)
=> Note nVol nPch a -> (Amplitude, Frequency)
absNote (Note v p _) = (absVolume v, absPitch p)
-- Drum
-- | Value of type 'Drum' is just 'Volume'.
data Drum n a = Drum
{ drumVolume :: Volume n
, drumParam :: Maybe a
} deriving (Show, Eq)
-- volume instances
instance Seg nVol => VolumeFunctor (Drum nVol a) where
mapVolume f n = n{ drumVolume = f $ drumVolume n }
instance Seg nVol=> LevelFunctor (Drum nVol a) where
mapLevel f n = n{ drumVolume = mapLevel f $ drumVolume n }
-- | synonym for 'absVolume'
absDrum :: (Seg nVol)
=> Drum nVol a -> Amplitude
absDrum = absVolume . drumVolume
-- shortcuts
-- notes
n :: (Vol nVol, Pch nPch)
=> Dur -> Tone nPch -> Score (Note nVol nPch a)
n dt t = note dt $ Note (volume mediumLevel) (pitch t) Nothing
bn, wn, hn, en, sn, tn, dbn, dwn, dhn, den, dsn, dtn ::
(Vol nVol, Pch nPch)
=> Tone nPch -> Score (Note nVol nPch a)
bn = n 2
wn = n 1
hn = n 0.5
qn = n 0.25
en = n 0.125
sn = n 0.0625
tn = n 0.03125
dbn = dot . bn
dwn = dot . wn
dhn = dot . hn
dqn = dot . qn
den = dot . en
dsn = dot . sn
dtn = dot . tn
-- drums
d :: (Vol nVol)
=> Dur -> Accent -> Score (Drum nVol a)
d dt a = note dt $ Drum (setAccent a $ volume mediumLevel) Nothing
bd, wd, hd, ed, sd, td, dbd, dwd, dhd, ded, dsd, dtd ::
(Vol nVol)
=> Accent -> Score (Drum nVol a)
bd = d 2
wd = d 1
hd = d 0.5
qd = d 0.25
ed = d 0.125
sd = d 0.0625
td = d 0.03125
dbd = dot . bd
dwd = dot . wd
dhd = dot . hd
dqd = dot . qd
ded = dot . ed
dsd = dot . sd
dtd = dot . td
-- rests
--
bnr, wnr, hnr, qnr, enr, snr, tnr,
dbnr, dwnr, dhnr, dqnr, denr, dsnr, dtnr :: Score a
bnr = rest 2
wnr = rest 1
hnr = rest 0.5
qnr = rest 0.25
enr = rest 0.125
snr = rest 0.0625
tnr = rest 0.03125
dbnr = dot $ bnr
dwnr = dot $ wnr
dhnr = dot $ hnr
dqnr = dot $ qnr
denr = dot $ enr
dsnr = dot $ snr
dtnr = dot $ tnr