{-# Language FlexibleContexts #-} -- | Names specific to western music tradition module Temporal.Music.Western( -- * Basic functions -- | All basic functions (composition, time stretching, -- dynamic changing of volume and pitch etc, etc) live in this module. module Temporal.Music, -- * Volume -- | Dynamics values form 9-level equally spaced grid. -- They are from quietest -- to loudest: piano pianissimo (ppp), pianissimo (pp), piano (p), -- mezzo piano (mp), mezzo forte (mf), forte (f), fortissimo (ff), -- forte fortissimo (fff). -- These modifiers change level relative to the current level. -- It means that -- -- > piano . forte = id pppiano, ppiano, piano, mpiano, mforte, forte, fforte, ffforte, -- ** Shortcuts to set dynamics level. ppp', pp', p', mp', mf', f', ff', fff', -- ** Envelops dim, cresc, -- * Score rondo, reprise, -- * Tempo -- | Tempo terms specify not a rigid value but tempo range. So all -- terms are functions from relative power of term (it's value -- of type Double from 0 to 1) to some tempo value. Zero means -- the lowest value from tempo range and one means the highest value. -- To be used with 'bpm' function. Tempo, lento, largo, larghetto, grave, adagio, adagietto, andante, andantino, moderato, allegretto, allegro, vivace, presto, prestissimo ) where import Temporal.Music pppiano, ppiano, piano, mpiano, mforte, forte, fforte, ffforte :: (VolumeLike a) => Score a -> Score a pppiano = quieter 4; ppiano = quieter 3; piano = quieter 2 mpiano = quieter 1; mforte = louder 1; forte = louder 2; fforte = louder 3; ffforte = louder 4; ppp', pp', p', mp', mf', f', ff', fff' :: (VolumeLike a) => Score a -> Score a ppp' = pppiano; pp' = ppiano; p' = piano; mp' = mpiano; mf' = mforte; f' = forte; ff' = fforte; fff' = ffforte; -- | diminuendo dim :: VolumeLike a => Accent -> Score a -> Score a dim = envelope . (*) . negate -- | crescendo cresc :: VolumeLike a => Accent -> Score a -> Score a cresc = envelope . (*) --------------------------------------- -- forms -- | rondo form -- -- >rondo a b c = line [a, b, a, c, a] rondo :: Score a -> Score a -> Score a -> Score a rondo a b c = line [a, b, a, c, a] -- | reprise form -- -- >reprise a b1 b2 = line [a, b1, a, b2] reprise :: Score a -> Score a -> Score a -> Score a reprise a b c = line [a, b, a, c] --------------------------------------- -- tempo type Tempo = Double largoRange, larghettoRange, adagioRange, adagiettoRange, andanteRange, andantinoRange, moderatoRange, allegroRange, allegrettoRange, vivaceRange, prestoRange, prestissimoRange :: (Double, Double) largoRange = ( 40, 60) larghettoRange = ( 60, 66) adagioRange = ( 66, 76) adagiettoRange = ( 70, 80) andanteRange = ( 76, 80) andantinoRange = ( 80,100) moderatoRange = (101,110) allegrettoRange = (115,125) allegroRange = (120,139) vivaceRange = (135,160) prestoRange = (168,200) prestissimoRange = (200,230) getTempo :: (Tempo, Tempo) -> Double -> Tempo getTempo (a, b) x = a + (b - a) * x -- | very slow (40-60 bpm), like largo lento :: Double -> Tempo lento = largo -- | very slow (40-60 bpm) largo :: Double -> Tempo largo = getTempo largoRange -- | rather broadly (60-66 bpm) larghetto :: Double -> Tempo larghetto = getTempo larghettoRange -- | slow and sloemn (60 - 66 bpm) grave :: Double -> Tempo grave = larghetto -- | slow and stately (literally "at ease") (66-76 bpm) adagio :: Double -> Tempo adagio = getTempo adagioRange -- | rather slow (70-80 bpm) adagietto :: Double -> Tempo adagietto = getTempo adagiettoRange -- | at awalking pace (76-80 bpm) andante :: Double -> Tempo andante = getTempo andanteRange -- | slightly faster then andante (80-100 bpm) andantino :: Double -> Tempo andantino = getTempo andantinoRange -- | moderately (101-110 bpm) moderato :: Double -> Tempo moderato = getTempo moderatoRange -- | moderately fast (115-125 bpm) allegretto :: Double -> Tempo allegretto = getTempo allegrettoRange -- | fast, at 'march tempo' (120-139 bpm) allegro :: Double -> Tempo allegro = getTempo allegroRange -- | lively and fast (135-160 bpm) vivace :: Double -> Tempo vivace = getTempo vivaceRange -- | very fast (168-200 bpm) presto :: Double -> Tempo presto = getTempo prestoRange -- | extremely fast (200 - 230 bpm) prestissimo :: Double -> Tempo prestissimo = getTempo prestissimoRange