{-# LANGUAGE TemplateHaskell #-} ----------------------------------------------------------------------------- -- | -- Module : Mezzo.Compose.Basic -- Description : Basic composition units -- Copyright : (c) Dima Szamozvancev -- License : MIT -- -- Maintainer : ds709@cam.ac.uk -- Stability : experimental -- Portability : portable -- -- Literals for pitches, notes, durations, etc. -- ----------------------------------------------------------------------------- module Mezzo.Compose.Basic where import GHC.TypeLits import Data.Kind import Control.Monad import Mezzo.Model import Mezzo.Compose.Types import Mezzo.Compose.Builder import Mezzo.Compose.Templates -- * Atomic literals -- ** Pitch class literals pitchClassLits -- ** Accidental literals accidentalLits -- ** Octave literals octaveLits -- ** Duration literals and terminators mk32ndLits join <$> traverse mkDurLits [''Whole, ''Half, ''Quarter, ''Eighth, ''Sixteenth] -- * Pitches -- ** Constructor -- | Create a new pitch with the given class, accidental and octave. pitch :: Primitive (Pitch pc acc oct) => PC pc -> Acc acc -> Oct oct -> Pit (Pitch pc acc oct) pitch pc acc oct = Pit -- | Value representing silence, the "pitch" of rests. silence :: Pit Silence silence = Pit -- ** Concrete literals mkPitchLits -- ** Pitch specifiers (admitting continuations) mkPitchSpecs r :: RestS r dur = dur Pit -- | Raise a pitch by a semitone. sharp :: RootM r (Sharpen r) sharp = constConv Root -- | Lower a pitch by a semitone. flat :: RootM r (Flatten r) flat = constConv Root -- * Notes -- ** Constructors -- | Create a new root from a pitch. rootP :: IntRep p => Pit p -> Root (PitchRoot p) rootP p = Root -- | Create a new root from a key and a scale degree. rootS :: Primitive (DegreeRoot k d) => KeyS k -> Deg d -> Root (DegreeRoot k d) rootS k d = Root -- | Create a new note from a root and duration. noteP :: (Primitive d, IntRep p, ValidNote s (PitchRoot p) d) => Pit p -> Dur d -> Music s (FromRoot (PitchRoot p) d) noteP p = Note (rootP p) noteS :: (Primitive d, IntRep (DegreeRoot k sd), ValidNote (Sig :: Signature t k r) (DegreeRoot k sd) d) => KeyS k -> Deg sd -> Dur d -> Music (Sig :: Signature t k r) (FromRoot (DegreeRoot k sd) d) noteS k sd = Note (rootS k sd) -- | Create a rest from a duration. rest :: (Primitive d, ValidRest s d) => Dur d -> Music s (FromSilence d) rest = Rest