From 669995964ac4af116e41882d41cb741e7ed3667b Mon Sep 17 00:00:00 2001 From: fred Date: Sun, 24 Mar 2002 19:54:42 +0000 Subject: [PATCH] lilypond-0.1.10 --- Documentation/mi2mu.pod | 5 + init/paper20.ly | 30 +++ init/table16.ly | 173 ++++++++--------- init/table20.ly | 174 +++++++++++++++++ lib/duration-convert.cc | 4 +- lib/duration.cc | 8 +- lib/include/duration.hh | 1 - mi2mu/include/midi-parser.hh | 112 +++++++++++ mi2mu/include/mudela-item.hh | 5 +- mi2mu/main.cc | 60 ++++-- mi2mu/midi-parser.cc | 98 ++++++++++ mi2mu/midi-score-parser.cc | 123 ++++++++++++ mi2mu/midi-track-parser.cc | 352 +++++++++++++++++++++++++++++++++++ mi2mu/mudela-item.cc | 114 ++++++------ mi2mu/mudela-score.cc | 104 ++++++++--- 15 files changed, 1162 insertions(+), 201 deletions(-) create mode 100644 init/paper20.ly create mode 100644 init/table20.ly create mode 100644 mi2mu/include/midi-parser.hh create mode 100644 mi2mu/midi-parser.cc create mode 100644 mi2mu/midi-score-parser.cc create mode 100644 mi2mu/midi-track-parser.cc diff --git a/Documentation/mi2mu.pod b/Documentation/mi2mu.pod index 1e35a7547a..6ee3e13a16 100644 --- a/Documentation/mi2mu.pod +++ b/Documentation/mi2mu.pod @@ -31,6 +31,11 @@ Show a summary of usage. Add DIR to search path. +=item B<-k, --key>=ACC[:MINOR], + +Set default key. ACC > 0 sets number of sharps; ACC < 0 sets number +of flats. A minor key is indicated by ":1". + =item B<-n, --no-silly>, Assume no plets or double dots, assume smallest (reciprocal) duration 16. diff --git a/init/paper20.ly b/init/paper20.ly new file mode 100644 index 0000000000..e2878e6de7 --- /dev/null +++ b/init/paper20.ly @@ -0,0 +1,30 @@ +% paper20.ly + +\include "table20.ly" + +paper_twenty = \paper { + linewidth = 15.0 \cm; + rule_thickness = 0.4\pt; + bar_size = 20.0 \pt; + interline = 5.\pt; + notewidth = 6.0\pt; + wholewidth = 7.5\pt; + unitspace = 22.\pt; +% basicspace = 4.\pt; +% geometric = 1.414; + geometric = 0.; + basicspace = 8.\pt; + + arithmetic_basicspace = 2.; + arithmetic_multiplier = 6.\pt; + + % + interbeam = 2.667\pt; + gourlay_energybound = 100000.; + gourlay_maxmeasures = 12.; + + castingalgorithm = \Gourlay; + \symboltables { \table_twenty } + \requesttranslator { \orchestral_score_translator } +} + diff --git a/init/table16.ly b/init/table16.ly index 71cc34dcba..290318e7cd 100644 --- a/init/table16.ly +++ b/init/table16.ly @@ -1,3 +1,4 @@ +% table16.ly % % spacing info for LilyPond. Do not edit this if you're not a guru. % It has a lot of hard-wired stringconstants @@ -12,35 +13,35 @@ table_sixteen= % index TeXstring, xmin xmax ymin ymax "scripts" = \table { - "fermata" "\fermata" 0.0\pt 0.0\pt 0.0\pt 6.0\pt - "-fermata" "\ifermata" 0.0\pt 0.0\pt -6.0\pt 0.0\pt - "portato" "\portato" 0.0\pt 4.0\pt 0.0\pt 2.0\pt - "-portato" "\iportato" 0.0\pt 4.0\pt -2.0\pt 0.0\pt - "tenuto" "\tenuto" 0.0\pt 4.0\pt -1.0\pt 1.0\pt - "-tenuto" "\itenuto" 0.0\pt 4.0\pt -1.0\pt 1.0\pt - "sforzato" "\sforzato" -0.8\pt 4.0\pt -1.92\pt 1.92\pt - "marcato" "\marcato" 0.0\pt 4.0\pt 0.0\pt 4.0\pt - "-marcato" "\imarcato" 0.0\pt 4.0\pt -4.0\pt 0.0\pt - "staccato" "\staccato" 0.0\pt 0.0\pt -1.1\pt 1.1\pt - "staccatissimo" "\staccatissimo" 0.0\pt 0.0\pt 0.0\pt 1.0\pt - "-staccatissimo" "\istaccatissimo" 0.0\pt 0.0\pt 0.0\pt 1.0\pt - "upbow" "\upbow" -1.0\pt 6.0\pt 0.0\pt 5.0\pt - "downbow" "\downbow" 0.0\pt 5.0\pt 0.0\pt 7.5\pt - "back" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt - "-front" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt - "heel" "\heel" 0.0\pt 6.0\pt -1.0\pt 5.0\pt - "toe" "\toe" 0.0\pt 6.0\pt -1.0\pt 5.0\pt - "bheel" "\bheel" 0.0\pt 6.0\pt -1.0\pt 5.0\pt - "btoe" "\btoe" 0.0\pt 6.0\pt -1.0\pt 5.0\pt - "fheel" "\fheel" 0.0\pt 6.0\pt -1.0\pt 5.0\pt - "ftoe" "\ftoe" 0.0\pt 6.0\pt -1.0\pt 5.0\pt - "-back" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt - "front" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt - "turn" "\turn" -2.0\pt 7.0\pt 0.0\pt 4.0\pt + "fermata" "\fermata" 0.0\pt 0.0\pt 0.0\pt 6.0\pt + "-fermata" "\ifermata" 0.0\pt 0.0\pt -6.0\pt 0.0\pt + "portato" "\portato" 0.0\pt 4.0\pt 0.0\pt 2.0\pt + "-portato" "\iportato" 0.0\pt 4.0\pt -2.0\pt 0.0\pt + "tenuto" "\tenuto" 0.0\pt 4.0\pt -1.0\pt 1.0\pt + "-tenuto" "\itenuto" 0.0\pt 4.0\pt -1.0\pt 1.0\pt + "sforzato" "\sforzato" -0.8\pt 4.0\pt -1.92\pt 1.92\pt + "marcato" "\marcato" 0.0\pt 4.0\pt 0.0\pt 4.0\pt + "-marcato" "\imarcato" 0.0\pt 4.0\pt -4.0\pt 0.0\pt + "staccato" "\staccato" 0.0\pt 0.0\pt -1.1\pt 1.1\pt + "staccatissimo" "\staccatissimo" 0.0\pt 0.0\pt 0.0\pt 1.0\pt + "-staccatissimo" "\istaccatissimo" 0.0\pt 0.0\pt 0.0\pt 1.0\pt + "upbow" "\upbow" -1.0\pt 6.0\pt 0.0\pt 5.0\pt + "downbow" "\downbow" 0.0\pt 5.0\pt 0.0\pt 7.5\pt + "back" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt + "-front" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt + "heel" "\heel" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "toe" "\toe" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "bheel" "\bheel" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "btoe" "\btoe" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "fheel" "\fheel" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "ftoe" "\ftoe" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "-back" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt + "front" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt + "turn" "\turn" -2.0\pt 7.0\pt 0.0\pt 4.0\pt } "style" = \table { - "roman" "\settext{%}" 0.0\pt 5.0\pt 0.0\pt 8.0\pt + "roman" "\settext{%}" 0.0\pt 7.50\pt 0.0\pt 8.0\pt "italic" "\setitalic{%}" 0.0\pt 0.0\pt 0.0\pt 8.0\pt "dynamic" "\setdynamic{%}" 0.0\pt 0.0\pt 0.0\pt 8.0\pt } @@ -63,38 +64,38 @@ table_sixteen= } "clefs" = \table { - "violin" "\violinclef" 0.0\pt 12.8\pt -10.0\pt 18.0\pt - "bass" "\bassclef" 0.0\pt 12.8\pt 0.0\pt 16.0\pt - "alto" "\altoclef" 0.0\pt 12.8\pt 0.0\pt 16.0\pt - "tenor" "\altoclef" 0.0\pt 12.8\pt 0.0\pt 16.0\pt - "violin_change" "\cviolinclef" 0.0\pt 11.2\pt -12.0\pt 12.0\pt - "bass_change" "\cbassclef" 0.0\pt 11.2\pt 0.0\pt 16.0\pt - "alto_change" "\caltoclef" 0.0\pt 11.2\pt 0.0\pt 16.0\pt - "tenor_change" "\caltoclef" 0.0\pt 11.2\pt 0.0\pt 16.0\pt + "violin" "\violinclef" 0.0\pt 12.8\pt -10.0\pt 18.0\pt + "bass" "\bassclef" 0.0\pt 12.8\pt 0.0\pt 16.0\pt + "alto" "\altoclef" 0.0\pt 12.8\pt 0.0\pt 16.0\pt + "tenor" "\altoclef" 0.0\pt 12.8\pt 0.0\pt 16.0\pt + "violin_change" "\cviolinclef" 0.0\pt 11.2\pt -12.0\pt 12.0\pt + "bass_change" "\cbassclef" 0.0\pt 11.2\pt 0.0\pt 16.0\pt + "alto_change" "\caltoclef" 0.0\pt 11.2\pt 0.0\pt 16.0\pt + "tenor_change" "\caltoclef" 0.0\pt 11.2\pt 0.0\pt 16.0\pt } "balls" = \table { - "-1" "\breveball" 0.0\pt 6.0\pt -2.0\pt 2.0\pt - "0" "\wholeball" 0.0\pt 6.0\pt -2.0\pt 2.0\pt - "1" "\halfball" 0.0\pt 5.0\pt -2.0\pt 2.0\pt - "2" "\quartball" 0.0\pt 5.0\pt -2.0\pt 2.0\pt + "-1" "\breveball" 0.0\pt 6.0\pt -2.0\pt 2.0\pt + "0" "\wholeball" 0.0\pt 6.0\pt -2.0\pt 2.0\pt + "1" "\halfball" 0.0\pt 5.0\pt -2.0\pt 2.0\pt + "2" "\quartball" 0.0\pt 5.0\pt -2.0\pt 2.0\pt } "slur" = \table { - "whole" "\slurchar%{%}" - "half" "\hslurchar%{%}" + "whole" "\slurchar%{%}" + "half" "\hslurchar%{%}" } "accidentals" = \table { - "-2" "\flatflat" 0.0\pt 8.16\pt -2.5\pt 7.5\pt - "-1" "\flat" 0.0\pt 4.8\pt -2.5\pt 7.5\pt - "0" "\natural" 0.0\pt 4.8\pt -7.5\pt 7.5\pt - "1" "\sharp" 0.0\pt 3.6\pt -7.5\pt 7.5\pt - "2" "\sharpsharp" 0.0\pt 4.8\pt -2.5\pt 7.5\pt + "-2" "\flatflat" 0.0\pt 8.16\pt -2.5\pt 7.5\pt + "-1" "\flat" 0.0\pt 4.8\pt -2.5\pt 7.5\pt + "0" "\natural" 0.0\pt 4.8\pt -7.5\pt 7.5\pt + "1" "\sharp" 0.0\pt 3.6\pt -7.5\pt 7.5\pt + "2" "\sharpsharp" 0.0\pt 4.8\pt -2.5\pt 7.5\pt } "streepjes" = \table { - "toplines" "\toplines{%}" -1.0\pt 7.0\pt 0.0\pt 0.0\pt - "botlines" "\botlines{%}" -1.0\pt 7.0\pt 0.0\pt 0.0\pt + "toplines" "\toplines{%}" -1.0\pt 7.0\pt 0.0\pt 0.0\pt + "botlines" "\botlines{%}" -1.0\pt 7.0\pt 0.0\pt 0.0\pt } "bars" = \table { @@ -111,62 +112,62 @@ table_sixteen= } "rests" = \table { - "-1o" "\breverest" 0.0\pt 6.0\pt 0.0\pt 4.0\pt - "-1" "\breverest" 0.0\pt 6.0\pt 0.0\pt 4.0\pt - "0o" "\outsidewholerest" 0.0\pt 6.0\pt 0.0\pt 2.0\pt - "0" "\wholerest" 0.0\pt 6.0\pt 0.0\pt 2.0\pt - "1" "\halfrest" 0.0\pt 6.0\pt -2.0\pt 0.0\pt - "1o" "\outsidehalfrest" 0.0\pt 6.0\pt -2.0\pt 0.0\pt - "2o" "\quartrest" -5.0\pt 2.0\pt -5.0\pt 5.0\pt - "3o" "\eighthrest" 0.0\pt 5.0\pt 0.0\pt 8.0\pt - "4o" "\sixteenthrest" 0.0\pt 6.0\pt 0.0\pt 12.0\pt - "2" "\quartrest" -5.0\pt 2.0\pt -5.0\pt 5.0\pt - "3" "\eighthrest" 0.0\pt 5.0\pt 0.0\pt 8.0\pt - "4" "\sixteenthrest" 0.0\pt 6.0\pt 0.0\pt 12.0\pt - "5" "\thirtysecondrest" 0.0\pt 6.0\pt 0.0\pt 16.0\pt - "6" "\sixtyfourthrest" 0.0\pt 6.0\pt 0.0\pt 16.0\pt - "7" "\hundredtwentyeighthrest" 0.0\pt 6.0\pt 0.0\pt 16.0\pt + "-1o" "\breverest" 0.0\pt 6.0\pt 0.0\pt 4.0\pt + "-1" "\breverest" 0.0\pt 6.0\pt 0.0\pt 4.0\pt + "0o" "\outsidewholerest" 0.0\pt 6.0\pt 0.0\pt 2.0\pt + "0" "\wholerest" 0.0\pt 6.0\pt 0.0\pt 2.0\pt + "1" "\halfrest" 0.0\pt 6.0\pt -2.0\pt 0.0\pt + "1o" "\outsidehalfrest" 0.0\pt 6.0\pt -2.0\pt 0.0\pt + "2o" "\quartrest" -5.0\pt 2.0\pt -5.0\pt 5.0\pt + "3o" "\eighthrest" 0.0\pt 5.0\pt 0.0\pt 8.0\pt + "4o" "\sixteenthrest" 0.0\pt 6.0\pt 0.0\pt 12.0\pt + "2" "\quartrest" -5.0\pt 2.0\pt -5.0\pt 5.0\pt + "3" "\eighthrest" 0.0\pt 5.0\pt 0.0\pt 8.0\pt + "4" "\sixteenthrest" 0.0\pt 6.0\pt 0.0\pt 12.0\pt + "5" "\thirtysecondrest" 0.0\pt 6.0\pt 0.0\pt 16.0\pt + "6" "\sixtyfourthrest" 0.0\pt 6.0\pt 0.0\pt 16.0\pt + "7" "\hundredtwentyeighthrest" 0.0\pt 6.0\pt 0.0\pt 16.0\pt } "meters" = \table { - "C" "\fourfourmeter" 0.0\pt 10.0\pt -5.0\pt 5.0\pt - "C2" "\allabreve" 0.0\pt 10.0\pt -5.0\pt 5.0\pt + "C" "\fourfourmeter" 0.0\pt 10.0\pt -5.0\pt 5.0\pt + "C2" "\allabreve" 0.0\pt 10.0\pt -5.0\pt 5.0\pt } % dims ignored for this table "param" = \table { - "brace" "\pianobrace{%}" 0.0\pt 0.0\pt 0.0\pt 0.0\pt - "meter" "\generalmeter{%}{%}" 0.0\pt 10.0\pt -5.0\pt 5.0\pt - "linestaf" "\linestafsym{%}{%}" - "stem" "\stem{%}{%}" - "fill" "\hbox{}" + "brace" "\pianobrace{%}" 0.0\pt 0.0\pt 0.0\pt 0.0\pt + "meter" "\generalmeter{%}{%}" 0.0\pt 10.0\pt -5.0\pt 5.0\pt + "linestaf" "\linestafsym{%}{%}" + "stem" "\stem{%}{%}" + "fill" "\hbox{}" % ugh. 8pt - "crescendosym" "\crescendosym{%}" 0.0\pt 0.0\pt -3.0\pt 3.0\pt - "decrescendosym" "\decrescendosym{%}" 0.0\pt 0.0\pt -3.0\pt 3.0\pt + "crescendosym" "\crescendosym{%}" 0.0\pt 0.0\pt -3.0\pt 3.0\pt + "decrescendosym" "\decrescendosym{%}" 0.0\pt 0.0\pt -3.0\pt 3.0\pt } "dots" = \table { - "1" "\lsingledot" 0.0\pt 2.0\pt -1.0\pt 1.0\pt - "2" "\ldoubledot" 0.0\pt 5.0\pt -1.0\pt 1.0\pt - "3" "\ltripledot" 0.0\pt 8.0\pt -1.0\pt 1.0\pt + "1" "\lsingledot" 0.0\pt 2.0\pt -1.0\pt 1.0\pt + "2" "\ldoubledot" 0.0\pt 5.0\pt -1.0\pt 1.0\pt + "3" "\ltripledot" 0.0\pt 8.0\pt -1.0\pt 1.0\pt } "flags" = \table { - "8" "\eighthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt - "16" "\sixteenthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt - "32" "\thirtysecondflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt - "64" "\sixtyfourthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt - "128" "\hundredtwentyeighthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt - "-8" "\deighthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt - "-16" "\dsixteenthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt - "-32" "\dthirtysecondflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt - "-64" "\dsixtyfourthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt - "-128" "\dhundredtwentyeighthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt + "8" "\eighthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt + "16" "\sixteenthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt + "32" "\thirtysecondflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt + "64" "\sixtyfourthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt + "128" "\hundredtwentyeighthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt + "-8" "\deighthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt + "-16" "\dsixteenthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt + "-32" "\dthirtysecondflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt + "-64" "\dsixtyfourthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt + "-128" "\dhundredtwentyeighthflag" 0.0\pt 4.0\pt 0.0\pt 0.0\pt } "beamslopes" = \table { - "slope" "\beamslope{%}{%}" - "horizontal" "\rulesym{%}{%}" + "slope" "\beamslope{%}{%}" + "horizontal" "\rulesym{%}{%}" } } diff --git a/init/table20.ly b/init/table20.ly new file mode 100644 index 0000000000..57f6c6305e --- /dev/null +++ b/init/table20.ly @@ -0,0 +1,174 @@ +% table20.ly +% +% spacing info for LilyPond. Do not edit this. +% It has a lot of hard-wired stringconstants +% + +table_twenty = +\symboltables { + + \texid "\input lilyponddefs \musixtwentydefs" + + % index TeXstring, xmin xmax ymin ymax + + % not yet updated + "scripts" = \table { + "fermata" "\fermata" 0.0\pt 0.0\pt 0.0\pt 6.0\pt + "-fermata" "\ifermata" 0.0\pt 0.0\pt -6.0\pt 0.0\pt + "portato" "\portato" 0.0\pt 4.0\pt 0.0\pt 2.0\pt + "-portato" "\iportato" 0.0\pt 4.0\pt -2.0\pt 0.0\pt + "tenuto" "\tenuto" 0.0\pt 4.0\pt -1.0\pt 1.0\pt + "-tenuto" "\itenuto" 0.0\pt 4.0\pt -1.0\pt 1.0\pt + "sforzato" "\sforzato" -0.8\pt 4.0\pt -1.92\pt 1.92\pt + "marcato" "\marcato" 0.0\pt 4.0\pt 0.0\pt 4.0\pt + "-marcato" "\imarcato" 0.0\pt 4.0\pt -4.0\pt 0.0\pt + "staccato" "\staccato" 0.0\pt 0.0\pt -1.1\pt 1.1\pt + "staccatissimo" "\staccatissimo" 0.0\pt 0.0\pt 0.0\pt 1.0\pt + "-staccatissimo" "\istaccatissimo" 0.0\pt 0.0\pt 0.0\pt 1.0\pt + "upbow" "\upbow" -1.0\pt 6.0\pt 0.0\pt 5.0\pt + "downbow" "\downbow" 0.0\pt 5.0\pt 0.0\pt 7.5\pt + "back" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt + "-front" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt + "heel" "\heel" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "toe" "\toe" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "bheel" "\bheel" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "btoe" "\btoe" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "fheel" "\fheel" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "ftoe" "\ftoe" 0.0\pt 6.0\pt -1.0\pt 5.0\pt + "-back" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt + "front" "\backorfront" 0.0\pt 6.0\pt 0.0\pt 3.0\pt + "turn" "\turn" -2.0\pt 7.0\pt 0.0\pt 4.0\pt + } + + "style" = \table { + "roman" "\settext{%}" 0.0\pt 7.5\pt 0.0\pt 10.0\pt + "italic" "\setitalic{%}" 0.0\pt 0.0\pt 0.0\pt 8.0\pt + "dynamic" "\setdynamic{%}" 0.0\pt 0.0\pt 0.0\pt 8.0\pt + } + "dynamics" = \table { + + "mf" "\dynmf" + "fff" "\dynfff" + "ff" "\dynff" + "f" "\dynf" + "mp" "\dynmp" + "p" "\dynp" + "pp" "\dynpp" + "ppp" "\dynppp" + + } + "align" = \table { + "-1" "\leftalign{%}" + "0" "\centeralign{%}" + "1" "\rightalign{%}" + } + + + "clefs" = \table { + "violin" "\violinclef" 0.0\pt 16.0\pt -12.5\pt 22.5\pt + "bass" "\bassclef" 0.0\pt 16.0\pt 0.0\pt 20.0\pt + "alto" "\altoclef" 0.0\pt 16.0\pt 0.0\pt 20.0\pt + "tenor" "\altoclef" 0.0\pt 16.0\pt 0.0\pt 20.0\pt + "violin_change" "\cviolinclef" 0.0\pt 16.0\pt -12.5\pt 22.5\pt + "bass_change" "\cbassclef" 0.0\pt 16.0\pt 0.0\pt 20.0\pt + "alto_change" "\caltoclef" 0.0\pt 16.0\pt 0.0\pt 20.0\pt + "tenor_change" "\caltoclef" 0.0\pt 16.0\pt 0.0\pt 20.0\pt + } + + "balls" = \table { + "-1" "\breveball" 0.0\pt 7.5\pt -2.5\pt 2.5\pt + "0" "\wholeball" 0.0\pt 7.5\pt -2.5\pt 2.5\pt + "1" "\halfball" 0.0\pt 6.0\pt -2.5\pt 2.5\pt + "2" "\quartball" 0.0\pt 6.0\pt -2.5\pt 2.5\pt + } + + "slur" = \table { + "whole" "\slurchar%{%}" 0.0\pt 0.0\pt 0.0\pt 0.0\pt + "half" "\hslurchar%{%}" 0.0\pt 0.0\pt 0.0\pt 0.0\pt + } + + "accidentals" = \table { + "-2" "\flatflat" 0.0\pt 10.2\pt -2.5\pt 7.5\pt + "-1" "\flat" 0.0\pt 6.0\pt -2.5\pt 7.5\pt + "0" "\natural" 0.0\pt 6.0\pt -7.5\pt 7.5\pt + "1" "\sharp" 0.0\pt 6.0\pt -7.5\pt 7.5\pt + "2" "\sharpsharp" 0.0\pt 6.0\pt -2.5\pt 7.5\pt + } + + "streepjes" = \table { + "toplines" "\toplines{%}" -3.0\pt 9.0\pt 0.0\pt 0.0\pt + "botlines" "\botlines{%}" -3.0\pt 9.0\pt 0.0\pt 0.0\pt + } + + "bars" = \table { + "empty" "\emptybar" + "" "" 0.0\pt 0.0\pt 0.0\pt 16.0\pt + "|" "\maatstreep{%}" 0.0\pt 0.64\pt 0.0\pt 20.0\pt + "||" "\doublebar{%}" 0.0\pt 4.0\pt 0.0\pt 20.0\pt + "|." "\finishbar{%}" 0.0\pt 2.0\pt 0.0\pt 20.0\pt + ".|" "\startbar{%}" 0.0\pt 4.0\pt 0.0\pt 20.0\pt + ":|" "\repeatbar" -8.0\pt 0.0\pt 0.0\pt 20.0\pt + "|:" "\startrepeat" 0.0\pt 8.0\pt 0.0\pt 20.0\pt + ":|:" "\repeatbarstartrepeat" 0.0\pt 16.0\pt 0.0\pt 20.0\pt + } + + "rests" = \table { + "-1o" "\breverest" 0.0\pt 6.0\pt 0.0\pt 4.0\pt + "-1" "\breverest" 0.0\pt 6.0\pt 0.0\pt 4.0\pt + "0o" "\outsidewholerest" 0.0\pt 6.0\pt 0.0\pt 2.0\pt + "0" "\wholerest" 0.0\pt 6.0\pt 0.0\pt 2.0\pt + "1" "\halfrest" 0.0\pt 6.0\pt -2.0\pt 0.0\pt + "1o" "\outsidehalfrest" 0.0\pt 6.0\pt -2.0\pt 0.0\pt + "2o" "\quartrest" -5.0\pt 2.0\pt -5.0\pt 5.0\pt + "3o" "\eighthrest" 0.0\pt 5.0\pt 0.0\pt 8.0\pt + "4o" "\sixteenthrest" 0.0\pt 6.0\pt 0.0\pt 12.0\pt + "2" "\quartrest" -5.0\pt 2.0\pt -5.0\pt 5.0\pt + "3" "\eighthrest" 0.0\pt 5.0\pt 0.0\pt 8.0\pt + "4" "\sixteenthrest" 0.0\pt 6.0\pt 0.0\pt 12.0\pt + "5" "\thirtysecondrest" 0.0\pt 6.0\pt 0.0\pt 16.0\pt + "6" "\sixtyfourthrest" 0.0\pt 6.0\pt 0.0\pt 16.0\pt + "7" "\hundredtwentyeighthrest" 0.0\pt 6.0\pt 0.0\pt 16.0\pt + } + + "meters" = \table { + "C" "\fourfourmeter" 0.0\pt 10.0\pt -5.0\pt 5.0\pt + "C2" "\allabreve" 0.0\pt 10.0\pt -5.0\pt 5.0\pt + } + + % dims ignored for this table + "param" = \table { + "brace" "\pianobrace{%}" 0.0\pt 0.0\pt 0.0\pt 0.0\pt + "meter" "\generalmeter{%}{%}" 0.0\pt 10.0\pt -5.0\pt 5.0\pt + "linestaf" "\linestafsym{%}{%}" + "stem" "\stem{%}{%}" + "fill" "\hbox{}" + % ugh. 8\pt + "crescendosym" "\crescendosym{%}" 0.0\pt 0.0\pt -3.0\pt 3.0\pt + "decrescendosym" "\decrescendosym{%}" 0.0\pt 0.0\pt -3.0\pt 3.0\pt + } + + "dots" = \table { + "1" "\lsingledot" 0.0\pt 8.0\pt -1.0\pt 1.0\pt + "2" "\ldoubledot" 0.0\pt 12.0\pt -1.0\pt 1.0\pt + "3" "\ltripledot" 0.0\pt 16.0\pt -1.0\pt 1.0\pt + } + + "flags" = \table { + "8" "\eighthflag" 0.0\pt 5.0\pt 0.0\pt 0.0\pt + "16" "\sixteenthflag" 0.0\pt 5.0\pt 0.0\pt 0.0\pt + "32" "\thirtysecondflag" 0.0\pt 5.0\pt 0.0\pt 0.0\pt + "64" "\sixtyfourthflag" 0.0\pt 5.0\pt 0.0\pt 0.0\pt + "128" "\hundredtwentyeighthflag" 0.0\pt 5.0\pt 0.0\pt 0.0\pt + "-8" "\deighthflag" 0.0\pt 5.0\pt 0.0\pt 0.0\pt + "-16" "\dsixteenthflag" 0.0\pt 5.0\pt 0.0\pt 0.0\pt + "-32" "\dthirtysecondflag" 0.0\pt 5.0\pt 0.0\pt 0.0\pt + "-64" "\dsixtyfourthflag" 0.0\pt 5.0\pt 0.0\pt 0.0\pt + "-128" "\dhundredtwentyeighthflag" 0.0\pt 5.0\pt 0.0\pt 0.0\pt + } + + "beamslopes" = \table { + "slope" "\beamslope{%}{%}" + "horizontal" "\rulesym{%}{%}" + } +} + diff --git a/lib/duration-convert.cc b/lib/duration-convert.cc index c96273e5ba..e64ca663ea 100644 --- a/lib/duration-convert.cc +++ b/lib/duration-convert.cc @@ -25,8 +25,8 @@ Duration_convert::dur2_str( Duration dur ) return String( "[" ) + String( dur.ticks_i_ ) + "]"; String str; - if (dur.durlog_i_ >= 0) - str="breve"; + if (dur.durlog_i_ <= 0) + str="\\breve"; else str= String( type2_i(dur.durlog_i_) ); str += String( '.', dur.dots_i_ ); diff --git a/lib/duration.cc b/lib/duration.cc index c26699c5bd..24ae6b5da6 100644 --- a/lib/duration.cc +++ b/lib/duration.cc @@ -7,6 +7,7 @@ Han-Wen Nienhuys */ +#include #include "proto.hh" #include "plist.hh" #include "string.hh" @@ -27,13 +28,6 @@ Duration::Duration() ticks_i_ = 0; } -Duration::Duration( int type_i, int dots_i = 0 ) -{ - durlog_i_ = type_i; - dots_i_ = dots_i; - ticks_i_ = 0; -} - bool Duration::duration_type_b(int t) { diff --git a/lib/include/duration.hh b/lib/include/duration.hh index c7f2ef3a47..0ae66d572e 100644 --- a/lib/include/duration.hh +++ b/lib/include/duration.hh @@ -29,7 +29,6 @@ struct Duration { Ctor of Duration. */ Duration(); - Duration( int type_i, int dots_i = 0 ); /// is the "plet factor" of this note != 1 ? bool plet_b(); String str()const; diff --git a/mi2mu/include/midi-parser.hh b/mi2mu/include/midi-parser.hh new file mode 100644 index 0000000000..3c1b491f65 --- /dev/null +++ b/mi2mu/include/midi-parser.hh @@ -0,0 +1,112 @@ +/* + midi-parser.hh -- declare Midi_parser + + source file of the GNU LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + + +#ifndef MIDI_PARSER_HH +#define MIDI_PARSER_HH + +// must, gcc 2.7.2{,.1} hits ico on midi-track-parser.cc:134 (@Midi_note) +#define INLINES + +#ifdef INLINES + +#define next_byte() (inline_next_byte (__FUNCTION__)) +#define peek_byte() (inline_peek_byte (__FUNCTION__)) +#define forward_byte_L(n) (inline_forward_byte_L (__FUNCTION__, n)) + +#else + +#define next_byte()\ + ((info_l_->byte_L_ < info_l_->end_byte_L_ ?\ + *info_l_->byte_L_++\ + : (Byte const)exit (__FUNCTION__": unexpected EOF"))); + +#define peek_byte()\ + ((info_l_->byte_L_ < info_l_->end_byte_L_ ?\ + *info_l_->byte_L_\ + : (Byte const)exit (__FUNCTION__": unexpected EOF"))); + +#define forward_byte_L(n) (inline_forward_byte_L (__FUNCTION__, n)) + +#endif + +#include "proto.hh" +#include "moment.hh" +#include "mi2mu-proto.hh" + +struct Midi_parser_info +{ + Midi_parser_info(); + int division_1_i_; + int format_i_; + int tracks_i_; + int errorlevel_i_; + Byte const* byte_L_; + Byte const* end_byte_L_; + Source_file* source_l_; + Mudela_score* score_l_; + Moment bar_mom_; +}; + +#include "string.hh" + +class Midi_parser +{ +public: + Midi_parser (); + + Midi_parser_info* info_l_; + +protected: +// Byte const* inline_forward_byte_L (int n) + Byte const* inline_forward_byte_L (char const* fun, int n) + { + if (info_l_->byte_L_ + n < info_l_->end_byte_L_ ) + { + Byte const* p = info_l_->byte_L_; + info_l_->byte_L_ += n; + return p; + } +// exit (__FUNCTION__": unexpected EOF"); + exit (String (fun) + ": unexpected EOF"); + return 0; + } + +#ifdef INLINES +// Byte inline_next_byte () + Byte inline_next_byte (char const* fun) + { + if (info_l_->byte_L_ < info_l_->end_byte_L_) + return *info_l_->byte_L_++; +// exit (__FUNCTION__": unexpected EOF"); + exit (String (fun) + ": unexpected EOF"); + return 0; + } + +// Byte inline_peek_byte () + Byte inline_peek_byte (char const* fun) + { + if (info_l_->byte_L_ < info_l_->end_byte_L_) + return *info_l_->byte_L_; +// exit (__FUNCTION__": unexpected EOF"); + exit (String (fun) + ": unexpected EOF"); + return 0; + } +#endif + + int get_i (int); + String get_str (int); + unsigned get_u (int); + int get_var_i (); + int exit (String); + void error (String); + String message (String); + void warning (String); +}; + +#endif // MIDI_PARSER_HH diff --git a/mi2mu/include/mudela-item.hh b/mi2mu/include/mudela-item.hh index ba0d77c518..9423959b6d 100644 --- a/mi2mu/include/mudela-item.hh +++ b/mi2mu/include/mudela-item.hh @@ -39,10 +39,9 @@ public: String notename_str (int pitch_i); virtual String str(); -private: +//private: int accidentals_i_; int minor_i_; - int key_i_; }; class Mudela_meter : public Mudela_item @@ -121,7 +120,7 @@ public: Mudela_text (Mudela_text::Type type, String str); virtual String str(); -private: +//private: Type type_; String text_str_; }; diff --git a/mi2mu/main.cc b/mi2mu/main.cc index c138322590..8626213568 100644 --- a/mi2mu/main.cc +++ b/mi2mu/main.cc @@ -4,6 +4,7 @@ // // copyright 1997 Jan Nieuwenhuizen +#include #include "string-convert.hh" #include "lgetopt.hh" #include "path.hh" @@ -11,12 +12,18 @@ #include "source.hh" #include "mi2mu-global.hh" -#include "my-midi-parser.hh" +#include "midi-score-parser.hh" +#include "mudela-item.hh" #include "mudela-score.hh" #include "version.hh" +// ugh +String filename_str_g; + +// ugh +Mudela_score* mudela_score_l_g = 0; + Sources source; -Sources* source_l_g = &source; static File_path path; @@ -37,6 +44,7 @@ usage() " -d, --debug print lots of debugging stuff\n" " -h, --help this help\n" " -I, --include=DIR add DIR to search path\n" + " -k, --key=ACC[:MINOR] set key: ACC +sharps/-flats; :1 minor\n" " -n, --no-silly assume no plets or double dots, smallest is 32\n" " -o, --output=FILE set FILE as default output\n" " -p, --no-plets assume no plets\n" @@ -82,6 +90,7 @@ notice() int main (int argc_i, char* argv_sz_a[]) { + Mudela_key key (0, 0); rat_printer = print_rat; Long_option_init long_option_init_a[] = @@ -89,6 +98,7 @@ main (int argc_i, char* argv_sz_a[]) {0, "no-quantify", 'b'}, {0, "debug", 'd'}, {0, "help", 'h'}, + {1, "key", 'k'}, {0, "no-silly", 'n'}, {1, "output", 'o'}, {0, "no-plets", 'p'}, @@ -102,8 +112,8 @@ main (int argc_i, char* argv_sz_a[]) Getopt_long getopt_long (argc_i, argv_sz_a, long_option_init_a); String output_str; - while (Long_option_init const* long_option_init_p = getopt_long()) - switch (long_option_init_p->shortname) + while (Long_option_init const* long_option_init_p = getopt_long()) + switch (long_option_init_p->shortname) { case 'b': Duration_convert::no_quantify_b_s = true; @@ -119,6 +129,15 @@ main (int argc_i, char* argv_sz_a[]) // case 'I': // path->push (getopt_long.optional_argument_ch_C_); // break; + case 'k': + { + String str = getopt_long.optional_argument_ch_C_; + int i = str.index_i (':'); + i = (i >=0 ? i : str.length_i ()); + key.accidentals_i_ = String_convert::dec2_i (str.left_str (i)); + key.minor_i_ = (int)(bool)String_convert::dec2_i (str.mid_str (i,1)); + break; + } case 'n': Duration_convert::no_double_dots_b_s = true; Duration_convert::no_triplets_b_s = true; @@ -136,7 +155,7 @@ main (int argc_i, char* argv_sz_a[]) case 's': { int i = String_convert::dec2_i (getopt_long.optional_argument_ch_C_); - if (!i) + if (!i) { identify(); usage(); @@ -166,32 +185,33 @@ main (int argc_i, char* argv_sz_a[]) identify(); path.add (""); - source_l_g->set_path (&path); + source.set_binary (true); + source.set_path (&path); char const* arg_sz = 0; - while ( (arg_sz = getopt_long.get_next_arg())) + while ( (arg_sz = getopt_long.get_next_arg ())) { - My_midi_parser midi_parser (arg_sz, & source); - midi_parser_l_g = &midi_parser; + filename_str_g = arg_sz; + Midi_score_parser midi_parser; + Mudela_score* score_p = midi_parser.parse (arg_sz, &source); - int error_i = midi_parser.parse(); - if (error_i) - return error_i; + if (!score_p) + return 1; - if (!output_str.length_i()) + if (!score_p->mudela_key_l_) + score_p->mudela_key_l_ = &key; + mudela_score_l_g = score_p; + score_p->process(); + + if (!output_str.length_i ()) { String d, dir, base, ext; - split_path (arg_sz, d, dir, base, ext); - output_str = base + ext + ".ly"; } - assert (midi_parser.mudela_score_p_); - midi_parser.mudela_score_p_->process(); - midi_parser.mudela_score_p_->output (output_str); - - midi_parser_l_g = 0; + score_p->output (output_str); + delete score_p; } return 0; } diff --git a/mi2mu/midi-parser.cc b/mi2mu/midi-parser.cc new file mode 100644 index 0000000000..d5e6727776 --- /dev/null +++ b/mi2mu/midi-parser.cc @@ -0,0 +1,98 @@ +/* + midi-parser.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + +#include +#include "string-convert.hh" +#include "source-file.hh" +#include "mi2mu-global.hh" +#include "midi-parser.hh" + +Midi_parser_info::Midi_parser_info () +{ + division_1_i_ = 0; + format_i_ = 0; + tracks_i_ = 0; + errorlevel_i_ = 0; + byte_L_ = 0; + end_byte_L_ = 0; + score_l_ = 0; +} + +Midi_parser::Midi_parser () +{ + info_l_ = 0; +} + +int +Midi_parser::exit (String str) +{ + error (str); + ::exit (1); + return 0; +} + +void +Midi_parser::error (String str) +{ + ::message (message (str)); +} + +int +Midi_parser::get_i (int n) +{ + assert (n <= (int)sizeof(int)); + return String_convert::bin2_i (get_str (n)); +} + +unsigned +Midi_parser::get_u (int n) +{ + assert (n <= (int)sizeof(int)); + return String_convert::bin2_i (get_str (n)); +} + +String +Midi_parser::get_str (int n) +{ + assert (n > 0); + Byte const* p = forward_byte_L (n); + return String (p, n); +} + +int +Midi_parser::get_var_i () +{ + int var_i = 0; + + while (1) + { + Byte byte = next_byte (); + var_i <<= 7; + var_i += byte & 0x7f; + if (!(byte & 0x80)) + return var_i; + } + exit ("get_var_i:"); + return 0; +} + +String +Midi_parser::message (String str) +{ + return String ("mi2mu: ") + + info_l_->source_l_->name_str () + ": " + + String_convert::i2dec_str (info_l_->source_l_->line_i ((char const*)info_l_->byte_L_), 0, 0) + ": " + + str + "\n" + + info_l_->source_l_->error_str ((char const*)info_l_->byte_L_); +} + +void +Midi_parser::warning (String str) +{ + ::message (message (String ("warning: ") + str)); +} diff --git a/mi2mu/midi-score-parser.cc b/mi2mu/midi-score-parser.cc new file mode 100644 index 0000000000..ab5169da12 --- /dev/null +++ b/mi2mu/midi-score-parser.cc @@ -0,0 +1,123 @@ +/* + midi-score-parser.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + +#include "moment.hh" +#include "source-file.hh" +#include "source.hh" +#include "mi2mu-global.hh" +#include "midi-score-parser.hh" +#include "midi-track-parser.hh" +#include "mudela-item.hh" +#include "mudela-score.hh" + + +void +Midi_score_parser::open (String filename_str, Sources* sources_l) +{ + info_l_->source_l_ = sources_l->get_file_l (filename_str); + if (!info_l_->source_l_) + ::error ("can't find: `" + filename_str + "'"); + info_l_->byte_L_ = (Byte const*)info_l_->source_l_->ch_C (); +// info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i (); + info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i () + 1; +} + +Mudela_score* +Midi_score_parser::parse (String filename_str, Sources* sources_l) +{ + Midi_parser_info info; + info_l_ = &info; + open (filename_str, sources_l); + parse_header (); + return parse_score (); +} + +void +Midi_score_parser::parse_header () +{ + String str = get_str (4); + if ( str != "MThd" ) + exit ("MIDI header expected"); + + int length_i = get_i (4); + // is this signed? + if (length_i < 6) + exit ("Invalid header length"); + info_l_->format_i_ = get_i (2); + if (info_l_->format_i_ != 0 && info_l_->format_i_ != 1) + exit ("Invalid midi format"); + info_l_->tracks_i_ = get_i (2); + if (info_l_->tracks_i_ < 0 || info_l_->tracks_i_ > 32 ) + exit ("Invalid number of tracks"); + info_l_->division_1_i_ = get_i (2) * 4; + if (info_l_->division_1_i_ < 0) + exit ("Cannot handle non-metrical time"); + // ugh + Duration::division_1_i_s = info_l_->division_1_i_; + forward_byte_L (length_i - 6); +} + +int +Midi_score_parser::find_earliest_i (Link_array& tracks) +{ + int earliest_i = 0; + Moment earliest_mom = infinity_mom; + for (int i = 0; i < tracks.size(); i++) + { + if ( tracks [i]->at_mom () < earliest_mom ) + { + earliest_mom = tracks [i]->at_mom (); + earliest_i = i; + } + } + return earliest_i; +} + +Mudela_score* +Midi_score_parser::parse_score () +{ + int current_bar_i = 0; + Mudela_meter m4 (4, 2, 24, 8); + Moment bar4_mom = m4.bar_mom (); + + Mudela_score* score_p = new Mudela_score( 1, 1, 1 ); + info_l_->score_l_ = score_p; + + Link_array tracks; + for (int i = 0; i < info_l_->tracks_i_; i++) + tracks.push (new Midi_track_parser (info_l_)); + + LOGOUT (NORMAL_ver) << "Parsing...\n"; + while (tracks.size ()) + { + int i = find_earliest_i (tracks); + Moment at_mom = tracks [i]->at_mom (); + Mudela_column* column_l = score_p->get_column_l (at_mom); + Mudela_staff* staff_p = tracks [i]->parse (column_l); + if ( staff_p ) + { + score_p->add_staff (staff_p); + delete tracks [i]; + tracks.del (i); + } + + // brr, musta have some progress + for (int ii = 0; !info_l_->bar_mom_ && ii < tracks.size (); ii++) + info_l_->bar_mom_ = tracks [ii]->info_l_->bar_mom_; + + int bar_i = (int) (at_mom + / (info_l_->bar_mom_ ? info_l_->bar_mom_ : bar4_mom)) + 1; + if (bar_i > current_bar_i) + { + LOGOUT (NORMAL_ver) << '[' << bar_i << ']' << flush; + current_bar_i = bar_i; + } + } + return score_p; +} + diff --git a/mi2mu/midi-track-parser.cc b/mi2mu/midi-track-parser.cc new file mode 100644 index 0000000000..028c3face3 --- /dev/null +++ b/mi2mu/midi-track-parser.cc @@ -0,0 +1,352 @@ +/* + midi-track-parser.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1997 Jan Nieuwenhuizen +*/ + +#include +#include "string-convert.hh" +#include "mi2mu-global.hh" +#include "midi-track-parser.hh" +#include "mudela-column.hh" +#include "mudela-item.hh" +#include "mudela-score.hh" +#include "mudela-staff.hh" + +Midi_track_parser::Midi_track_parser (Midi_parser_info* info_l) +{ + info_l_ = info_l; + at_mom_ = 0; + track_info_p_ = 0; + mudela_staff_p_ = new Mudela_staff (0, "", "", ""); + parse_header (); + parse_delta_time (); +} + +Midi_track_parser::~Midi_track_parser () +{ + delete mudela_staff_p_; + delete track_info_p_; +} + +Moment +Midi_track_parser::at_mom () +{ + return at_mom_; +} + +bool +Midi_track_parser::eot () +{ + if ( info_l_->byte_L_ < info_l_->end_byte_L_ ) + return false; + return true; +} + +void +Midi_track_parser::note_end (Mudela_column* col_l, int channel_i, int pitch_i, int aftertouch_i ) +{ + // junk dynamics + (void)aftertouch_i; + + for (PCursor i (open_note_l_list_.top ()); i.ok (); i++) + { + if ((i->pitch_i_ == pitch_i) && (i->channel_i_ == channel_i)) + { + i->end_column_l_ = col_l; + // LOGOUT(DEBUG_ver) << "Note: " << pitch_i; + // LOGOUT(DEBUG_ver) << "; " << i->mudela_column_l_->at_mom_; + // LOGOUT(DEBUG_ver) << ", " << i->end_column_l_->at_mom_ << "\n"; + i.remove_p(); + return; + } + } + warning (String ("junking note-end event: ") + + " channel = " + String_convert::i2dec_str (channel_i, 0, ' ') + + ", pitch = " + String_convert::i2dec_str (pitch_i, 0, ' ')); +} + +void +Midi_track_parser::note_end_all (Mudela_column* col_l) +{ + // find + for (PCursor i (open_note_l_list_.top ()); i.ok (); i++) + { + i->end_column_l_ = col_l; + i.remove_p(); + // ugh + if (!i.ok()) + break; + } +} + +Mudela_staff* +Midi_track_parser::parse (Mudela_column* col_l) +{ + Moment mom = at_mom (); + while (!eot () && (mom == at_mom ())) + { + Mudela_item* p = parse_event (col_l); + if (p) + mudela_staff_p_->add_item (p); + } + + if (!eot()) + return 0; + + Mudela_staff* p = mudela_staff_p_; + mudela_staff_p_ = 0; + return p; +} + +void +Midi_track_parser::parse_delta_time () +{ + if (eot ()) + return; + int delta_i = get_var_i (); + at_mom_ += Moment (delta_i, info_l_->division_1_i_); +} + +Mudela_item* +Midi_track_parser::parse_event (Mudela_column* col_l) +{ + Byte byte = peek_byte (); + // RUNNING_STATUS [\x00-\x5f] + if (byte <= 0x5f) + { + if (running_byte_ <= 0x5f) + exit ("Invalid running status"); + /* + 'running status' rather means 'missing status'. + we'll just pretend we read the running status byte. + */ + byte = running_byte_; + } + else + byte = next_byte (); + + Mudela_item* item_p = 0; + // DATA_ENTRY [\x60-\x79] + if ((byte >= 0x60) && (byte <= 0x79)) + { + next_byte (); + } + // ALL_NOTES_OFF [\x7a-\x7f] + else if ((byte >= 0x7a) && (byte <= 0x7f)) + { + next_byte (); + next_byte (); + note_end_all (col_l); + } + // NOTE_OFF [\x80-\x8f] + else if ((byte >= 0x80) && (byte <= 0x8f)) + { + running_byte_ = byte; + int channel_i = byte & ~0x90; + int pitch_i = (int)next_byte (); + int dyn_i = (int)next_byte (); + note_end (col_l, channel_i, pitch_i, dyn_i); + } + // NOTE_ON [\x90-\x9f] + else if ((byte >= 0x90) && (byte <= 0x9f)) + { + running_byte_ = byte; + int channel_i = byte & ~0x90; + int pitch_i = (int)next_byte (); + int dyn_i = (int)next_byte (); + /* + sss: some broken devices encode NOTE_OFF as + NOTE_ON with zero volume + */ + if (dyn_i) + { + Mudela_note* p = new Mudela_note (col_l, channel_i, pitch_i, dyn_i); + item_p = p; + open_note_l_list_.bottom ().add (p); + } + else + { + note_end (col_l, channel_i, pitch_i, dyn_i); + } + } + // POLYPHONIC_AFTERTOUCH [\xa0-\xaf] + else if ((byte >= 0xa0) && (byte <= 0xaf)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // CONTROLMODE_CHANGE [\xb0-\xbf] + else if ((byte >= 0xb0) && (byte <= 0xbf)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // PROGRAM_CHANGE [\xc0-\xcf] + else if ((byte >= 0xc0) && (byte <= 0xcf)) + { + running_byte_ = byte; + next_byte (); + } + // CHANNEL_AFTERTOUCH [\xd0-\xdf] + else if ((byte >= 0xd0) && (byte <= 0xdf)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // PITCHWHEEL_RANGE [\xe0-\xef] + else if ((byte >= 0xe0) && (byte <= 0xef)) + { + running_byte_ = byte; + next_byte (); + next_byte (); + } + // SYSEX_EVENT1 [\xf0] + else if (byte == 0xf0) + { + int length_i = get_var_i (); + String str = get_str (length_i); + } + // SYSEX_EVENT2 [\xf7] + else if (byte == 0xf7) + { + int length_i = get_var_i (); + String str = get_str (length_i); + } + // META_EVENT [\xff] + else if (byte == 0xff) + { + // SEQUENCE [\x00][\x02] + byte = next_byte (); + if (byte == 0) + { + next_byte (); + get_i (2); + } + // YYTEXT [\x01] + // YYCOPYRIGHT [\x02] + // YYTRACK_NAME [\x03] + // YYINSTRUMENT_NAME [\x04] + // YYLYRIC [\x05] + // YYMARKER [\x06] + // YYCUE_POINT [\x07] + else if ((byte >= 0x01) && (byte <= 0x07)) + { + // LOGOUT (DEBUG_ver) << "\n% Text(" << (int)byte << "):" << flush; + int length_i = get_var_i (); + String str = get_str (length_i); + // LOGOUT (DEBUG_ver) << str << endl; + Mudela_text::Type t = (Mudela_text::Type)byte; + Mudela_text* p = new Mudela_text (t, str); + item_p = p; + if (t == Mudela_text::COPYRIGHT) + mudela_staff_p_->copyright_str_ = p->text_str_; + else if (t == Mudela_text::TRACK_NAME) + mudela_staff_p_->name_str_ = p->text_str_; + else if (t == Mudela_text::INSTRUMENT_NAME) + mudela_staff_p_->instrument_str_ = p->text_str_; + } + // END_OF_TRACK [\x2f][\x00] + else + { + Byte next = peek_byte (); + if ((byte == 0x2f) && (next == 0x00)) + { + next_byte (); + info_l_->byte_L_ = info_l_->end_byte_L_; + } + // TEMPO [\x51][\x03] + else if ((byte == 0x51) && (next == 0x03)) + { + next_byte (); + unsigned useconds_per_4_u = get_u (3); + // $$ = new Mudela_tempo ( ($2 << 16) + ($3 << 8) + $4); + // LOGOUT (DEBUG_ver) << $$->str() << endl; + Mudela_tempo* p = new Mudela_tempo ( useconds_per_4_u ); + item_p = p; + info_l_->score_l_->mudela_tempo_l_ = p; + } + // SMPTE_OFFSET [\x54][\x05] + else if ((byte == 0x54) && (next == 0x05)) + { + next_byte (); + (int)next_byte (); + (int)next_byte (); + (int)next_byte (); + (int)next_byte (); + (int)next_byte (); + } + // TIME [\x58][\x04] + else if ((byte == 0x58) && (next == 0x04)) + { + next_byte (); + int num_i = (int)next_byte (); + int den_i = (int)next_byte (); + int clocks_4_i = (int)next_byte (); + int count_32_i = (int)next_byte (); + Mudela_meter* p = new Mudela_meter ( num_i, den_i, clocks_4_i, count_32_i ); + item_p = p; + info_l_->score_l_->mudela_meter_l_ = p; + info_l_->bar_mom_ = p->bar_mom (); + } + // KEY [\x59][\x02] + else if ((byte == 0x59) && (next == 0x02)) + { + next_byte (); + int accidentals_i = (int)next_byte (); + int minor_i = (int)next_byte (); + Mudela_key* p = new Mudela_key (accidentals_i, minor_i); + item_p = p; + info_l_->score_l_->mudela_key_l_ = p; + } + // SSME [\0x7f][\x03] + else if ((byte == 0x7f) && (next == 0x03)) + { + next_byte (); + int length_i = get_var_i (); + String str = get_str (length_i); + item_p = new Mudela_text ((Mudela_text::Type)byte, str); + } + else + { + next_byte (); + next_byte (); + warning ("Unimplemented MIDI meta-event"); + } + } + } + else + exit ("Invalid MIDI event"); + + if (item_p) + item_p->mudela_column_l_ = col_l; + + parse_delta_time (); + + return item_p; +} + +void +Midi_track_parser::parse_header () +{ + String str = get_str (4); + if ( str != "MTrk" ) + exit ("MIDI track expected"); + + int length_i = get_i (4); + // is this signed? + if (length_i < 0) + exit ("Invalid track length"); + assert (!track_info_p_); + track_info_p_ = new Midi_parser_info (*info_l_); + track_info_p_->end_byte_L_ = track_info_p_->byte_L_ + length_i; + forward_byte_L (length_i); +// forward_byte_L (length_i-1); + info_l_ = track_info_p_; +} + diff --git a/mi2mu/mudela-item.cc b/mi2mu/mudela-item.cc index 3179662b72..7a69984b9a 100644 --- a/mi2mu/mudela-item.cc +++ b/mi2mu/mudela-item.cc @@ -3,6 +3,7 @@ // // copyright 1997 Jan Nieuwenhuizen +#include #include "mi2mu-global.hh" #include "string-convert.hh" #include "duration-convert.hh" @@ -17,13 +18,13 @@ Mudela_item::Mudela_item (Mudela_column* mudela_column_l) } Moment -Mudela_item::at_mom() +Mudela_item::at_mom () { - return mudela_column_l_->at_mom(); + return mudela_column_l_->at_mom (); } Moment -Mudela_item::duration_mom() +Mudela_item::duration_mom () { return Moment (0); } @@ -31,7 +32,7 @@ Mudela_item::duration_mom() void Mudela_item::output (Mudela_stream& mudela_stream_r) { - mudela_stream_r << str() << String (" "); + mudela_stream_r << str () << String (" "); } Mudela_key::Mudela_key (int accidentals_i, int minor_i) @@ -39,22 +40,23 @@ Mudela_key::Mudela_key (int accidentals_i, int minor_i) { accidentals_i_ = accidentals_i; minor_i_ = minor_i; - if (accidentals_i >= 0) - key_i_ = ((accidentals_i % 7)[ "cgdaebf" ] - 'a' - 2) % 7; - else - key_i_ = ((-accidentals_i % 7)[ "cfbeadg" ] - 'a' - 2) % 7; } String -Mudela_key::str() +Mudela_key::str () { + int key_i = 0; + if (accidentals_i_ >= 0) + key_i = ((accidentals_i_ % 7)[ "cgdaebf" ] - 'a' - 2) % 7; + else + key_i = ((-accidentals_i_ % 7)[ "cfbeadg" ] - 'a' - 2) % 7; String str = "\\key "; - if (!minor_i_) - str += String ((char) ((key_i_ + 2) % 7 + 'A')); + if (!minor_i_) + str += String ((char) ((key_i + 2) % 7 + 'A')); else // heu, -2: should be - 1 1/2: A -> fis - str += String ((char) ((key_i_ + 2 - 2) % 7 + 'a')); + str += String ((char) ((key_i + 2 - 2) % 7 + 'a')); str = String ("% \"") + str - + String('"') + "; % not supported yet\n"; + + String ('"') + "; % not supported yet\n"; return str; } @@ -71,7 +73,7 @@ Mudela_key::notename_str (int pitch_i) static int accidentals_i_a[ 12 ] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 }; int accidental_i = accidentals_i_a[ minor_i_ * 5 + pitch_i % 12 ]; - if (accidental_i && (accidentals_i_ < 0)) + if (accidental_i && (accidentals_i_ < 0)) { accidental_i = - accidental_i; notename_i = (notename_i + 1) % 7; @@ -96,9 +98,9 @@ Mudela_key::notename_str (int pitch_i) Mudela_meter::Mudela_meter (int num_i, int den_i, int clocks_4_i, int count_32_i) : Mudela_item (0) { - sync_dur_.durlog_i_ = 3 ; + sync_dur_.durlog_i_ = 3; sync_f_ = 1.0; - if (count_32_i != 8) + if (count_32_i != 8) warning (String ("#32 in quarter: ") + String (count_32_i)); num_i_ = num_i; den_i_ = den_i; @@ -106,33 +108,33 @@ Mudela_meter::Mudela_meter (int num_i, int den_i, int clocks_4_i, int count_32_i } Moment -Mudela_meter::bar_mom() +Mudela_meter::bar_mom () { Duration d; - d.durlog_i_ = den_i_; + d.durlog_i_ = den_i_; return Moment (num_i_) * Duration_convert::dur2_mom (d); } int -Mudela_meter::clocks_1_i() +Mudela_meter::clocks_1_i () { return clocks_1_i_; } int -Mudela_meter::den_i() +Mudela_meter::den_i () { return den_i_; } int -Mudela_meter::num_i() +Mudela_meter::num_i () { return num_i_; } String -Mudela_meter::str() +Mudela_meter::str () { String str = "\\meter " + String (num_i_) + "/" + String (1 << den_i_) @@ -160,22 +162,38 @@ Mudela_note::Mudela_note (Mudela_column* mudela_column_l, int channel_i, int pit end_column_l_ = 0; } +Duration +Mudela_note::duration () +{ + assert (end_column_l_); + Moment mom = end_column_l_->at_mom () - at_mom (); + return Duration_convert::mom2_dur (mom); +} + +Moment +Mudela_note::duration_mom () +{ +// ugh +// return Duration_convert::dur2_mom (duration ()); + return end_column_l_->at_mom () - at_mom (); +} + String -Mudela_note::str() +Mudela_note::str () { - Duration dur = duration(); - if (dur.durlog_i_ < -10) + Duration dur = duration (); + if (dur.durlog_i_ < -10) return ""; String name_str = mudela_column_l_->mudela_score_l_->mudela_key_l_->notename_str (pitch_i_); - if (simple_plet_b_s) + if (simple_plet_b_s) return name_str + Duration_convert::dur2_str (dur) + " "; //ugh String str; - if (dur.plet_b()) + if (dur.plet_b ()) str += String ("\\plet ") + String_convert::i2dec_str (dur.plet_.iso_i_, 0, 0) + "/" @@ -188,28 +206,12 @@ Mudela_note::str() tmp.set_plet (1,1); str += Duration_convert::dur2_str (tmp); - if (dur.plet_b()) + if (dur.plet_b ()) str += String (" \\plet 1/1;"); return str + " "; } -Duration -Mudela_note::duration() -{ - assert (end_column_l_); - Moment mom = end_column_l_->at_mom() - at_mom(); - return Duration_convert::mom2_dur (mom); -} - -Moment -Mudela_note::duration_mom() -{ -// ugh -// return Duration_convert::dur2_mom (duration()); - return end_column_l_->at_mom() - at_mom(); -} - Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom) : Mudela_item (mudela_column_l) { @@ -217,25 +219,25 @@ Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom) } Duration -Mudela_skip::duration() +Mudela_skip::duration () { return Duration_convert::mom2_dur (mom_); } Moment -Mudela_skip::duration_mom() +Mudela_skip::duration_mom () { - return Duration_convert::dur2_mom (duration()); + return Duration_convert::dur2_mom (duration ()); } String -Mudela_skip::str() +Mudela_skip::str () { - if (!mom_) + if (!mom_) return String (""); - Duration dur = duration(); - if (dur.durlog_i_<-10) + Duration dur = duration (); + if (dur.durlog_i_<-10) return ""; String str = "\\skip "; @@ -252,7 +254,7 @@ Mudela_tempo::Mudela_tempo (int useconds_per_4_i) } String -Mudela_tempo::str() +Mudela_tempo::str () { String str = "\\tempo 4="; str += String (get_tempo_i (Moment (1, 4))); @@ -261,7 +263,7 @@ Mudela_tempo::str() } int -Mudela_tempo::useconds_per_4_i() +Mudela_tempo::useconds_per_4_i () { return useconds_per_4_i_; } @@ -280,10 +282,10 @@ Mudela_text::Mudela_text (Mudela_text::Type type, String text_str) } String -Mudela_text::str() +Mudela_text::str () { - if (!text_str_.length_i() - || (text_str_.length_i() != (int)strlen (text_str_.ch_C()))) + if (!text_str_.length_i () + || (text_str_.length_i () != (int)strlen (text_str_.ch_C ()))) return ""; return "% " + text_str_ + "\n"; diff --git a/mi2mu/mudela-score.cc b/mi2mu/mudela-score.cc index 843bab56c7..75205c2ddd 100644 --- a/mi2mu/mudela-score.cc +++ b/mi2mu/mudela-score.cc @@ -3,6 +3,7 @@ // // copyright 1997 Jan Nieuwenhuizen +#include #include "moment.hh" #include "duration.hh" #include "duration-convert.hh" @@ -13,12 +14,21 @@ #include "mudela-staff.hh" #include "mudela-stream.hh" +//static Mudela_key key_c (0, 0); +static Mudela_meter meter_4 (4, 2, 24, 8); +// useconds per 4: 250000 === 60 4 per minute +static Mudela_tempo tempo_60 (1000000); + Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i) { format_i_ = format_i; tracks_i_ = tracks_i; tempo_i_ = tempo_i; - mudela_column_p_list_.bottom().add (new Mudela_column (this, Moment (0))); + column_l_array_.push (new Mudela_column (this, Moment (0))); +// mudela_key_l_ = &key_c; + mudela_key_l_ = 0; + mudela_meter_l_ = &meter_4; + mudela_tempo_l_ = &tempo_60; } Mudela_score::~Mudela_score() @@ -38,23 +48,54 @@ Mudela_score::add_staff (Mudela_staff* mudela_staff_p) } Mudela_column* -Mudela_score::mudela_column_l (Moment mom) +Mudela_score::find_column_l (Moment mom) { - for (PCursor i (mudela_column_p_list_); i.ok(); i++) +#if 0 + // should do binary search + for (int i = 0; i < column_l_array_.size (); i++ ) + if ( column_l_array_[i]->at_mom () == mom ) + return column_l_array_[i]; + return 0; +#else + int upper_i = max (0, column_l_array_.size () - 1); + int lower_i = 0; + int i = 0; //upper_i; + while (1) { - if (i->at_mom() > mom) - { - Mudela_column* p = new Mudela_column (this, mom); - i.insert (p); - return p; - } - if (i->at_mom() == mom) - return *i; + Moment i_mom = column_l_array_ [i]->at_mom (); + if (i_mom == mom) + return column_l_array_ [i]; + if (mom < i_mom) + upper_i = i; + else + lower_i = i; + if ((upper_i == lower_i) || (i == column_l_array_.size () - 1)) + { + // we don't do inserts + assert (0); + Mudela_column* col_p = new Mudela_column (this, mom); + column_l_array_.push (col_p); + return col_p; + } + i = (upper_i + lower_i + 1 ) / 2; } + assert (0); + return 0; +#endif +} - Mudela_column* p = new Mudela_column (this, mom); - mudela_column_p_list_.bottom().add (p); - return p; +Mudela_column* +Mudela_score::get_column_l (Moment mom) +{ + if ( column_l_array_ [column_l_array_.size() - 1]->at_mom () > mom ) + { + error ("ugh"); + exit (1); + } + if ( column_l_array_[column_l_array_.size() - 1]->at_mom () < mom ) + column_l_array_.push (new Mudela_column (this, mom)); + + return column_l_array_ [column_l_array_.size() - 1]; } void @@ -93,7 +134,7 @@ Mudela_score::output (String filename_str) mudela_stream << "\\paper{}\n"; - mudela_stream << "\\midi{ "; + mudela_stream << "\\midi{\n"; // let's not use silly 0 track mudela_staff_p_list_.bottom()->mudela_tempo_p_->output (mudela_stream); mudela_stream << "}\n"; @@ -107,8 +148,8 @@ Mudela_score::process() LOGOUT(NORMAL_ver) << "\nProcessing..." << endl; LOGOUT(DEBUG_ver) << "columns\n"; - for (PCursor i (mudela_column_p_list_); i.ok(); i++) - LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << "\n"; +// for (PCursor i (mudela_column_p_list_); i.ok(); i++) +// LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << "\n"; settle_columns(); filter_tempo(); @@ -143,17 +184,24 @@ Mudela_score::quantify_columns() LOGOUT(NORMAL_ver) << "\nQuantifying columns..." << endl; + int current_bar_i = 0; + Moment bar_mom = mudela_meter_l_->bar_mom(); + int n = 5 >? Duration_convert::no_smaller_than_i_s; + n = Duration_convert::type2_i (n); Moment s = Moment (1, n); Moment sh = Moment (1, 2 * n); for (int i = 0; i < column_l_array_.size(); i++) { -// Moment mom = column_l_array_[ i ]->at_mom(); -// column_l_array_[ i ]->at_mom_ = Duration_convert::dur2_mom (dur); - column_l_array_[ i ]->at_mom_ = -// s * (int) ( (sh + column_l_array_[ i ]->at_mom()) / s); - s * (int) ( (column_l_array_[ i ]->at_mom()) / s); - LOGOUT(NORMAL_ver) << '.'; + column_l_array_ [i]->at_mom_ = + s * (int) ( (column_l_array_ [i]->at_mom()) / s); + + int bar_i = (int) (column_l_array_ [i]->at_mom () / bar_mom) + 1; + if (bar_i > current_bar_i) + { + LOGOUT (NORMAL_ver) << '[' << bar_i << ']' << flush; + current_bar_i = bar_i; + } } LOGOUT(NORMAL_ver) << endl; } @@ -171,12 +219,16 @@ Mudela_score::settle_columns() // return; LOGOUT(NORMAL_ver) << "\nSettling columns..." << endl; +#if 0 assert (!column_l_array_.size()); int n = mudela_column_p_list_.size(); // huh? // column_l_array_.set_size (n); for (PCursor i (mudela_column_p_list_); i.ok(); i++) column_l_array_.push (*i); +#endif + + int n = column_l_array_.size(); int start_i = 0; int end_i = 0; @@ -190,18 +242,18 @@ Mudela_score::settle_columns() if (!start_i) { start_i = end_i = i; - start_mom = column_l_array_[ i ]->at_mom(); + start_mom = column_l_array_ [i]->at_mom(); continue; } // find all columns within noise's distance while ( (i < n) - && (column_l_array_[ i ]->at_mom() - start_mom < noise_mom)) + && (column_l_array_ [i]->at_mom() - start_mom < noise_mom)) end_i = ++i; // bluntly set all to time of first in group for (int j = start_i; j < end_i; j++) - column_l_array_[ j ]->at_mom_ = start_mom; + column_l_array_ [j]->at_mom_ = start_mom; start_i = end_i = 0; } -- 2.39.5