mezzo 0.3.0.0 → 0.3.1.0
raw patch · 12 files changed
+186/−57 lines, 12 filesdep +EuterpeaPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: Euterpea
API changes (from Hackage documentation)
- Mezzo.Compose.Combine: play :: (Primitive d) => Melody s m d -> Music s m
+ Mezzo.Compose.Combine: start :: (Primitive d) => Melody s m d -> Music s m
+ Mezzo.Compose.Harmony: end :: InKey k (PhraseList (CadPhrase NoCad))
+ Mezzo.Model.Harmony.Functional: [NoCad] :: Cadence k 0
+ Mezzo.Model.Harmony.Functional: instance Mezzo.Model.Reify.Primitive 'Mezzo.Model.Harmony.Functional.NoCad
+ Mezzo.Render.MIDI: (><) :: MidiTrack -> MidiTrack -> MidiTrack
+ Mezzo.Render.MIDI: MidiNote :: Int -> Velocity -> Ticks -> Ticks -> MidiNote
+ Mezzo.Render.MIDI: [noteDur] :: MidiNote -> Ticks
+ Mezzo.Render.MIDI: [noteNum] :: MidiNote -> Int
+ Mezzo.Render.MIDI: [startT] :: MidiNote -> Ticks
+ Mezzo.Render.MIDI: [vel] :: MidiNote -> Velocity
+ Mezzo.Render.MIDI: data MidiNote
+ Mezzo.Render.MIDI: playLive :: Music (Sig :: Signature 4 (Key C Natural MajorMode) Classical) m -> IO ()
+ Mezzo.Render.MIDI: playLive' :: Score -> IO ()
+ Mezzo.Render.MIDI: type Score = MidiTrack
+ Mezzo.Render.Transform: (+++) :: Score -> Score -> Score
+ Mezzo.Render.Transform: (><) :: MidiTrack -> MidiTrack -> MidiTrack
+ Mezzo.Render.Transform: cascade :: Int -> (Score -> Score) -> Score -> Score
+ Mezzo.Render.Transform: delay :: Ticks -> Score -> Score
+ Mezzo.Render.Transform: flatten :: [Score] -> Score
+ Mezzo.Render.Transform: reprise :: Int -> Score -> Score
+ Mezzo.Render.Transform: scale :: Int -> Int -> Score -> Score
+ Mezzo.Render.Transform: transpose :: Int -> Score -> Score
+ Mezzo.Render.Transform: volta :: Score -> [Score] -> Score
- Mezzo.Compose.Basic: ec :: forall n_aR9C r_aR9D s_aR9E. (Primitive n_aR9C, IntListRep r_aR9D, ValidChord s_aR9E r_aR9D Eighth) => ChorT s_aR9E (r_aR9D :: ChordType n_aR9C) Eighth
+ Mezzo.Compose.Basic: ec :: forall n_aRDf r_aRDg s_aRDh. (Primitive n_aRDf, IntListRep r_aRDg, ValidChord s_aRDh r_aRDg Eighth) => ChorT s_aRDh (r_aRDg :: ChordType n_aRDf) Eighth
- Mezzo.Compose.Basic: ec' :: forall n_aR9G r_aR9H s_aR9I. (Primitive n_aR9G, IntListRep r_aR9H, ValidChord s_aR9I r_aR9H (Dot Eighth)) => ChorT s_aR9I (r_aR9H :: ChordType n_aR9G) (Dot Eighth)
+ Mezzo.Compose.Basic: ec' :: forall n_aRDj r_aRDk s_aRDl. (Primitive n_aRDj, IntListRep r_aRDk, ValidChord s_aRDl r_aRDk (Dot Eighth)) => ChorT s_aRDl (r_aRDk :: ChordType n_aRDj) (Dot Eighth)
- Mezzo.Compose.Basic: en :: forall r_aR9u s_aR9v. (ValidNote s_aR9v r_aR9u Eighth, IntRep r_aR9u) => RootT s_aR9v r_aR9u Eighth
+ Mezzo.Compose.Basic: en :: forall r_aRD7 s_aRD8. (ValidNote s_aRD8 r_aRD7 Eighth, IntRep r_aRD7) => RootT s_aRD8 r_aRD7 Eighth
- Mezzo.Compose.Basic: en' :: forall r_aR9x s_aR9y. (ValidNote s_aR9y r_aR9x (Dot Eighth), IntRep r_aR9x) => RootT s_aR9y r_aR9x (Dot Eighth)
+ Mezzo.Compose.Basic: en' :: forall r_aRDa s_aRDb. (ValidNote s_aRDb r_aRDa (Dot Eighth), IntRep r_aRDa) => RootT s_aRDb r_aRDa (Dot Eighth)
- Mezzo.Compose.Basic: er :: forall s_aR9A. ValidRest s_aR9A Eighth => RestT s_aR9A Eighth
+ Mezzo.Compose.Basic: er :: forall s_aRDd. ValidRest s_aRDd Eighth => RestT s_aRDd Eighth
- Mezzo.Compose.Basic: er' :: forall s_aR9B. ValidRest s_aR9B (Dot Eighth) => RestT s_aR9B (Dot Eighth)
+ Mezzo.Compose.Basic: er' :: forall s_aRDe. ValidRest s_aRDe (Dot Eighth) => RestT s_aRDe (Dot Eighth)
- Mezzo.Compose.Basic: hc :: forall n_aR96 r_aR97 s_aR98. (Primitive n_aR96, IntListRep r_aR97, ValidChord s_aR98 r_aR97 Half) => ChorT s_aR98 (r_aR97 :: ChordType n_aR96) Half
+ Mezzo.Compose.Basic: hc :: forall n_aRCJ r_aRCK s_aRCL. (Primitive n_aRCJ, IntListRep r_aRCK, ValidChord s_aRCL r_aRCK Half) => ChorT s_aRCL (r_aRCK :: ChordType n_aRCJ) Half
- Mezzo.Compose.Basic: hc' :: forall n_aR9a r_aR9b s_aR9c. (Primitive n_aR9a, IntListRep r_aR9b, ValidChord s_aR9c r_aR9b (Dot Half)) => ChorT s_aR9c (r_aR9b :: ChordType n_aR9a) (Dot Half)
+ Mezzo.Compose.Basic: hc' :: forall n_aRCN r_aRCO s_aRCP. (Primitive n_aRCN, IntListRep r_aRCO, ValidChord s_aRCP r_aRCO (Dot Half)) => ChorT s_aRCP (r_aRCO :: ChordType n_aRCN) (Dot Half)
- Mezzo.Compose.Basic: hn :: forall r_aR8Y s_aR8Z. (ValidNote s_aR8Z r_aR8Y Half, IntRep r_aR8Y) => RootT s_aR8Z r_aR8Y Half
+ Mezzo.Compose.Basic: hn :: forall r_aRCB s_aRCC. (ValidNote s_aRCC r_aRCB Half, IntRep r_aRCB) => RootT s_aRCC r_aRCB Half
- Mezzo.Compose.Basic: hn' :: forall r_aR91 s_aR92. (ValidNote s_aR92 r_aR91 (Dot Half), IntRep r_aR91) => RootT s_aR92 r_aR91 (Dot Half)
+ Mezzo.Compose.Basic: hn' :: forall r_aRCE s_aRCF. (ValidNote s_aRCF r_aRCE (Dot Half), IntRep r_aRCE) => RootT s_aRCF r_aRCE (Dot Half)
- Mezzo.Compose.Basic: hr :: forall s_aR94. ValidRest s_aR94 Half => RestT s_aR94 Half
+ Mezzo.Compose.Basic: hr :: forall s_aRCH. ValidRest s_aRCH Half => RestT s_aRCH Half
- Mezzo.Compose.Basic: hr' :: forall s_aR95. ValidRest s_aR95 (Dot Half) => RestT s_aR95 (Dot Half)
+ Mezzo.Compose.Basic: hr' :: forall s_aRCI. ValidRest s_aRCI (Dot Half) => RestT s_aRCI (Dot Half)
- Mezzo.Compose.Basic: qc :: forall n_aR9m r_aR9n s_aR9o. (Primitive n_aR9m, IntListRep r_aR9n, ValidChord s_aR9o r_aR9n Quarter) => ChorT s_aR9o (r_aR9n :: ChordType n_aR9m) Quarter
+ Mezzo.Compose.Basic: qc :: forall n_aRCZ r_aRD0 s_aRD1. (Primitive n_aRCZ, IntListRep r_aRD0, ValidChord s_aRD1 r_aRD0 Quarter) => ChorT s_aRD1 (r_aRD0 :: ChordType n_aRCZ) Quarter
- Mezzo.Compose.Basic: qc' :: forall n_aR9q r_aR9r s_aR9s. (Primitive n_aR9q, IntListRep r_aR9r, ValidChord s_aR9s r_aR9r (Dot Quarter)) => ChorT s_aR9s (r_aR9r :: ChordType n_aR9q) (Dot Quarter)
+ Mezzo.Compose.Basic: qc' :: forall n_aRD3 r_aRD4 s_aRD5. (Primitive n_aRD3, IntListRep r_aRD4, ValidChord s_aRD5 r_aRD4 (Dot Quarter)) => ChorT s_aRD5 (r_aRD4 :: ChordType n_aRD3) (Dot Quarter)
- Mezzo.Compose.Basic: qn :: forall r_aR9e s_aR9f. (ValidNote s_aR9f r_aR9e Quarter, IntRep r_aR9e) => RootT s_aR9f r_aR9e Quarter
+ Mezzo.Compose.Basic: qn :: forall r_aRCR s_aRCS. (ValidNote s_aRCS r_aRCR Quarter, IntRep r_aRCR) => RootT s_aRCS r_aRCR Quarter
- Mezzo.Compose.Basic: qn' :: forall r_aR9h s_aR9i. (ValidNote s_aR9i r_aR9h (Dot Quarter), IntRep r_aR9h) => RootT s_aR9i r_aR9h (Dot Quarter)
+ Mezzo.Compose.Basic: qn' :: forall r_aRCU s_aRCV. (ValidNote s_aRCV r_aRCU (Dot Quarter), IntRep r_aRCU) => RootT s_aRCV r_aRCU (Dot Quarter)
- Mezzo.Compose.Basic: qr :: forall s_aR9k. ValidRest s_aR9k Quarter => RestT s_aR9k Quarter
+ Mezzo.Compose.Basic: qr :: forall s_aRCX. ValidRest s_aRCX Quarter => RestT s_aRCX Quarter
- Mezzo.Compose.Basic: qr' :: forall s_aR9l. ValidRest s_aR9l (Dot Quarter) => RestT s_aR9l (Dot Quarter)
+ Mezzo.Compose.Basic: qr' :: forall s_aRCY. ValidRest s_aRCY (Dot Quarter) => RestT s_aRCY (Dot Quarter)
- Mezzo.Compose.Basic: sc :: forall n_aR9S r_aR9T s_aR9U. (Primitive n_aR9S, IntListRep r_aR9T, ValidChord s_aR9U r_aR9T Sixteenth) => ChorT s_aR9U (r_aR9T :: ChordType n_aR9S) Sixteenth
+ Mezzo.Compose.Basic: sc :: forall n_aRDv r_aRDw s_aRDx. (Primitive n_aRDv, IntListRep r_aRDw, ValidChord s_aRDx r_aRDw Sixteenth) => ChorT s_aRDx (r_aRDw :: ChordType n_aRDv) Sixteenth
- Mezzo.Compose.Basic: sc' :: forall n_aR9W r_aR9X s_aR9Y. (Primitive n_aR9W, IntListRep r_aR9X, ValidChord s_aR9Y r_aR9X (Dot Sixteenth)) => ChorT s_aR9Y (r_aR9X :: ChordType n_aR9W) (Dot Sixteenth)
+ Mezzo.Compose.Basic: sc' :: forall n_aRDz r_aRDA s_aRDB. (Primitive n_aRDz, IntListRep r_aRDA, ValidChord s_aRDB r_aRDA (Dot Sixteenth)) => ChorT s_aRDB (r_aRDA :: ChordType n_aRDz) (Dot Sixteenth)
- Mezzo.Compose.Basic: sn :: forall r_aR9K s_aR9L. (ValidNote s_aR9L r_aR9K Sixteenth, IntRep r_aR9K) => RootT s_aR9L r_aR9K Sixteenth
+ Mezzo.Compose.Basic: sn :: forall r_aRDn s_aRDo. (ValidNote s_aRDo r_aRDn Sixteenth, IntRep r_aRDn) => RootT s_aRDo r_aRDn Sixteenth
- Mezzo.Compose.Basic: sn' :: forall r_aR9N s_aR9O. (ValidNote s_aR9O r_aR9N (Dot Sixteenth), IntRep r_aR9N) => RootT s_aR9O r_aR9N (Dot Sixteenth)
+ Mezzo.Compose.Basic: sn' :: forall r_aRDq s_aRDr. (ValidNote s_aRDr r_aRDq (Dot Sixteenth), IntRep r_aRDq) => RootT s_aRDr r_aRDq (Dot Sixteenth)
- Mezzo.Compose.Basic: sr :: forall s_aR9Q. ValidRest s_aR9Q Sixteenth => RestT s_aR9Q Sixteenth
+ Mezzo.Compose.Basic: sr :: forall s_aRDt. ValidRest s_aRDt Sixteenth => RestT s_aRDt Sixteenth
- Mezzo.Compose.Basic: sr' :: forall s_aR9R. ValidRest s_aR9R (Dot Sixteenth) => RestT s_aR9R (Dot Sixteenth)
+ Mezzo.Compose.Basic: sr' :: forall s_aRDu. ValidRest s_aRDu (Dot Sixteenth) => RestT s_aRDu (Dot Sixteenth)
- Mezzo.Compose.Basic: tc :: forall n_aR4q r_aR4r s_aR4s. (Primitive n_aR4q, IntListRep r_aR4r, ValidChord s_aR4s r_aR4r ThirtySecond) => ChorT s_aR4s (r_aR4r :: ChordType n_aR4q) ThirtySecond
+ Mezzo.Compose.Basic: tc :: forall n_aRy3 r_aRy4 s_aRy5. (Primitive n_aRy3, IntListRep r_aRy4, ValidChord s_aRy5 r_aRy4 ThirtySecond) => ChorT s_aRy5 (r_aRy4 :: ChordType n_aRy3) ThirtySecond
- Mezzo.Compose.Basic: tn :: forall r_aR4m s_aR4n. (ValidNote s_aR4n r_aR4m ThirtySecond, IntRep r_aR4m) => RootT s_aR4n r_aR4m ThirtySecond
+ Mezzo.Compose.Basic: tn :: forall r_aRxZ s_aRy0. (ValidNote s_aRy0 r_aRxZ ThirtySecond, IntRep r_aRxZ) => RootT s_aRy0 r_aRxZ ThirtySecond
- Mezzo.Compose.Basic: tr :: forall s_aR4p. ValidRest s_aR4p ThirtySecond => RestT s_aR4p ThirtySecond
+ Mezzo.Compose.Basic: tr :: forall s_aRy2. ValidRest s_aRy2 ThirtySecond => RestT s_aRy2 ThirtySecond
- Mezzo.Compose.Basic: wc :: forall n_aR8Q r_aR8R s_aR8S. (Primitive n_aR8Q, IntListRep r_aR8R, ValidChord s_aR8S r_aR8R Whole) => ChorT s_aR8S (r_aR8R :: ChordType n_aR8Q) Whole
+ Mezzo.Compose.Basic: wc :: forall n_aRCt r_aRCu s_aRCv. (Primitive n_aRCt, IntListRep r_aRCu, ValidChord s_aRCv r_aRCu Whole) => ChorT s_aRCv (r_aRCu :: ChordType n_aRCt) Whole
- Mezzo.Compose.Basic: wc' :: forall n_aR8U r_aR8V s_aR8W. (Primitive n_aR8U, IntListRep r_aR8V, ValidChord s_aR8W r_aR8V (Dot Whole)) => ChorT s_aR8W (r_aR8V :: ChordType n_aR8U) (Dot Whole)
+ Mezzo.Compose.Basic: wc' :: forall n_aRCx r_aRCy s_aRCz. (Primitive n_aRCx, IntListRep r_aRCy, ValidChord s_aRCz r_aRCy (Dot Whole)) => ChorT s_aRCz (r_aRCy :: ChordType n_aRCx) (Dot Whole)
- Mezzo.Compose.Basic: wn :: forall r_aR8I s_aR8J. (ValidNote s_aR8J r_aR8I Whole, IntRep r_aR8I) => RootT s_aR8J r_aR8I Whole
+ Mezzo.Compose.Basic: wn :: forall r_aRCl s_aRCm. (ValidNote s_aRCm r_aRCl Whole, IntRep r_aRCl) => RootT s_aRCm r_aRCl Whole
- Mezzo.Compose.Basic: wn' :: forall r_aR8L s_aR8M. (ValidNote s_aR8M r_aR8L (Dot Whole), IntRep r_aR8L) => RootT s_aR8M r_aR8L (Dot Whole)
+ Mezzo.Compose.Basic: wn' :: forall r_aRCo s_aRCp. (ValidNote s_aRCp r_aRCo (Dot Whole), IntRep r_aRCo) => RootT s_aRCp r_aRCo (Dot Whole)
- Mezzo.Compose.Basic: wr :: forall s_aR8O. ValidRest s_aR8O Whole => RestT s_aR8O Whole
+ Mezzo.Compose.Basic: wr :: forall s_aRCr. ValidRest s_aRCr Whole => RestT s_aRCr Whole
- Mezzo.Compose.Basic: wr' :: forall s_aR8P. ValidRest s_aR8P (Dot Whole) => RestT s_aR8P (Dot Whole)
+ Mezzo.Compose.Basic: wr' :: forall s_aRCs. ValidRest s_aRCs (Dot Whole) => RestT s_aRCs (Dot Whole)
- Mezzo.Compose.Chords: aug :: forall r_aZog. ChorC Triad r_aZog AugTriad
+ Mezzo.Compose.Chords: aug :: forall r_aZRT. ChorC Triad r_aZRT AugTriad
- Mezzo.Compose.Chords: aug' :: forall r_aZod i_aZoe. ChorC' Triad r_aZod AugTriad i_aZoe
+ Mezzo.Compose.Chords: aug' :: forall r_aZRQ i_aZRR. ChorC' Triad r_aZRQ AugTriad i_aZRR
- Mezzo.Compose.Chords: augD :: forall r_aZEr. ChorC Tetrad r_aZEr (DoubledT AugTriad)
+ Mezzo.Compose.Chords: augD :: forall r_a1084. ChorC Tetrad r_a1084 (DoubledT AugTriad)
- Mezzo.Compose.Chords: augD' :: forall r_aZEo i_aZEp. ChorC' Tetrad r_aZEo (DoubledT AugTriad) i_aZEp
+ Mezzo.Compose.Chords: augD' :: forall r_a1081 i_a1082. ChorC' Tetrad r_a1081 (DoubledT AugTriad) i_a1082
- Mezzo.Compose.Chords: dim :: forall r_aZoc. ChorC Triad r_aZoc DimTriad
+ Mezzo.Compose.Chords: dim :: forall r_aZRP. ChorC Triad r_aZRP DimTriad
- Mezzo.Compose.Chords: dim' :: forall r_aZo9 i_aZoa. ChorC' Triad r_aZo9 DimTriad i_aZoa
+ Mezzo.Compose.Chords: dim' :: forall r_aZRM i_aZRN. ChorC' Triad r_aZRM DimTriad i_aZRN
- Mezzo.Compose.Chords: dim7 :: forall r_aZyB. ChorC Tetrad r_aZyB DimSeventh
+ Mezzo.Compose.Chords: dim7 :: forall r_a102e. ChorC Tetrad r_a102e DimSeventh
- Mezzo.Compose.Chords: dim7' :: forall r_aZyy i_aZyz. ChorC' Tetrad r_aZyy DimSeventh i_aZyz
+ Mezzo.Compose.Chords: dim7' :: forall r_a102b i_a102c. ChorC' Tetrad r_a102b DimSeventh i_a102c
- Mezzo.Compose.Chords: dimD :: forall r_aZEn. ChorC Tetrad r_aZEn (DoubledT DimTriad)
+ Mezzo.Compose.Chords: dimD :: forall r_a1080. ChorC Tetrad r_a1080 (DoubledT DimTriad)
- Mezzo.Compose.Chords: dimD' :: forall r_aZEk i_aZEl. ChorC' Tetrad r_aZEk (DoubledT DimTriad) i_aZEl
+ Mezzo.Compose.Chords: dimD' :: forall r_a107X i_a107Y. ChorC' Tetrad r_a107X (DoubledT DimTriad) i_a107Y
- Mezzo.Compose.Chords: dom7 :: forall r_aZyN. ChorC Tetrad r_aZyN MajMinSeventh
+ Mezzo.Compose.Chords: dom7 :: forall r_a102q. ChorC Tetrad r_a102q MajMinSeventh
- Mezzo.Compose.Chords: dom7' :: forall r_aZyK i_aZyL. ChorC' Tetrad r_aZyK MajMinSeventh i_aZyL
+ Mezzo.Compose.Chords: dom7' :: forall r_a102n i_a102o. ChorC' Tetrad r_a102n MajMinSeventh i_a102o
- Mezzo.Compose.Chords: fifth :: forall r_aZiu. ChorC Dyad r_aZiu PerfFifth
+ Mezzo.Compose.Chords: fifth :: forall r_aZM7. ChorC Dyad r_aZM7 PerfFifth
- Mezzo.Compose.Chords: fifth' :: forall r_aZir i_aZis. ChorC' Dyad r_aZir PerfFifth i_aZis
+ Mezzo.Compose.Chords: fifth' :: forall r_aZM4 i_aZM5. ChorC' Dyad r_aZM4 PerfFifth i_aZM5
- Mezzo.Compose.Chords: fifthD :: forall r_aZsT. ChorC Triad r_aZsT (DoubledD PerfFifth)
+ Mezzo.Compose.Chords: fifthD :: forall r_aZWw. ChorC Triad r_aZWw (DoubledD PerfFifth)
- Mezzo.Compose.Chords: fifthD' :: forall r_aZsQ i_aZsR. ChorC' Triad r_aZsQ (DoubledD PerfFifth) i_aZsR
+ Mezzo.Compose.Chords: fifthD' :: forall r_aZWt i_aZWu. ChorC' Triad r_aZWt (DoubledD PerfFifth) i_aZWu
- Mezzo.Compose.Chords: fourth :: forall r_aZiy. ChorC Dyad r_aZiy PerfFourth
+ Mezzo.Compose.Chords: fourth :: forall r_aZMb. ChorC Dyad r_aZMb PerfFourth
- Mezzo.Compose.Chords: fourth' :: forall r_aZiv i_aZiw. ChorC' Dyad r_aZiv PerfFourth i_aZiw
+ Mezzo.Compose.Chords: fourth' :: forall r_aZM8 i_aZM9. ChorC' Dyad r_aZM8 PerfFourth i_aZM9
- Mezzo.Compose.Chords: fourthD :: forall r_aZsX. ChorC Triad r_aZsX (DoubledD PerfFourth)
+ Mezzo.Compose.Chords: fourthD :: forall r_aZWA. ChorC Triad r_aZWA (DoubledD PerfFourth)
- Mezzo.Compose.Chords: fourthD' :: forall r_aZsU i_aZsV. ChorC' Triad r_aZsU (DoubledD PerfFourth) i_aZsV
+ Mezzo.Compose.Chords: fourthD' :: forall r_aZWx i_aZWy. ChorC' Triad r_aZWx (DoubledD PerfFourth) i_aZWy
- Mezzo.Compose.Chords: hdim7 :: forall r_aZyF. ChorC Tetrad r_aZyF HalfDimSeventh
+ Mezzo.Compose.Chords: hdim7 :: forall r_a102i. ChorC Tetrad r_a102i HalfDimSeventh
- Mezzo.Compose.Chords: hdim7' :: forall r_aZyC i_aZyD. ChorC' Tetrad r_aZyC HalfDimSeventh i_aZyD
+ Mezzo.Compose.Chords: hdim7' :: forall r_a102f i_a102g. ChorC' Tetrad r_a102f HalfDimSeventh i_a102g
- Mezzo.Compose.Chords: maj :: forall r_aZoo. ChorC Triad r_aZoo MajTriad
+ Mezzo.Compose.Chords: maj :: forall r_aZS1. ChorC Triad r_aZS1 MajTriad
- Mezzo.Compose.Chords: maj' :: forall r_aZol i_aZom. ChorC' Triad r_aZol MajTriad i_aZom
+ Mezzo.Compose.Chords: maj' :: forall r_aZRY i_aZRZ. ChorC' Triad r_aZRY MajTriad i_aZRZ
- Mezzo.Compose.Chords: maj3 :: forall r_aZiC. ChorC Dyad r_aZiC MajThird
+ Mezzo.Compose.Chords: maj3 :: forall r_aZMf. ChorC Dyad r_aZMf MajThird
- Mezzo.Compose.Chords: maj3' :: forall r_aZiz i_aZiA. ChorC' Dyad r_aZiz MajThird i_aZiA
+ Mezzo.Compose.Chords: maj3' :: forall r_aZMc i_aZMd. ChorC' Dyad r_aZMc MajThird i_aZMd
- Mezzo.Compose.Chords: maj3D :: forall r_aZt1. ChorC Triad r_aZt1 (DoubledD MajThird)
+ Mezzo.Compose.Chords: maj3D :: forall r_aZWE. ChorC Triad r_aZWE (DoubledD MajThird)
- Mezzo.Compose.Chords: maj3D' :: forall r_aZsY i_aZsZ. ChorC' Triad r_aZsY (DoubledD MajThird) i_aZsZ
+ Mezzo.Compose.Chords: maj3D' :: forall r_aZWB i_aZWC. ChorC' Triad r_aZWB (DoubledD MajThird) i_aZWC
- Mezzo.Compose.Chords: maj7 :: forall r_aZyR. ChorC Tetrad r_aZyR MajSeventh
+ Mezzo.Compose.Chords: maj7 :: forall r_a102u. ChorC Tetrad r_a102u MajSeventh
- Mezzo.Compose.Chords: maj7' :: forall r_aZyO i_aZyP. ChorC' Tetrad r_aZyO MajSeventh i_aZyP
+ Mezzo.Compose.Chords: maj7' :: forall r_a102r i_a102s. ChorC' Tetrad r_a102r MajSeventh i_a102s
- Mezzo.Compose.Chords: majD :: forall r_aZEz. ChorC Tetrad r_aZEz (DoubledT MajTriad)
+ Mezzo.Compose.Chords: majD :: forall r_a108c. ChorC Tetrad r_a108c (DoubledT MajTriad)
- Mezzo.Compose.Chords: majD' :: forall r_aZEw i_aZEx. ChorC' Tetrad r_aZEw (DoubledT MajTriad) i_aZEx
+ Mezzo.Compose.Chords: majD' :: forall r_a1089 i_a108a. ChorC' Tetrad r_a1089 (DoubledT MajTriad) i_a108a
- Mezzo.Compose.Chords: min :: forall r_aZok. ChorC Triad r_aZok MinTriad
+ Mezzo.Compose.Chords: min :: forall r_aZRX. ChorC Triad r_aZRX MinTriad
- Mezzo.Compose.Chords: min' :: forall r_aZoh i_aZoi. ChorC' Triad r_aZoh MinTriad i_aZoi
+ Mezzo.Compose.Chords: min' :: forall r_aZRU i_aZRV. ChorC' Triad r_aZRU MinTriad i_aZRV
- Mezzo.Compose.Chords: min3 :: forall r_aZiG. ChorC Dyad r_aZiG MinThird
+ Mezzo.Compose.Chords: min3 :: forall r_aZMj. ChorC Dyad r_aZMj MinThird
- Mezzo.Compose.Chords: min3' :: forall r_aZiD i_aZiE. ChorC' Dyad r_aZiD MinThird i_aZiE
+ Mezzo.Compose.Chords: min3' :: forall r_aZMg i_aZMh. ChorC' Dyad r_aZMg MinThird i_aZMh
- Mezzo.Compose.Chords: min3D :: forall r_aZt5. ChorC Triad r_aZt5 (DoubledD MinThird)
+ Mezzo.Compose.Chords: min3D :: forall r_aZWI. ChorC Triad r_aZWI (DoubledD MinThird)
- Mezzo.Compose.Chords: min3D' :: forall r_aZt2 i_aZt3. ChorC' Triad r_aZt2 (DoubledD MinThird) i_aZt3
+ Mezzo.Compose.Chords: min3D' :: forall r_aZWF i_aZWG. ChorC' Triad r_aZWF (DoubledD MinThird) i_aZWG
- Mezzo.Compose.Chords: min7 :: forall r_aZyJ. ChorC Tetrad r_aZyJ MinSeventh
+ Mezzo.Compose.Chords: min7 :: forall r_a102m. ChorC Tetrad r_a102m MinSeventh
- Mezzo.Compose.Chords: min7' :: forall r_aZyG i_aZyH. ChorC' Tetrad r_aZyG MinSeventh i_aZyH
+ Mezzo.Compose.Chords: min7' :: forall r_a102j i_a102k. ChorC' Tetrad r_a102j MinSeventh i_a102k
- Mezzo.Compose.Chords: minD :: forall r_aZEv. ChorC Tetrad r_aZEv (DoubledT MinTriad)
+ Mezzo.Compose.Chords: minD :: forall r_a1088. ChorC Tetrad r_a1088 (DoubledT MinTriad)
- Mezzo.Compose.Chords: minD' :: forall r_aZEs i_aZEt. ChorC' Tetrad r_aZEs (DoubledT MinTriad) i_aZEt
+ Mezzo.Compose.Chords: minD' :: forall r_a1085 i_a1086. ChorC' Tetrad r_a1085 (DoubledT MinTriad) i_a1086
- Mezzo.Compose.Chords: oct :: forall r_aZiq. ChorC Dyad r_aZiq PerfOct
+ Mezzo.Compose.Chords: oct :: forall r_aZM3. ChorC Dyad r_aZM3 PerfOct
- Mezzo.Compose.Chords: oct' :: forall r_aZin i_aZio. ChorC' Dyad r_aZin PerfOct i_aZio
+ Mezzo.Compose.Chords: oct' :: forall r_aZM0 i_aZM1. ChorC' Dyad r_aZM0 PerfOct i_aZM1
- Mezzo.Compose.Chords: octD :: forall r_aZsP. ChorC Triad r_aZsP (DoubledD PerfOct)
+ Mezzo.Compose.Chords: octD :: forall r_aZWs. ChorC Triad r_aZWs (DoubledD PerfOct)
- Mezzo.Compose.Chords: octD' :: forall r_aZsM i_aZsN. ChorC' Triad r_aZsM (DoubledD PerfOct) i_aZsN
+ Mezzo.Compose.Chords: octD' :: forall r_aZWp i_aZWq. ChorC' Triad r_aZWp (DoubledD PerfOct) i_aZWq
Files
- CHANGELOG.md +16/−1
- README.md +25/−18
- mezzo.cabal +4/−2
- src/Mezzo.hs +2/−1
- src/Mezzo/Compose/Chords.hs +1/−1
- src/Mezzo/Compose/Combine.hs +27/−27
- src/Mezzo/Compose/Harmony.hs +4/−0
- src/Mezzo/Model/Harmony/Functional.hs +8/−0
- src/Mezzo/Render.hs +1/−0
- src/Mezzo/Render/MIDI.hs +19/−6
- src/Mezzo/Render/Score.hs +2/−1
- src/Mezzo/Render/Transform.hs +77/−0
CHANGELOG.md view
@@ -4,7 +4,22 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## 0.3.0 - 2017-06-10+<!-- ## [Unreleased](https://github.com/DimaSamoz/mezzo/compare/v0.3.1...HEAD) -->++## [0.3.1 - 2017-10-07](https://github.com/DimaSamoz/mezzo/releases/tag/v0.3.1)+### Added+- Live playback on the terminal: Mezzo compositions can now be played back live from the terminal using an external midi synthesiser (e.g. [SimpleSynth](http://notahat.com/simplesynth/)) and [Euterpea](http://www.euterpea.com/).+- Empty cadences: you can use `end` as a cadential phrase to compose a chord progression without a cadence.+- Score transformation: you can use the functions such as `delay` and `transpose` to manipulate music at the MIDI track level. While this allows for more flexibility, composition of `Score`s is not rule-checked, so there is no static guarantee that the resulting music will sound good.++### Changed+- The melody constructor `play` has been renamed to `start`.++### Fixed+- Readme typos and rule set changes in examples.+- Clashes with Prelude's `min` function.++## [0.3.0 - 2017-06-16](https://github.com/DimaSamoz/mezzo/releases/tag/v0.3.0) ### Added - Chord progressions: create chord progressions following the conventions of functional harmony. - Dyads: 2-note chords (thirds, fourths, fifths and octaves), together with their doubled versions.
README.md view
@@ -4,8 +4,6 @@ *Mezzo* is a Haskell library and embedded domain-specific language for music description. Its novelty is in the fact that it can enforce various rules of music composition *statically*, that is, at compile-time. This effectively means that if you write "bad" music, your composition will not compile – think of it as a **very** strict spell-checker for music. -<!-- TOC depthFrom:2 depthTo:6 withLinks:1 updateOnSave:1 orderedList:0 -->- - [Getting started](#getting-started) - [Prerequisites](#prerequisites) - [Installation](#installation)@@ -37,8 +35,6 @@ - [License](#license) - [Acknowledgments](#acknowledgments) -<!-- /TOC -->- ## Getting started This section explains how to install Mezzo and start using the library.@@ -60,7 +56,7 @@ If using Stack, you will need to add the package to your `extra-deps` in your `stack.yaml` (as Mezzo is not part of Stackage yet), and then add it normally to your `.cabal` file dependencies: ```cabal-extra-deps: [ mezzo-0.3.0.0 ]+extra-deps: [ mezzo-0.3.1.0 ] build-depends: base >= 4.7 && < 5 , mezzo@@ -76,10 +72,10 @@ ```haskell import Mezzo -comp = defScore $ play $ melody :| c :| d :| e :| f :>> g+comp = defScore $ start $ melody :| c :| d :| e :| f :>> g main :: IO ()-main = renderMusic "comp.mid" comp+main = renderScore "comp.mid" "First composition" comp ``` Save, build and execute (e.g. with `stack exec <project_name>`). You should get a `.mid` file in the project directory which looks something like this:@@ -123,7 +119,7 @@ * **Accidental**: a suffix of the pitch class, one of `f` (flat, e.g. `bf qn`) or `s` (sharp, e.g. `fs qn`). Natural accidentals are not specified, so `c` means C natural. Accidentals can also be written out as a separate attribute (`c sharp qn`), or even repeated (for example, double sharps: `c sharp sharp qn` or `cs sharp qn`). * **Octave**: the last component of the value. The default octave is 4, this is unmarked. Lower octaves are marked with `_`, `__`, `_3`, `_4` and `_5`. Higher octaves are marked with `'`, `''`, `'3` and `'4`. A C natural in octave 2 is therefore `c__ qn`, a B flat in octave 7 is `bf'3 qn`. -Durations are written after the pitch. For notes, the value is the first letter of the duration name (eighth, quarter, etc.) followed by `n` for note, e.g., `qn` for quarter note. A dotted duration is specified by following the name with a `'`: `hn'` is a dotted half note, with the length of three quarters.+Durations are written after the pitch. For notes, the value is the first letter of the duration name (eighth, quarter, etc.) followed by `n` for note, e.g., `qn` for quarter note. A dotted duration is specified by following the name with a `'` (single quote): `hn'` is a dotted half note, with the length of three quarters. #### Rests @@ -210,10 +206,10 @@ Mezzo provides a more concise way of melody input, where only the duration changes are explicit: ```haskell-play $ melody :| c :< c :| d :| ef :| d :| c :| b_ :> c :| c+start $ melody :| c :< c :| d :| ef :| d :| c :| b_ :> c :| c ``` -Melodies are effectively lists of pitches with the constructors specifying the duration of the next pitch. All melodies have to start with the `melody` keyword – which initialises the melody and set the "default" duration to a quarter note – and a melody can be converted into a playable `Music` value with the `play` function. The constructors can be used as follows:+Melodies are effectively lists of pitches with the constructors specifying the duration of the next pitch. All melodies have to start with the `melody` keyword – which initialises the melody and set the "default" duration to a quarter note – and a melody can be converted into a playable `Music` value with the `start` function. The constructors can be used as follows: * `(:|)`: the next note has the same duration as the previous one. For example, `melody :| c :| d :| e` creates a melody of 3 quarter notes (since `melody` initialises the duration to a quarter note). * `(:<<<)`, `(:<<)`, `(:<)`, `(:^)`, `(:>)` and `(:>>)`: the next note is a thirty-second, sixteenth, eighth, quarter, half or whole note, respectively.@@ -222,6 +218,7 @@ * All constructors that change the duration (except `(:<<<)` and `(:~<<<)`) can be followed by a `.` to make the duration dotted. For example, `melody :^ c :^. d :> e` specifies a melody of a quarter note, a dotted quarter note and a half note. Below is a table summarising the melody construction operators.+(See the [https://github.com/DimaSamoz/mezzo/blob/master/README.md](GitHub README) if the table is not formatted.) | Duration | Note | Rest | Dotted note | Dotted rest | |---------------|-------|-------|-------------|-------------|@@ -239,10 +236,10 @@ * Frère Jacques: ```haskell-fj1 = play $ melody :| g :| a :| b :| g-fj2 = play $ melody :| b :| c' :> d'-fj3 = play $ melody :< d' :| e' :| d' :| c' :^ b :| g-fj4 = play $ melody :| g :| d :> g+fj1 = start $ melody :| g :| a :| b :| g+fj2 = start $ melody :| b :| c' :> d'+fj3 = start $ melody :< d' :| e' :| d' :| c' :^ b :| g+fj4 = start $ melody :| g :| d :> g fj = defScore $ fj1 :|: fj1 :|: fj2 :|: fj2 :|: fj3 :|: fj3 :|: fj4 :|: fj4 ```@@ -250,8 +247,8 @@ * Jingle Bells: ```haskell-p1 = play $ melody :< e :| e :^ e :< e :| e :^ e :< e :| g :<. c :<< d :>> e-p2 = play $ melody :< f :| f :<. f :<< f :< f :| e :<. e :<< e :< e :| d :| d :| e :^ d :| g+p1 = start $ melody :< e :| e :^ e :< e :| e :^ e :< e :| g :<. c :<< d :>> e+p2 = start $ melody :< f :| f :<. f :<< f :< f :| e :<. e :<< e :< e :| d :| d :| e :^ d :| g jb = defScore $ p1 :|: p2 ```@@ -298,6 +295,7 @@ * `auth_64_V7_I`: an authentic dominant cadence with a cadential 6-4. * `decept_V_iv`: a deceptive V-iv cadence. * `full sd c`: a full cadence, consisting of a subdominant region and a cadence.+ * `end`: empty cadence. The example above therefore has a tonic-dominant-tonic region, followed by a full cadence with a fourth degree subdominant and authentic dominant cadence. The `prog` keyword converts a schema into a `Music` value. @@ -354,11 +352,18 @@ If a piece is broken up into smaller scores (sections), all of them can be concatenated and rendered using the `renderScores` function: ```haskell-renderScore :: FilePath -> Title -> [Score] -> IO ()+renderScores :: FilePath -> Title -> [Score] -> IO () ``` This is similar to `renderScore`, but takes a list of `Score`s (in the desired order). Note that this allows for reuse of sections: for example, a refrain (or repeated section) only has to be described once, and the score created from it can be reused without any additional rule-checking. See the Für Elise example for a demonstration. +Mezzo compositions can be played live, from the terminal, using the function++```haskell+playLive' :: Score -> IO ()+```+You can also use `playLive = playLive' . defScore` to play a `Music` value right away. Note that in order to play Mezzo compositions from the terminal, you need to have an appropriate MIDI device (e.g. synthesiser) configured. As the implementation uses Euterpea's playback features, you should set up the configuration following [these](http://www.euterpea.com/euterpea/setting-up-midi/) instructions.+ ## Rule sets As different musical genres enforce different kinds of rules, Mezzo lets users select different levels of strictness (called *rule sets*) or even completely customise the musical rules that are checked. In particular, one rule set turns off correctness checking completely, allowing for complete creative freedom. @@ -476,7 +481,9 @@ ## License -This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details+This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.++Note that this project is different from [Mezzo](http://protz.github.io/mezzo/), a research language for effectful concurrent programming. ## Acknowledgments
mezzo.cabal view
@@ -1,5 +1,5 @@ name: mezzo-version: 0.3.0.0+version: 0.3.1.0 synopsis: Typesafe music composition description: A Haskell music composition library that enforces common musical rules in the type system.@@ -46,13 +46,15 @@ , Mezzo.Render , Mezzo.Render.MIDI , Mezzo.Render.Score-+ , Mezzo.Render.Transform+ build-depends: base >= 4.7 && < 5 , ghc-typelits-natnormalise , template-haskell , HCodecs , boxes , ghc-prim+ , Euterpea ghc-options: -fplugin GHC.TypeLits.Normalise default-language: Haskell2010 default-extensions: TypeInType
src/Mezzo.hs view
@@ -1,4 +1,4 @@-+{-# LANGUAGE NoImplicitPrelude #-} ----------------------------------------------------------------------------- -- | -- Module : Mezzo@@ -15,6 +15,7 @@ ----------------------------------------------------------------------------- module Mezzo (module X, ($), (++), concat) where+import Prelude (($), (++), concat) -- Uses import/export shortcut as suggested by HLint.
src/Mezzo/Compose/Chords.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TemplateHaskell, NoImplicitPrelude #-} ----------------------------------------------------------------------------- -- |
src/Mezzo/Compose/Combine.hs view
@@ -28,7 +28,7 @@ , pad3 , pad4 -- * Melody composition- , play+ , start , melody -- * Textures , hom@@ -123,31 +123,31 @@ ------------------------------------------------------------------------------- -- | Convert a melody (a sequence of notes and rests) to `Music`.-play :: (Primitive d) => Melody s m d -> Music s m-play m@(ps :| p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :<<< p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :<< p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :< p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :^ p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :> p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :>> p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :<<. p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :<. p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :^. p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :>. p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :>>. p) = case ps of Melody -> mkMelNote m p ; ps' -> play ps' :|: mkMelNote m p-play m@(ps :~| p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~<<< p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~<< p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~< p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~^ p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~> p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~>> p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~<<. p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~<. p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~^. p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~>. p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m-play m@(ps :~>>. p) = case ps of Melody -> mkMelRest m ; ps' -> play ps' :|: mkMelRest m+start :: (Primitive d) => Melody s m d -> Music s m+start m@(ps :| p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :<<< p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :<< p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :< p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :^ p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :> p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :>> p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :<<. p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :<. p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :^. p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :>. p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :>>. p) = case ps of Melody -> mkMelNote m p ; ps' -> start ps' :|: mkMelNote m p+start m@(ps :~| p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~<<< p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~<< p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~< p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~^ p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~> p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~>> p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~<<. p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~<. p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~^. p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~>. p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m+start m@(ps :~>>. p) = case ps of Melody -> mkMelRest m ; ps' -> start ps' :|: mkMelRest m -- | Make a note of suitable duration from a root specifier. mkMelNote :: (IntRep r, Primitive d, ValidNote s r d) => Melody s m d -> RootS r -> Music s (FromRoot r d)@@ -173,7 +173,7 @@ hom = Homophony melAccomp :: (s ~ (Sig :: Signature t k r), ValidProg r t p, pm ~ FromProg p t, ValidHom s m pm, Primitive d) => Melody s m d -> InKey k (PhraseList p) -> Music s (m +-+ pm)-melAccomp m p = Homophony (play m) (prog p)+melAccomp m p = Homophony (start m) (prog p) ------------------------------------------------------------------------------- -- Triplets
src/Mezzo/Compose/Harmony.hs view
@@ -92,6 +92,10 @@ full :: InKey k (Sub s) -> InKey k (Cad c) -> InKey k (Cad (FullCad s c)) full _ _ = const Cad +-- | End progression without an explicit cadence.+end :: InKey k (PhraseList (CadPhrase NoCad))+end = cadence $ const Cad+ -- ** Tonic chords -- | Tonic chord.
src/Mezzo/Model/Harmony/Functional.hs view
@@ -137,6 +137,8 @@ DeceptCad :: DegreeC V DomQ k Inv2 o -> DegreeC VI q k Inv1 o -> Cadence k 2 -- | Full cadence from subdominant to dominant to tonic. FullCad :: Subdominant k l1 -> Cadence k (l - l1) -> Cadence k l+ -- | No cadence.+ NoCad :: Cadence k 0 -- | A tonic chord. data Tonic (k :: KeyType) (l :: Nat) where@@ -182,6 +184,7 @@ CadToChords 2 (DeceptCad d1 d2) = DegToChord d1 :-- DegToChord d2 :-- None CadToChords 3 (AuthCad64 d1 d2 d3) = DegToChord d1 :-- DegToChord d2 :-- DegToChord d3 :-- None CadToChords l (FullCad (s :: Subdominant k l1) c) = SubdomToChords l1 s ++. CadToChords (l - l1) c+ CadToChords 0 NoCad = None -- | Convert a tonic to chords. type family TonToChords (l :: Nat) (t :: Tonic k l) :: Vector (ChordType 4) l where@@ -355,6 +358,11 @@ type Rep (FullCad sd c) = [[Int]] prim _ = prim (Sub @k @sdur @sd) ++ prim (Cad @k @(l - sdur) @c) pretty _ = pretty (Sub @k @sdur @sd) ++ " | " ++ pretty (Cad @k @(l - sdur) @c)++instance Primitive NoCad where+ type Rep NoCad = [[Int]]+ prim _ = []+ pretty _ = "NoCad" -- Phrases
src/Mezzo/Render.hs view
@@ -20,3 +20,4 @@ import Mezzo.Render.MIDI as X import Mezzo.Render.Score as X+import Mezzo.Render.Transform as X
src/Mezzo/Render/MIDI.hs view
@@ -17,7 +17,8 @@ ----------------------------------------------------------------------------- module Mezzo.Render.MIDI- (renderScore, renderScores, withMusic, defScore )+ ( MidiNote (..), Score, (><)+ , renderScore, renderScores, withMusic, defScore, playLive, playLive' ) where import Mezzo.Model@@ -28,6 +29,9 @@ import Codec.Midi hiding (key, Key) import qualified Codec.Midi as CM (key, Key)+import Euterpea.IO.MIDI.Play (playM')+import Euterpea.IO.MIDI.MidiIO (unsafeOutputID)+import Prelude hiding (min) ------------------------------------------------------------------------------- -- Types@@ -37,7 +41,7 @@ data MidiNote = MidiNote { noteNum :: Int -- ^ MIDI number of a note (middle C is 60). , vel :: Velocity -- ^ Performance velocity of the note.- , start :: Ticks -- ^ Relative start time of the note.+ , startT :: Ticks -- ^ Relative start time of the note. , noteDur :: Ticks -- ^ Duration of the note. } deriving Show @@ -56,18 +60,18 @@ -- | Play a MIDI note with the specified duration and default velocity. midiNote :: Int -> Ticks -> MidiNote-midiNote root dur = MidiNote {noteNum = root, vel = 100, start = 0, noteDur = dur}+midiNote root dur = MidiNote {noteNum = root, vel = 100, startT = 0, noteDur = dur} midiRest :: Ticks -> MidiNote-midiRest dur = MidiNote {noteNum = 60, vel = 0, start = 0, noteDur = dur}+midiRest dur = MidiNote {noteNum = 0, vel = 0, startT = 0, noteDur = dur} -- | Start playing the specified 'MidiNote'. keyDown :: MidiNote -> MidiEvent-keyDown n = (start n, NoteOn {channel = 0, CM.key = noteNum n, velocity = vel n})+keyDown n = (startT n, NoteOn {channel = 0, CM.key = noteNum n, velocity = vel n}) -- | Stop playing the specified 'MidiNote'. keyUp :: MidiNote -> MidiEvent-keyUp n = (start n + noteDur n, NoteOn {channel = 0, CM.key = noteNum n, velocity = 0})+keyUp n = (startT n + noteDur n, NoteOn {channel = 0, CM.key = noteNum n, velocity = 0}) -- | Play the specified 'MidiNote'. playNote :: Int -> Ticks -> MidiTrack@@ -151,3 +155,12 @@ -- | Create a MIDI file with the specified path, title and list of scores. renderScores :: FilePath -> Title -> [Score] -> IO () renderScores f compTitle ts = renderScore f compTitle (concat ts)++-- | Live playback of a Mezzo score.+playLive' :: Score -> IO ()+playLive' s = playM' (Just $ unsafeOutputID 0) $ midiSkeleton "Live playback" s++-- | Live playback of a Mezzo piece with default score attributes.+playLive :: Music (Sig :: Signature 4 (Key C Natural MajorMode) Classical) m+ -> IO ()+playLive m = playLive' (defScore m)
src/Mezzo/Render/Score.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE RecordWildCards, NoImplicitPrelude #-} ----------------------------------------------------------------------------- -- |@@ -43,6 +43,7 @@ import Codec.Midi hiding (key, Key) import qualified Codec.Midi as CM (key, Key) import qualified GHC.TypeLits as GT+import Prelude hiding (min) ------------------------------------------------------------------------------- -- Attributes
+ src/Mezzo/Render/Transform.hs view
@@ -0,0 +1,77 @@++-----------------------------------------------------------------------------+-- |+-- Module : Mezzo.Render.Transform+-- Description : Score-level transformations+-- Copyright : (c) Dima Szamozvancev+-- License : MIT+--+-- Maintainer : ds709@cam.ac.uk+-- Stability : experimental+-- Portability : portable+--+-- Functions and combinators for transforming Scores. Allows for more flexibility,+-- but no static correctness guarantees.+--+-----------------------------------------------------------------------------++module Mezzo.Render.Transform+ (transpose, delay, (><), (+++), flatten, reprise, cascade, scale, volta)+ where++import Mezzo.Render.Score+import Mezzo.Render.MIDI++import Codec.Midi hiding (key, Key)+import qualified Codec.Midi as CM (key, Key)+import Prelude hiding (min)+import Control.Arrow (first, second)++-- | Transpose a single MIDI message by the given number of semitones.+transposeMessage :: Int -> Message -> Message+transposeMessage t (NoteOff ch key vel) = NoteOff ch (key + t) vel+transposeMessage t (NoteOn ch key vel) = NoteOn ch (key + t) vel+transposeMessage _ m = m++-- | Transpose a score by the given number of semitones.+transpose :: Int -> Score -> Score+transpose n = map (second (transposeMessage n))++-- | Delay a score by the given number of ticks (60ths of a thirty-second note).+delay :: Ticks -> Score -> Score+delay ticks (n@(_, NoteOn{}) : rest) =+ [ (0, NoteOn {channel = 0, CM.key = 60, velocity = 0})+ , (ticks, NoteOn {channel = 0, CM.key = 60, velocity = 0})+ ] ++ n : rest+delay ticks (m : rest) = m : delay ticks rest++-- | Remove the attribute MIDI messages in the score header.+stripHeader :: Score -> Score+stripHeader [] = []+stripHeader (n@(_, NoteOn{}) : rest) = n : rest+stripHeader (_ : rest) = stripHeader rest++-- | Concatenation of scores.+(+++) :: Score -> Score -> Score+s1 +++ s2 = s1 ++ stripHeader s2++-- | Flatten a list of scores into a single score.+flatten :: [Score] -> Score+flatten = foldr (+++) []++-- | Repeat a score the given number of times.+reprise :: Int -> Score -> Score+reprise n = flatten . replicate n++-- | Repeat the score, successively applying the function to each repetition.+-- cascade 4 f s = s +++ f s +++ f (f s) +++ f (f (f s))+cascade :: Int -> (Score -> Score) -> Score -> Score+cascade n f = flatten . take n . iterate f++-- | Create a scale of the given length and interval between scores.+scale :: Int -> Int -> Score -> Score+scale l i = cascade l (transpose i)++-- | Repeat the score with the different endings at each repetition.+volta :: Score -> [Score] -> Score+volta s vs = flatten $ map (s +++) vs