This document describes the the LilyPond input format, which is an
effective language for definining music. We call this language
-(rather arrogantly) The Musical Definition Language (S<Mudela 2>).
+(rather arrogantly) The Musical Definition Language (S<Mudela 0.1>).
The first aim of Mudela is to define a piece of music,
being complete from both from a musical typesetting,
followed by alpha-numerics. Identifiers can contain any characters
(except whitespace, C<$> and C<%>), if you use this construct:
- $Id_with###@weird92chars =
+ $i'm_a_weird###identifier
+
+(which is the identifier with the name
+C<i'm_a_weird###identifier> ). C<$> Takes any sequence of
+characters which are not whitespace, C<$> and C<%>.
+
+ \$i'm_a_weird###escaped_word
=head2 Nesting characters
Mudela uses the brace (C<{> and C<}>) for hierarchical structures. To
-aid the eye in reading, for chords the C<<> and the C<>> are used as
+aid the eye in reading, for chords the < and the > are used as
nesting braces.
=head2 Identifiers
Most instantiations that use an IDENTIFIER are specified as follows:
- \TYPE { IDENTIFIER [...] }
+ \TYPE{ IDENTIFIER [...] }
Some exceptions on this rule have been made to prevent inputting
Mudela becoming tedious
maintenance no long examples are included in this document.
+=head1 INTERNALS
+
+This chapter deals with the internals of Mudela. In the end Mudela
+converted to Voice, which contain Voice_elements which (in turn)
+contain Requests. The former 2 types are basically containers.
+Consider the following simple mudela
+
+ \music { c4 <e4 g4> }
+
+After the parsing, this is converted to: (from the debug output)
+
+ Voice { start: 0
+ voice_element { dur :1/4
+ Stem_req {duration { 4}}
+ Note_req {notename: 0 acc: 0 oct: -1
+ duration { 4}}
+ Group_change_req {}
+ }
+ voice_element { dur :0
+ Terminate_voice_req {}
+ }
+ }
+
+ Voice { start: 1/4
+ voice_element { dur :1/4
+ Stem_req {duration { 4}}
+ Note_req {notename: 2 acc: 0 oct: -1
+ duration { 4}}
+ Group_change_req {}
+ }
+ voice_element { dur :0
+ Terminate_voice_req {}
+ }
+ }
+
+ Voice { start: 1/4
+ voice_element { dur :1/4
+ Stem_req {duration { 4}}
+ Note_req {notename: 4 acc: 0 oct: -1
+ duration { 4}}
+ Group_change_req {}
+ }
+ voice_element { dur :0
+ Terminate_voice_req {}
+ }
+ }
+
+
=head2 Requests
+As you can see, most information is stored in the form of a request.
+In music typesetting, the user might want to cram a lot more symbols
+on the paper than actually fits. To reflect this idea (the user asks
+more than we can do), the container for this data is called Request.
+
+A request is done to
+the C<Staff> which contains the C<Voice_element>. The staff decides
+whether to to honor the request, ignore it, or merge it with other
+requests. Merging of requests is preferably done with other requests
+done by members of the same voicegroups (beams, brackets, stems)
+
+Please refer to the documentation of the Child classes of
+C<Request> for explanation of each request type.
+
+The result of a request will be an C<Item> or a C<Spanner>, which
+will be put on a C<PStaff>. Note that the C<PStaff> and the original
+C<Staff> need not have anything in common. For example, the
+``double'' piano Staff could interpret commands which juggle
+melodies across the left and right hand, and may put the result in
+two five-line PStaffs (maybe with extra PStaffs to carry the dynamic
+signs and any lyric.
+
+The class C<Staff> should be thought as a container for the
+C<Voice>s, and an interpreter for C<Request>s and C<Command>s.
+Different staffs can produce different outputs; a melodious voice
+which is put into a percussion-Staff, will be typeset as the rythm of
+that voice.
+
+After C<Staff> made up her mind, the resultant items and
+spanners are put on the PScore.
+
+=over 5
+
+=item C<Barcheck_req>
+
+Checks during music processing if start of this voice element
+coincides with the start of a measure. Handy to check if you left out
+some voice elts.
+
+=item C<Note_req>
+
+Staff has to decide if the ball should be hanging left or right. This
+influences the horizontal dimensions of a column, and this is why
+request processing should be done before horizontal spacing.
+
+Other voices' frivolities may cause the need for accidentals, so this
+is also for the C<Staff> to decide. The C<Staff> can decide on positioning
+based on ottava commands and the appropriate clef.
+
+=item C<Rest_req>
+
+Why a request? It might be a good idea to not typeset the rest, if the
+paper is too crowded.
+
+=item C<Span_req>
+
+This type of request typically results in the creation of a C<Spanner>
+
+=item C<Beam_req>
+
+Staff has to combine this request with the stem_request, since the
+number of flags that a stem wants to carry will determine the
+number of beams.
+
+=item C<Dynamic>
+
+Each dynamic is bound to one note (a crescendo spanning multiple
+notes is thought to be made of two "dynamics": a start and a stop).
+Dynamic changes can occur in a smaller time than the length of its
+note, therefore fore each C<Dynamic> request carries a time, measured
+from the start of its note.
+
=head2 Voice
=head2 Voice_element
+pl 45
+ - Removing unused Voice_regs & Voice_groups
+ - -O2 bugfix
+
+pl 44.jcn1
+ - merged 42.3 42.jcn4 code trees (see stuff below)
+ - moving towards Mudela 0.1 (again)
+ * keyword "music" dropped for horizontal music
+ * keywords "\lyric" "\melodic" introduced, e.g.:
+ melody = \melodic { c c | g g }
+ * removed level of indirection:
+ - staff initialisable with music identifier list:
+ \staff{ global melody }
+ - \score and staffs alike
+ - gnu standard(?) help texts
+ - configure "creates" toplevel Makefile from make/Toplevel.make
+
+Bugfix
+ - fixed mi2mu
+ - write meter to track0 too...
+ - default octave
+ - new Sources in My_midi_lexer: sourcefile_p_ = get_file_l(): oeps.
+ (ain-t hungarian grand?)
+
+Examples
+ - updated for mudela 0.1
+
******
pl 44
+ - naming: _c_l -> _C
- pure parser, My_lily_parser
- ''a iso ``a
- Includable_lexer
- declaration used check.
-
+pl 42.jcn4
+ - lily writes midi meter/key changes from requests
+ - mi2mu:
+ + write mudela 0.1
+ + write bar change requests
+ + more tunable quantisation
+
+Examples
+ - half-new-menuetto.ly converted to mudela -almost- 0.1
+ - new mi2mu of bach's wtk pre1/fugue1
+
+pl 42.3 (jcn version)
+ - oeps, branched source tree
+
pl 42.hwn3
- const naming change (T const <-> const T)
- Mudela 0.1 (roughly the same as below..)
pl 42.3
- moving towards Mudela 0.1:
- * (almost) all keywords must be preceded by backslash '\'
+ * all keywords must be preceded by backslash '\'
* explicit lexer switches '$' and '@' dropped
* keyword "music" dropped for horizontal music
* keywords "\lyric" " introduced, e.g.:
% common dutch names for notes. "es" means flat, "is" means sharp
%
-ceses = \melodic { -1 0 -2 }
-ces = \melodic { -1 0 -1 }
-c = \melodic { -1 0 0 }
-cis = \melodic { -1 0 1 }
-cisis = \melodic { -1 0 2 }
-deses = \melodic { -1 1 -2 }
-des = \melodic { -1 1 -1 }
-d = \melodic { -1 1 0 }
-dis = \melodic { -1 1 1 }
-disis = \melodic { -1 1 2 }
-eses = \melodic { -1 2 -2 }
-es = \melodic { -1 2 -1 }
-e = \melodic { -1 2 0 }
-eis = \melodic { -1 2 1 }
-eisis = \melodic { -1 2 2 }
-feses = \melodic { -1 3 -2 }
-fes = \melodic { -1 3 -1 }
-f = \melodic { -1 3 0 }
-fis = \melodic { -1 3 1 }
-fisis = \melodic { -1 3 2 }
-geses = \melodic { -1 4 -2 }
-ges = \melodic { -1 4 -1 }
-g = \melodic { -1 4 0 }
-gis = \melodic { -1 4 1 }
-gisis = \melodic { -1 4 2 }
-ases = \melodic { -1 5 -2 }
-as = \melodic { -1 5 -1 }
-a = \melodic { -1 5 0 }
-ais = \melodic { -1 5 1 }
-aisis = \melodic { -1 5 2 }
-beses = \melodic { -1 6 -2 }
-bes = \melodic { -1 6 -1 }
-b = \melodic { -1 6 0 }
-bis = \melodic { -1 6 1 }
-bisis = \melodic { -1 6 2 }
+
+%
+% Please note that, while these names are used to enter *notes*, they
+% actually are *melodic*s, i.e. they represent a pitch solely. Notes
+% have a rhythmic part too. This is the reason that we don't write 'note { .. }'
+%
+ceses = \melodic_request { -1 0 -2 }
+ces = \melodic_request { -1 0 -1 }
+c = \melodic_request { -1 0 0 }
+cis = \melodic_request { -1 0 1 }
+cisis = \melodic_request { -1 0 2 }
+deses = \melodic_request { -1 1 -2 }
+des = \melodic_request { -1 1 -1 }
+d = \melodic_request { -1 1 0 }
+dis = \melodic_request { -1 1 1 }
+disis = \melodic_request { -1 1 2 }
+eses = \melodic_request { -1 2 -2 }
+es = \melodic_request { -1 2 -1 }
+e = \melodic_request { -1 2 0 }
+eis = \melodic_request { -1 2 1 }
+eisis = \melodic_request { -1 2 2 }
+feses = \melodic_request { -1 3 -2 }
+fes = \melodic_request { -1 3 -1 }
+f = \melodic_request { -1 3 0 }
+fis = \melodic_request { -1 3 1 }
+fisis = \melodic_request { -1 3 2 }
+geses = \melodic_request { -1 4 -2 }
+ges = \melodic_request { -1 4 -1 }
+g = \melodic_request { -1 4 0 }
+gis = \melodic_request { -1 4 1 }
+gisis = \melodic_request { -1 4 2 }
+ases = \melodic_request { -1 5 -2 }
+as = \melodic_request { -1 5 -1 }
+a = \melodic_request { -1 5 0 }
+ais = \melodic_request { -1 5 1 }
+aisis = \melodic_request { -1 5 2 }
+beses = \melodic_request { -1 6 -2 }
+bes = \melodic_request { -1 6 -1 }
+b = \melodic_request { -1 6 0 }
+bis = \melodic_request { -1 6 1 }
+bisis = \melodic_request { -1 6 2 }
%
%
-Ceses = \melodic { -2 0 -2 }
-Ces = \melodic { -2 0 -1 }
-C = \melodic { -2 0 0 }
-Cis = \melodic { -2 0 1 }
-Cisis = \melodic { -2 0 2 }
-Deses = \melodic { -2 1 -2 }
-Des = \melodic { -2 1 -1 }
-D = \melodic { -2 1 0 }
-Dis = \melodic { -2 1 1 }
-Disis = \melodic { -2 1 2 }
-Eses = \melodic { -2 2 -2 }
-Es = \melodic { -2 2 -1 }
-E = \melodic { -2 2 0 }
-Eis = \melodic { -2 2 1 }
-Eisis = \melodic { -2 2 2 }
-Feses = \melodic { -2 3 -2 }
-Fes = \melodic { -2 3 -1 }
-F = \melodic { -2 3 0 }
-Fis = \melodic { -2 3 1 }
-Fisis = \melodic { -2 3 2 }
-Geses = \melodic { -2 4 -2 }
-Ges = \melodic { -2 4 -1 }
-G = \melodic { -2 4 0 }
-Gis = \melodic { -2 4 1 }
-Gisis = \melodic { -2 4 2 }
-Ases = \melodic { -2 5 -2 }
-As = \melodic { -2 5 -1 }
-A = \melodic { -2 5 0 }
-Ais = \melodic { -2 5 1 }
-Aisis = \melodic { -2 5 2 }
-Beses = \melodic { -2 6 -2 }
-Bes = \melodic { -2 6 -1 }
-B = \melodic { -2 6 0 }
-Bis = \melodic { -2 6 1 }
-Bisis = \melodic { -2 6 2 }
+Ceses = \melodic_request { -2 0 -2 }
+Ces = \melodic_request { -2 0 -1 }
+C = \melodic_request { -2 0 0 }
+Cis = \melodic_request { -2 0 1 }
+Cisis = \melodic_request { -2 0 2 }
+Deses = \melodic_request { -2 1 -2 }
+Des = \melodic_request { -2 1 -1 }
+D = \melodic_request { -2 1 0 }
+Dis = \melodic_request { -2 1 1 }
+Disis = \melodic_request { -2 1 2 }
+Eses = \melodic_request { -2 2 -2 }
+Es = \melodic_request { -2 2 -1 }
+E = \melodic_request { -2 2 0 }
+Eis = \melodic_request { -2 2 1 }
+Eisis = \melodic_request { -2 2 2 }
+Feses = \melodic_request { -2 3 -2 }
+Fes = \melodic_request { -2 3 -1 }
+F = \melodic_request { -2 3 0 }
+Fis = \melodic_request { -2 3 1 }
+Fisis = \melodic_request { -2 3 2 }
+Geses = \melodic_request { -2 4 -2 }
+Ges = \melodic_request { -2 4 -1 }
+G = \melodic_request { -2 4 0 }
+Gis = \melodic_request { -2 4 1 }
+Gisis = \melodic_request { -2 4 2 }
+Ases = \melodic_request { -2 5 -2 }
+As = \melodic_request { -2 5 -1 }
+A = \melodic_request { -2 5 0 }
+Ais = \melodic_request { -2 5 1 }
+Aisis = \melodic_request { -2 5 2 }
+Beses = \melodic_request { -2 6 -2 }
+Bes = \melodic_request { -2 6 -1 }
+B = \melodic_request { -2 6 0 }
+Bis = \melodic_request { -2 6 1 }
+Bisis = \melodic_request { -2 6 2 }
-%
+%%
+% Please note that, while these names are used to enter *notes*, they
+% actually are *melodic*s, i.e. they represent a pitch solely. Notes
+% have a rhythmic part too. This is the reason that we don't write 'note
% common Swedish names for notes. "-ess" means flat, "-iss" means sharp
%
% by Mats Bengtsson.
-cessess = \melodic { 0 0 -2 }
-cess = \melodic { 0 0 -1 }
-c = \melodic { 0 0 0 }
-ciss = \melodic { 0 0 1 }
-cississ = \melodic { 0 0 2 }
-dessess = \melodic { 0 1 -2 }
-dess = \melodic { 0 1 -1 }
-d = \melodic { 0 1 0 }
-diss = \melodic { 0 1 1 }
-dississ = \melodic { 0 1 2 }
-essess = \melodic { 0 2 -2 }
-ess = \melodic { 0 2 -1 }
-e = \melodic { 0 2 0 }
-eiss = \melodic { 0 2 1 }
-eississ = \melodic { 0 2 2 }
-fessess = \melodic { 0 3 -2 }
-fess = \melodic { 0 3 -1 }
-f = \melodic { 0 3 0 }
-fiss = \melodic { 0 3 1 }
-fississ = \melodic { 0 3 2 }
-gessess = \melodic { 0 4 -2 }
-gess = \melodic { 0 4 -1 }
-g = \melodic { 0 4 0 }
-giss = \melodic { 0 4 1 }
-gississ = \melodic { 0 4 2 }
-assess = \melodic { 0 5 -2 }
-ass = \melodic { 0 5 -1 }
-a = \melodic { 0 5 0 }
-aiss = \melodic { 0 5 1 }
-aississ = \melodic { 0 5 2 }
-hessess = \melodic { 0 6 -2 }
-b = \melodic { 0 6 -1 }
-h = \melodic { 0 6 0 }
-hiss = \melodic { 0 6 1 }
-hississ = \melodic { 0 6 2 }
+cessess = \melodic_request { 0 0 -2 }
+cess = \melodic_request { 0 0 -1 }
+c = \melodic_request { 0 0 0 }
+ciss = \melodic_request { 0 0 1 }
+cississ = \melodic_request { 0 0 2 }
+dessess = \melodic_request { 0 1 -2 }
+dess = \melodic_request { 0 1 -1 }
+d = \melodic_request { 0 1 0 }
+diss = \melodic_request { 0 1 1 }
+dississ = \melodic_request { 0 1 2 }
+essess = \melodic_request { 0 2 -2 }
+ess = \melodic_request { 0 2 -1 }
+e = \melodic_request { 0 2 0 }
+eiss = \melodic_request { 0 2 1 }
+eississ = \melodic_request { 0 2 2 }
+fessess = \melodic_request { 0 3 -2 }
+fess = \melodic_request { 0 3 -1 }
+f = \melodic_request { 0 3 0 }
+fiss = \melodic_request { 0 3 1 }
+fississ = \melodic_request { 0 3 2 }
+gessess = \melodic_request { 0 4 -2 }
+gess = \melodic_request { 0 4 -1 }
+g = \melodic_request { 0 4 0 }
+giss = \melodic_request { 0 4 1 }
+gississ = \melodic_request { 0 4 2 }
+assess = \melodic_request { 0 5 -2 }
+ass = \melodic_request { 0 5 -1 }
+a = \melodic_request { 0 5 0 }
+aiss = \melodic_request { 0 5 1 }
+aississ = \melodic_request { 0 5 2 }
+hessess = \melodic_request { 0 6 -2 }
+b = \melodic_request { 0 6 -1 }
+h = \melodic_request { 0 6 0 }
+hiss = \melodic_request { 0 6 1 }
+hississ = \melodic_request { 0 6 2 }
mtor << "rest:"<< yylval.string;
return RESTNAME;
}
-<INITIAL,lyrics,notes>\$\\{BLACK}*{WHITE} {
+<INITIAL,lyrics,notes>\\\${BLACK}*{WHITE} {
String s=YYText() + 2;
s=s.left_str(s.length_i() - 1);
return scan_escaped_word(s);
%token GEOMETRIC
%token GROUPING
%token IN_T
-%token LYRICS
+%token LYRIC
%token KEY
%token MELODIC
+%token MELODIC_REQUEST
%token METER
%token MIDI
%token MM_T
%token MULTIVOICE
-%token MUSIC
+%token NOTE
%token OCTAVECOMMAND
%token OUTPUT
%token PAPER
$$ = $4;
$$-> defined_ch_C_ = THIS->define_spot_array_.pop();
}
+ | { THIS->remember_spot(); }
+/*cont*/ STAFF_IDENTIFIER {
+ $$ = $2->staff(true);
+ $$-> defined_ch_C_ = THIS->define_spot_array_.pop();
+ }
;
staff_init:
- STAFF_IDENTIFIER { $$ = $1->staff(true); }
+ /* empty */ {
+ $$ = new Input_staff( "melodic" );
+ }
| STRING {
$$ = new Input_staff(*$1);
delete $1;
}
- | MELODIC {
- $$ = new Input_staff("melodic");
- }
;
staff_body:
staff_init
| staff_body init_music {
+ $$ = $1;
$2->set_default_group( "staff_music" + String($$->music_.size()));
$$->add($2);
}
init_music_voice { $$ = $1; }
| init_music_chord { $$ = $1; }
| init_lyrics_voice { $$ = $1; }
+ | VOICE_IDENTIFIER {
+ $$ = $1->mvoice(true);
+ }
;
init_lyrics_voice:
- LYRICS { THIS->lexer_p_->push_lyric_state(); }
+ LYRIC { THIS->lexer_p_->push_lyric_state(); }
music_voice { $$ = $3; THIS->lexer_p_->pop_state(); }
;
init_music_voice:
- MUSIC { THIS->lexer_p_->push_note_state(); }
+ MELODIC { THIS->lexer_p_->push_note_state(); }
/* cont*/ music_voice
{ $$=$3; THIS->lexer_p_->pop_state(); }
;
init_music_chord:
- MUSIC { THIS->lexer_p_->push_note_state(); }
+ { THIS->lexer_p_->push_note_state(); }
/* cont*/ music_chord
- { $$=$3; THIS->lexer_p_->pop_state(); }
+ { $$=$2; THIS->lexer_p_->pop_state(); }
;
/*
MUSIC
| music_voice_body '>' {
THIS->fatal_error_i_ = 1;
THIS->parser_error("Confused by errors: bailing out");
- };
+ }
+ ;
music_chord: '<' music_chord_body '>' { $$ = $2; }
;
;
melodic_request:
- MELODIC '{' int int int '}' {/* ugh */
+ MELODIC_REQUEST '{' int int int '}' {/* ugh */
$$ = new Melodic_req;
$$->octave_i_ = $3;
$$->notename_i_ = $4;
THIS->default_duration_ = *$3;
delete $3;
}
- | OCTAVECOMMAND '{' int '}' {
- THIS->default_octave_i_ = $3;
+ | OCTAVECOMMAND { THIS->default_octave_i_ = 2; }
+/* cont */
+ '{' steno_melodic_req '}' {
+ THIS->default_octave_i_ = $4->octave_i_;
}
| TEXTSTYLE STRING {
THIS->textstyle_str_ = *$2;