From: fred Date: Sun, 12 Jul 1998 22:26:15 +0000 (+0000) Subject: lilypond-1.0.1 X-Git-Tag: release/1.5.59~5900 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=42a88bf2eddf4332b1c761df0347207d2c6a759f;p=lilypond.git lilypond-1.0.1 --- diff --git a/Documentation/MANIFESTO.yo b/Documentation/MANIFESTO.yo new file mode 100644 index 0000000000..0bb3533763 --- /dev/null +++ b/Documentation/MANIFESTO.yo @@ -0,0 +1,97 @@ + +article(MANIFESTO -- Rationale behind the GNU LilyPond project)(HWN +and JCN)() + +sect(Goals for LilyPond) + + +GNU LilyPond was written with some considerations in mind: + + +itemize( +it() Describing a well-defined language for defining music. We call + this language (rather arrogantly) The Musical Definition Language + (mudela for short). GNU LilyPond reads a mudela sourcefile and outputs a + TeX file. +it() Providing an easy-to-use interface for typesetting music in + its broadest sense. This interface should be intuitive from a musical + point of view. By broadest sense we mean: it is designed for music + printed left to right in staffs, using notes to designate rythm and + pitch. +it()Generating high-quality output. Ideally it should be of a professional + quality. We'd like to render Herbert Chlapiks words, "Fine music + setting is not possible without a knowledgeable printer," untrue. +it()Making a system which is fully tweakable. It should be possible to + typeset a book on how not to typeset music. +) + +sect(Development constraints) + + +Further considerations while doing the programming + +itemize( +it()GNU LilyPond uses TeX for its output. This is not a key issue: in a + future version, GNU LilyPond might bypass TeX, but at the moment TeX + is convenient for producing output. +it()GNU LilyPond does not display notes directly, nor will it be rehacked + to be used interactively. GNU LilyPond writes output to a file. It + will not be extended to play music, or to recognize music. + [As an aside, I am contemplating to create a library for rendering + music, which is "X-capable", so that others can create interactive tools] +it()GNU LilyPond is intended to run on Unix platforms, but it should + be portable to any platform which can run TeX and the GNU tools +it()GNU LilyPond is free. Commercial windows packages for setting music are + abundant. Free musicprinting software is scarce. For more thoughts on + this, please consult the file(gnu-music) documentation. +it()GNU LilyPond is written in GNU C++. It will not be downgraded/ported to fit + broken systems. +) + +sect(Goals for mudela) + +The design of Mudela has been (perfect past tense, hopefully) an +ongoing process, the most important criteria being: + +itemize( +it()define the (musical) message of the composer as unambiguously as possible. + This means that, given a piece Mudela, it should be possible for a + program to play a reasonable interpretation of the piece. + + It also means that, given a piece of Mudela, it should be possible for a + program to print a score of the piece. +it()be intuitive, and easily readable (compared to, say, Musi*TeX input, + or MIDI :-), +it()be easily writable in ASCII with a simple texteditor +) + +Other considerations were (and will be): + +itemize( +it()be able to edit the layout without danger of changing the original + music (Urtext), +it()allow for adding different interpretations, again, + without danger of changing the original, +it()easy to create a conductor's score, + as well as the scores for all individual instruments, +it()provide simple musical manipulations, such as em(i) extracting a + slice of music from a previously defined piece, em(ii) extracting + only the rhythm from a piece of music, em(iii) transposing, etc., +it()easy to comprehend to both programmers and others. +) + +One of the things that (might) be here would be: feasible to use in a +graphic editor. We don't have experience with these beasts, so we +don't know how to do this. Comments appreciated. + +Musical pieces could be + +itemize( +it()Orchestral scores, (eg Mahler) +it()piano pieces (eg. Schubert, Rachmaninov), +it()pop songs (lyrics and chords), +it()Gregorian chants, +it()Bach multivoice organ pieces, +it()Short excerpts to be used in musicological publications. +) + diff --git a/Documentation/internals.yo b/Documentation/internals.yo new file mode 100644 index 0000000000..4cb8d0aae3 --- /dev/null +++ b/Documentation/internals.yo @@ -0,0 +1,288 @@ +article(LilyPond internals)(Han-Wen Nienhuys)() + +This documents some aspects of the internals of GNU 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. This page may be +a little incoherent. Unfortunately, it is also quite outdated. A +more thorough and understandable document is in the works. + +You should use code(doc++) to take a peek at the sources. + + +sect(OVERVIEW) + +GNU LilyPond is a "multi-pass" system. The different passes have been +created so that they do not depend on each other. In a later stage +some parts may be moved into libraries, or seperate programs, or they +might be integrated in larger systems. + +description( + +dit(Parsing:) + +No difficult algorithms. The .ly file is read, and converted to a list +of code(Scores), which each contain code(Music) and paper/midi-definitions. + +dit(Interpreting music) + +The music is walked column by column. The iterators which do the +walking report the Request to Translators which use this information +to create elements, either MIDI or "visual" elements. The translators +form a hierarchy; the ones for paper output are Engravers, for MIDI +Performers. + +The translators swallow requests, create elements, broadcast them to +other translators on higher or same level in the hierarchy: + +The stem of a voice A is broadcast to the staff which contains A, but +not to the noteheads of A, and not to the stems, beams and noteheads +of a different voice (say B) or a different staff. The stem and +noteheads of A are coupled, because the the Notehead_engraver +broadcasts its heads, and the Stem catches these. + +The engraver which agrees to handle a request 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). In this way you can put +the voices of 2 instruments in a conductor's score so they make chords +(the Stem_reqs of both instruments will be merged). + +dit(Prebreaking) + +Breakable stuff (eg. clefs and bars) are copied into pre and +postbreaks. + +dit(Preprocessing) + +Some dependencies are resolved, such as the direction of stems, beams, +and "horizontal" placement issues (the order of clefs, keys etc, +placement of chords in multi-voice music), + +dit(Break calculation:) + +The lines and horizontal positions of the columns are determined. + +dit(Breaking) + +Through some magical interactions with Line_of_score and Super_elem +(check out the source) the "lines" are produced. + +All other spanners can figure across which lines they are spread. If +applicable, they break themselves into pieces. After this, each piece +(or, if there are no pieces, the original spanner itself) throws out +any dependencies which are in the wrong line. + +dit(Postprocesing:) + +Some items and all spanners need computation after the Paper_column +positions are determined. Examples: slurs, vertical positions of +staffs. + +dit(Output paper) + +) + +sect(mudela) + +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. + +In a lot of other formats this would be called an 'Event' + +description( +dit(code(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. +dit(code(Note_req)) + LilyPond 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 to decide. The engraver can decide on positioning based on + ottava commands and the appropriate clef. +dit(code(Rest_req)) + Typeset a rest. +dit(code(Span_req)) + This type of request typically results in the creation of a code(Spanner) +dit(code(Beam_req)) + Start/stop a beam. + Engraver 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. +dit(code(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 code(Dynamic) request carries a time, measured + from the start of its note. +) + +sect(Request_engraver) + +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 input + +verb( + \type Staff < % chord + { \meter 2/4; [c8 c8] } + {\meter 2/4; [e8 e8] } + > +) + +Both the cs and es are part of a staff (they are in the same +Voice_group), so they should share meters, but the two [ ] pairs +should be merged. + +The judge in this "allocation" problem a set of brokers: the requests +are transmitted to so-called engravers which respond if they want to +accept a request eg, the code(Notehead_engraver) will accept +code(Note_req)s, and turn down code(Slur_req)s. If the Music_iterator +cannot find a engraver that wants the request, it is junked (with a +warning message). + +After all requests have been either assigned, or junked, the Engraver +will process the requests (which usually means creating an code(Item) +or code(Spanner)). If a code(Request_engraver) creates something, it +tells the enclosing context. If all items/spanners have been created, +then each Engraver is notified of any created Score_element, via a +broadcasting system. + +nsubsect(example:) + +verb( + c4 +) + +produces: + +verb( + Note_request (duration 1/4) + Stem_request (duration 1/4) +) + +Note_request will be taken by a code(Notehead_engraver), stem_request +will be taken by a code(Stem_beam_engraver). code(Notehead_engraver) +creates a code(Notehead), code(Stem_beam_engraver) creates a +code(Stem). Both announce this to the Staff_engraver. Staff_engraver +will tell code(Stem_beam_engraver) about the code(Notehead), which +will add the code(Notehead) to the code(Stem) it just created. + +To decide on merging, several engravers have been grouped. Please +check file(init/engraver.ly). + + +sect(ITEMS and SPANNERS) + +The symbols that are printed, are generated by items and spanners +(staff-elements). An item has one horizontal position, whereas a +spanner spans several columns. + +sect(DEPENDENCIES) + +In music symbols depend on each other: the stems of a beam should +point in the same direction as the beam itself, so the stems of a beam +depend on the beam. In the same way do scripts depend on the direction +of the stem. To reflect this, LilyPond has the notion of dependency. +It works in the same fashion that code(make) uses to build programs: +before a stem is calculated, its dependencies (the beam) should be +calculated. Before a slur is calculated, its dependencies (stems, +noteheads) should be calculated. + +sect(BREAKING) + +So what is this PREBREAK and POSTBREAK 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 GNU Lilypond, we have the same concepts (and the same +terminology). Each (nonrhythmic) symbol is typeset in a nonrhythmic column +At a breakpoint, multiple symbols are printed; symbols to be printed +if the line is not broken, symbols to appear on the previous line, and +on the next line if it is broken. + +sect(SPACING) + + +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: + +verb( + time -----> + + cols: 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 + +verb( + 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: GNU 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. GNU 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.) +