=head1 NAME LilyGuts - doco to the internals of LilyPond =head1 DESCRIPTION This page documents some aspects of the internals of LilyPond. Some of this stuff comes from e-mail I wrote, some from e-mail others wrote, some are large comments taken away from the headers You should use doc++ to take a peek at the sources. [have to do more doco; see TODO] =head1 OVERVIEW LilyPond is a "5-pass" system: =over 5 =item 1. Parsing: No difficult algorithms. Associated datastructures have prefix Input (eg Input_score, Input_command) =item 2. Processing: Requests are processed and granted. This is done by three cooperating structeres: Staff, Staff_walker and Staff_column. In this step data-structures for 3. are created and filled with data: PScore, PCol, PStaff =item 3. Calculation: This step uses structures which have names starting with 'P'. linebreaks and horizontal positions of PCols are determined. Line_of_* generated. =item 4. Postprocesing: Some items and all spanners need computation after the PCol positions are determined. =item 5. Output Very simple, just walk all Line_of_* and follow the links over there =back =head1 REQUESTS [see F] Any Voice_element can do a number of requests. A request is done to the C which contains the C. 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 for explanation of each request type. The result of a request will be an C or a C, which will be put on a C. Note that the C and the original C 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 should be thought as a container for the Cs, and an interpreter for Cs and Cs. 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 made up her mind, the resultant items and spanners are put on the PScore. =over 5 =item C 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 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 to decide. The C can decide on positioning based on ottava commands and the appropriate clef. =item C Why a request? It might be a good idea to not typeset the rest, if the paper is too crowded. =item C This type of request typically results in the creation of a C =item C 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 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 request carries a time, measured from the start of its note. This subfield would come in handy, if LilyPond was adapted for midi support. =back =head1 Request_register In the previous section the idea of Request has been explained, but this only solves one half of the problem. The other half is deciding which requests should be honored, which should merged with other requests, and which should be ignored. Consider this (pseudo)input { % chord \music { [c() c] } \music { [e() e] } } Both the c and e are part of a chord (they are in the same Voice_group), so they should share the beams, and the two [ ] pairs should be merged. The slurs OTOH are specific for each voice, so they should not be shared. The judge in this "allocation" problem is Staff (actually, it's child C). It uses the C to do most of the work. For each request C queries so-called Cs if they want to accept a request eg, the C will accept Cs, and turn down Cs. If C cannot find a register that wants the request, it is junked (with a warning message). After all requests have been either assigned, or junked, the Register will process the requests (which usually means creating an C or C). If a C creates something, it tells C. If all requests have been processed, then each Register is notified of any created Staff_element. =head2 example: c4 produces: note_request (duration 1/4) stem_request (duration 1/4) note_request will be taken by a C, stem_request will be taken by a C. C creates a C, C creates a C. Both announce this to the Staff. Staff will tell C about the C, which will add the C to the C it just created. To decide on merging, C has grouped several registers. There are a few groups: =item * Staff wide, contains Local_key_register Bar_register Key_register Meter_register Clef_register =item * Voice group, contains Stem_beam_register Script_register Text_register =item * Voice, contains Slur_register Notehead_register =item 1 =head1 BREAKING [Source files: F, F] BREAKING, PREBREAK POSTBREAK, etc. So what's the deal with PREBREAK and POSTBREAK and all this stuff? Let's take text as an example. In German some compound words change their spelling if they are broken: "backen" becomes "bak-ken". TeX has a mechanism to deal with this, you would define the spelling of "backen" in TeX in this way \discretionary{bak-}{ken}{backen} These 3 arguments are called "prebreak", "postbreak" and "nobreak" text. The same problem exists when typesetting music. If a line of music is broken, the next line usually gets a clef. So in TeX terms, the clef is a postbreak. The same thing happens with meter signs: Normally the meter follows the bar. If a line is broken at that bar, the bar along with the meter stays on the "last" line, but the next line also gets a meter sign after the clef. Using the previous notation, \discretionary{bar meter}{clef meter}{ bar meter } In Lilypond, we have the same concepts (and the same terminology). Each (nonrhythmic) symbol is typeset using a Command (code: TYPESET). At a breakpoint, TYPESET commands can be grouped using separators (in lower case): BREAK_PRE, typeset(bar), typeset(meter), BREAK_MID, typeset(bar), typeset(meter), BREAK_POST, typeset(clef), typeset(meter), BREAK_END The BREAK command sequence is terminated with BREAK_END, so other commands (like INTERPRET) may follow this sequence. =head1 SPACING I think my method is the most elegant algorithm i've seen so far. Some terminology: I call a vertical group of symbols (notes) which start at the same time a "column". Each line of a score has notes in it, grouped in columns. The difference in starting time between those columns makes it possible to determine ideal distances between those columns. Example: time -----> col1 col2 col3 col4 voice1 1 1 voice2 2 2 2 2 (1 is a whole note, 2 a half note.) time_difference (col1 , col2) = 0.5 wholes, time_difference (col1 , col3) = 1 wholes, time_difference (col2 , col3) = 0.5 wholes, etc. these differences are translated into ideal distances (these translations have been the subject of discussion in this thread). distance (col1,col2) = 10 pt distance (col1,col3) = 14.1 pt distance (col2,col3) = 10 pt etc. as you can see, these distance are conflicting. So instead of satisfying all those ideals simultaneously, a compromise is sought. This is Columbus' egg: LilyPond attaches "springs" to each column-pair. each spring has an equilibrium-position which is equal to the above mentioned distance, so spring (col1, col2) and spring (col2,col3) try to push column 1 and 3 away (to a distance of 20pt) from each other, whereas the spring between col 1 and col 3 tries to pull those two together (to a distance of 14.1 pt). The net result of this pushing and pulling is an equilibrium situation (the pushing cancels the pulling), which can be calculated as the solution of Quadratic program: it is the solution with minimum potential energy, for you physicists out there. This algorithm for doing one line, gives a "badness" parameter for each line (the potential energy). Now one can use TeX's algorithm for making paragraphs (using this new version of "badness"): one should try to minimise the overall badness of a paragraph. LilyPond also uses the concept of pre- and post-breaks. (actually, it is a bit more complicated: each column also has a minimum distance to other columns, to prevent symbols from running into symbols of other columns.) =head1 SEE ALSO =head2 References [partly by Mark Basinski ] Herbert Chlapik, W.A. Hegazy and J. S. Gourlay. Optimal line breaking in music. In ``Document Manipulation and Typography'', J.C. van Vliet (ed) 1988. Ross, Ted. ``Teach yourself the art of music engraving and processing'' (3rd edition). Hansen House, Miami Beach, FL. Hansen House 1820 West Ave. Miami, FL 33139 (305) 532-5461 [This is about *engraving* i.e. professional music typesetting, and includes some good spacing tables] Read, Gardner. ``Modern Rhythmic Notation.'' Indiana University Press, 1978. Read, Gardner. ``Music Notation'' (2nd edition). Taplinger Publishing, New York. [This is as close to the ``standard'' reference work for music notation issues as one is likely to get.] =head2 Further reading (of varying usefulness): Donato, Anthony. Preparing Music Manuscript. Englewood Cliffs: Prentice-Hall, 1963. Donemus. "Uitgeven van muziek". Donemus Amsterdam, 1900 Heussenstamm, George. The Norton Manual of Music Notation. New York: Norton, 1987. Karkoshka, Erdhard. Notation in New Music. Trans. Ruth Koenig. New York: Praeger Publishers, 1972. Out of print. Roelofs, Ren\'e. ``Een Geautomatiseerd Systeem voor het Afdrukken van Muziek'' afstudeerscriptie Bestuurlijke informatica, no 45327, Erasmus universiteit Rotterdam, 1991. (``An automated system for printing music'' Master's Thesis Management and Computer Science.) C. Roemer, The Art of Music Copying. Roerick music co., Sherman Oaks (CA), 1973. Rosecrans, Glen. Music Notation Primer. New York: Passantino, 1979. Stone, Kurt. Music Notation in the Twentieth Century. New York: Norton, 1980.