TOPLEVEL_MAJOR_VERSION = 0
TOPLEVEL_MINOR_VERSION = 0
-TOPLEVEL_PATCH_LEVEL = 62
+TOPLEVEL_PATCH_LEVEL = 63
# use to send patches, always empty for released version:
# include separator: ".postfix", "-pl" makes rpm barf
Inline definition files always have the file name extension ".icc".
+in emacs:
+
+ (setq auto-mode-alist
+ (append '(("\\.make$" . makefile-mode)
+ ("\\.cc$" . c++-mode)
+ ("\\.icc$" . c++-mode)
+ ("\\.tcc$" . c++-mode)
+ ("\\.hh$" . c++-mode)
+ ("\\.pod$" . text-mode)
+ )
+ auto-mode-alist))
+
+
=head2 INDENTATION
'(lambda() (c-set-style "Stroustrup")
)
)
+
If you like using font-lock, you can also add this to your F<.emacs>:
(setq font-lock-maximum-decoration t)
=back
Generally default arguments are taboo, except for nil pointers.
+
+=head1 MISCELLANEOUS
+
+For some tasks, some scripts are supplied, notably creating patches, a
+mirror of the website, generating the header to put over cc and hh
+files, doing a release.
+
+Use them.
+
+
=head2 Miscellaneous
-Q: How do I change the staff-dividers?
+Q: How do I change the TeX layout?
-A: See lilyponddefs.tex
+A: See lilyponddefs.tex, it has some comments.
Q: Why GPL?
--- /dev/null
+=head1 NAME
+
+GNU Music project - manifesto
+
+=head1 DESCRIPTION
+
+Random ranting about the GNU Music project
+
+=head GOAL
+
+Provide the users with free software for:
+
+ - composing
+ - setting
+ - playing
+ - sequencing
+ - interchanging music
+
+and possibly for
+
+ - arranging
+ - performing
+
+Music publishers make lots of money out of selling which sheet music
+essentially free (composed by people long dead). Publishers have two
+arguments for doing this: high prices are there to guarantee diversity
+(keeping lots of stock is expensive), and to encourage new work being
+composed.
+
+LilyPond addresses the first issue: storing mudelas takes up almost no
+space at all. Other systems should address the other issue:
+encouraging laymen to take up composing, in the same way that GNU
+tools have created a whole new generation of programmers.
+
+
+The public deserves free non-copyrighted music.
+
+The public deserves free tools for composing and printing
+
+
+=head1 REQUIREMENTS
+
+=over 4
+
+=item * high-quality
+
+(cf Emacs), from engraving point of view
+
+=item * high-quality
+
+from software point of view: like all GNU software, it
+should have no limits, be fast, etc.
+
+
+=item * tweakable
+
+Printed music has a lot of styles, and special symbols. It may be
+unfeasible to provide and maintain lots of code that is hardwired
+into the system. The tools should be extensible/programmable like
+Emacs and TeX
+
+=item * easy to use.
+
+That is, for technical users (that can read a
+manual). The learning curve should be as easy as possible but not at
+the expense of comfort of use.
+
+=back
+
+=head1 TASKS (LONGTERM)
+
+=over 4
+
+=item A typesetting engine.
+
+A system with rules on how to set properties of items to be printed
+(up/down directions, breaking, etc) LilyPond provides one, but it is
+not yet suited to interactive typesetting
+
+=item A display engine
+
+which can display clear notewriting in (say) an X-window
+
+Gsharp is there, but far from finished. Ideally the system should
+cooperate with the typesetting engine
+
+=item An ASCII language
+
+In development, LilyPond has a language. See over there for goals.
+Having an ASCII format which enables urtext, and easy sharing (via
+mail and news forums) encourages cooperation and exchange of music.
+
+=item A printing engine
+
+Maybe to be merged with the display system.
+
+=item An input system
+
+The natural way to enter composed music is singing or playing it. The
+GMP should have module which can take keyboard input or microphone
+input and convert it to computer data. (the second one would be difficult)
+
+=item sequencing
+
+(have no clue about this)
+
+=item A scanning system
+
+Having a system which can produce mudela from printed scores, greatly
+simplifies creating a collection of music
+
+=item A music-understanding system
+
+(difficult) A system to generate accompaniments, figured bass,
+automatic accompaniment, etc.
+
+=item an internet archive of free music
+
+The complete works by Bach, Beethoven, and any other ancient composer
+should be electronically retrievable. This might be a separate
+project: the Free Music Project.
+
+=back
+
+=head1 PROGRAMS
+
+=over 4
+
+=item *
+
+A noninteractive typesetter, suited for batch jobs, and
+typesetting existing music. This would couple the ASCII language, the
+printing engine and the typesetting engine
+
+=item *
+
+A GUI for composing. This would combine the display engine, the
+input system, the typesetting engine
+
+=back
+
+The typesetting system has a complexity comparable to TeX's, the GUI
+would be comparable to LyX (?) with additional complexity in
+recognizing input.
+
+=head1 TASKS (SHORT TERM)
+
+=over 4
+
+=item *
+
+gather moderate number of test users and hackers
+
+=item *
+
+a website on GMP
+
+=item *
+
+Libs for r/w MIDI
+
+=item *
+
+Think about interfaces for components.
+
+=item *
+
+Find sponsors. This project will take a long time, and in its infant
+stages, having a hard and small core which does a lot of work, is more
+efficient than lots of people doing small subprojects. Finanicial
+support would be desirable.
+
+=back
+
</a
>
+=item *
+<a href=lilyliterature.html
+>
+resources on music typesetting
+</a
+>
+
+=item *
+<a href=mi2mu.html
+>
+manual page for mi2mu, the MIDI convertor.
+</a
+>
+
=item *
<a href=mudela.html
>
=item *
Get it at ftp://pcnov095.win.tue.nl/pub/lilypond !
-=cut
-niet veranderen in expliciete URL. pod2* doet dit automaties.
-
-Should generate auto from POD sources.
-
-=pod
=head1 AUTHOR
You should use doc++ to take a peek at the sources.
-[have to do more doco; see TODO]
+This should become a Hacking-HOWTO. If you find any confusing stuff
+here, let me know. I am a hacker, and don't spend enough time doccing
+what I write.
+
+If you finally have mastered some internal piece of lily, your
+explanation could be added here.
=head1 OVERVIEW
-GNU LilyPond is a "5-pass" system:
+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.
=over 4
-=item 1. Parsing:
+=item Parsing:
No difficult algorithms. Associated datastructures have prefix Input
-(eg Input_score, Input_command)
+(eg Input_score, Input_command). The .ly file is read, and converted
+to Requests, Voice_elements, Voices.
+
+The result looks something like this (? = 0 or 1, * =0 or more, + = 1
+or more)
+
+ Score {
+ Midi_def?
+ Paper_def?
+ Staff+ {
+ Voice+ {
+ start_moment
+ Voice_element* {
+ duration
+ Request*
+ }
+ }
+ Input_register { ..}
+ }
+ }
+
+Request is a baseclass for almost all kinds of information. As you can
+see, the info is stored horizontally; horizontally is the natural form
+for entering music.
+
+=item Setting up music
+
+Simultaneous Requests are grouped into columns. Vertical is the
+natural form for processing music.
-=item 2. Processing:
+=item 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
+Requests are processed and used to create elements (like balls, stems,
+slurs etc). This is done by a hierarchy of brokers, which swallow
+requests, broadcast them and couple different elements.
-=item 3. Calculation:
+In this step data-structures for the next steps are created and filled
+with data: PScore, PCol, PStaff
+
+=item Preprocessing
+
+Some dependencies are resolved, such as the direction of stems, beams,
+
+=item 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:
+=item Postprocesing:
Some items and all spanners need computation after the PCol positions
are determined.
-=item 5. Output
+=item Output paper
Very simple, just walk all Line_of_* and follow the links over there
+=item Output midi
+
+The columns of requests (from the Setting up step) are used to
+determine what to output when.
+
=back
+=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 (lists).
+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)
+
+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.
+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.
+
Some of the important requests are:
=over 4
note, therefore fore each C<Dynamic> request carries a time, measured
from the start of its note.
-=head2 Voice
-
=head2 Voice_element
-=head2 Voice groups
-
-=head1 Requests
+Voice_element is a list of requests together with a duration. It is
+strictly horizontal
-inc
-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.
+=head2 Voice
-The class C<Staff> should be thought as a container for the
-C<Voice>s, and an interpreter for C<Request>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.
+Voice is a list of Voice_elements together with a starting time.
-After C<Staff> made up her mind, the resultant items and
-spanners are put on the PScore.
+=head2 Voice groups
+Voice group is a (time-dependent) collection of voices which share
+some characteristics (slurs, stems) at some time.
=head1 Request_register
To decide on merging, C<Complex_staff> has grouped several
registers. There are a few groups:
+=over 4
+
=item *
Staff wide, contains
Slur_register
Notehead_register
+=back
-=item 1
+=head1 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.
-=head1 BREAKING
+=head1 DEPENDENCIES
-[Source files: F<command.hh>, F<scommands.cc>]
+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 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)
+should be calculated.
-BREAKING, PREBREAK POSTBREAK, etc.
+=head1 BREAKING
So what's the deal with PREBREAK and POSTBREAK and all this
stuff?
\discretionary{bar meter}{clef meter}{ bar meter }
In GNU 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.
+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.
=head1 SPACING
minimum distance to other columns, to prevent symbols from running
into symbols of other columns.)
-=head1 SEE ALSO
-
-=head2 References
-
-[partly by Mark Basinski <basinski@arizona.edu>]
-
-Herbert Chlapik, Die Praxis des Notengraphikers. Doblinger, 1987.
-
-Helene Wanske, ?, Schott-Verlag Mainz.
-
-Maxwell Weaner and Walter Boelke, Standard Music Notation Practice,
-revised edition by Arnold Broido and Daniel Dorff. Music Publisher's
-Association of the United States Inc., 1993.
-
-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 I<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.
-
-
-=head2 On typesettig programs
-
-From: Miguel Filgueiras <mig@ncc.up.pt>
-
-... as well as other systems. I contribute with some references:
-
-
-D. Blostein, L. Haken, The Lime Music Editor: a Diagram Editor
-Involving Complex Translations. {\em
-Software --- Practice and Experience}, Vol. 24(3), 289--306, 1994.
-
-Alexander Brinkman, {\em PASCAL Programming for Music Research}.
-The University of Chicago Press, 1990.
-
-Miguel Filgueiras, Implementing a Symbolic Music Processing
-System. LIACC, Universidade do Porto, 1996; submitted.
-
-Miguel Filgueiras, Some Music Typesetting Algorithms. LIACC,
-Universidade do Porto, {\em forthcoming}.
-
- Miguel Filgueiras and Jos\'e Paulo Leal, A First Formulation of
-\SceX, a Music Typesetting System. Centro de Inform\'atica da
-Universidade do Porto, 1993.
-
-Miguel Filgueiras and Jos\'e Paulo Leal. Representation and
-manipulation of music documents in \SceX. {\em Electronic Publishing},
-vol. 6 (4), 507--518, 1993.
-
-Eric Foxley, Music --- A language for typesetting music scores. {\em
-Software --- Practice and Experience}, Vol. 17(8), 485--502, 1987.
-
-John S. Gourlay, A language for music printing. {\em Communications of
-the ACM}, Vol. 29(5), 388--401, 1986.
-
-Cindy Grande, NIFF6a Notation Interchange File Format.
-Grande Software Inc., 1995. {\tt ftp:blackbox.cartah.washington.edu}
-
-Fran\c{c}ois Jalbert, Mu\TeX\ User's Guide (Version $1.1$). Computer
-Science Department, University of British Columbia, 1989.
-
-Peter S. Langston, Unix music tools at Bellcore. {\em
-Software --- Practice and Experience}, Vol. 20(S1), S1/47--S1/61, 1990.
-
-Andreas Mahling, J. Herczeg, M. Herczeg and S<H.-D.> B\"ocker, Beyond
-visualization: knowing and understanding. In P.~Gorny, M.~J. Tauber
-(eds.), {\em Visualization in Human-Computer Interaction}, Lecture
-Notes in Computer Science, 439, 16--26, Springer-Verlag, 1990.
-
-Jan Nieuwenhuizen, Using \TeX\ and the MusiX\TeX\ macro package to
-write parts and scores of music. Department of Physics, Eindhoven
-University of Technology, 1995.
-
-Don Simons, PMX, A Preprocessor for MusiX\TeX\ (Version 1.04).
-dsimons@logicon.com.
-
-Daniel Taupin. Music\TeX: Using \TeX\ to Write Polyphonic or
-Instrumental Music (Version 5.17). Laboratoire de Physique des
-Solides, Centre Universitaire, Orsay, 1996.
-
-Daniel Taupin, Ross Mitchell and Andreas Egler, Musix\TeX: Using \TeX\
-to Write Polyphonic or Instrumental Music (Version T.64). Laboratoire
-de Physique des Solides, Centre Universitaire, Orsay, 1993.
-
-Barry Vercoe, Csound --- A Manual for the Audio Processing System and
-Supporting Programs with Tutorials. Media Lab, M.I.T., Cambridge,
-Massachusetts, 1986 (rev. 1992).
-
-Chris Walshaw, {\tt ABC2M\TeX} --- An easy way of transcribing folk
-and traditional music. School of Maths, University of Greenwich, 1993.
+This of course does not solve the problem of generating the
+springs. This is an area that needs a lot of work, and the optimal
+solution to find is not of a mathematical nature.
--- /dev/null
+=head1 NAME
+
+Lily literature -- reading on music engraving
+
+=head1 DESCRIPTION
+
+A list of resources on music printing/writing and engraving.
+
+=head2 References
+
+[partly by Mark Basinski <basinski@arizona.edu>]
+
+Herbert Chlapik, Die Praxis des Notengraphikers. Doblinger, 1987.
+
+Helene Wanske, ?, Schott-Verlag Mainz.
+
+Maxwell Weaner and Walter Boelke, Standard Music Notation Practice,
+revised edition by Arnold Broido and Daniel Dorff. Music Publisher's
+Association of the United States Inc., 1993.
+
+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 I<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.
+
+
+=head2 On typesettig programs
+
+From: Miguel Filgueiras <mig@ncc.up.pt>
+
+... as well as other systems. I contribute with some references:
+
+
+D. Blostein, L. Haken, The Lime Music Editor: a Diagram Editor
+Involving Complex Translations. {\em
+Software --- Practice and Experience}, Vol. 24(3), 289--306, 1994.
+
+Alexander Brinkman, {\em PASCAL Programming for Music Research}.
+The University of Chicago Press, 1990.
+
+Miguel Filgueiras, Implementing a Symbolic Music Processing
+System. LIACC, Universidade do Porto, 1996; submitted.
+
+Miguel Filgueiras, Some Music Typesetting Algorithms. LIACC,
+Universidade do Porto, {\em forthcoming}.
+
+ Miguel Filgueiras and Jos\'e Paulo Leal, A First Formulation of
+\SceX, a Music Typesetting System. Centro de Inform\'atica da
+Universidade do Porto, 1993.
+
+Miguel Filgueiras and Jos\'e Paulo Leal. Representation and
+manipulation of music documents in \SceX. {\em Electronic Publishing},
+vol. 6 (4), 507--518, 1993.
+
+Eric Foxley, Music --- A language for typesetting music scores. {\em
+Software --- Practice and Experience}, Vol. 17(8), 485--502, 1987.
+
+John S. Gourlay, A language for music printing. {\em Communications of
+the ACM}, Vol. 29(5), 388--401, 1986.
+
+Cindy Grande, NIFF6a Notation Interchange File Format.
+Grande Software Inc., 1995. {\tt ftp:blackbox.cartah.washington.edu}
+
+Fran\c{c}ois Jalbert, Mu\TeX\ User's Guide (Version $1.1$). Computer
+Science Department, University of British Columbia, 1989.
+
+Peter S. Langston, Unix music tools at Bellcore. {\em
+Software --- Practice and Experience}, Vol. 20(S1), S1/47--S1/61, 1990.
+
+Andreas Mahling, J. Herczeg, M. Herczeg and S<H.-D.> B\"ocker, Beyond
+visualization: knowing and understanding. In P.~Gorny, M.~J. Tauber
+(eds.), {\em Visualization in Human-Computer Interaction}, Lecture
+Notes in Computer Science, 439, 16--26, Springer-Verlag, 1990.
+
+Jan Nieuwenhuizen, Using \TeX\ and the MusiX\TeX\ macro package to
+write parts and scores of music. Department of Physics, Eindhoven
+University of Technology, 1995.
+
+Don Simons, PMX, A Preprocessor for MusiX\TeX\ (Version 1.04).
+dsimons@logicon.com.
+
+Daniel Taupin. Music\TeX: Using \TeX\ to Write Polyphonic or
+Instrumental Music (Version 5.17). Laboratoire de Physique des
+Solides, Centre Universitaire, Orsay, 1996.
+
+Daniel Taupin, Ross Mitchell and Andreas Egler, Musix\TeX: Using \TeX\
+to Write Polyphonic or Instrumental Music (Version T.64). Laboratoire
+de Physique des Solides, Centre Universitaire, Orsay, 1993.
+
+Barry Vercoe, Csound --- A Manual for the Audio Processing System and
+Supporting Programs with Tutorials. Media Lab, M.I.T., Cambridge,
+Massachusetts, 1986 (rev. 1992).
+
+Chris Walshaw, {\tt ABC2M\TeX} --- An easy way of transcribing folk
+and traditional music. School of Maths, University of Greenwich, 1993.
+
+
+
music conveys is usually a simple one. GNU LilyPond is a try at providing
a simple interface for setting music.
-
=head1 OPTIONS
=over 5
=item *
-beams, slurs, chords, super/subscripts (accents and text), triplets,
-general n-plet (triplet, quadruplets, etc.), lyrics, transposition
-dynamics (both absolute and hairpin style)
+beams, slurs, ties, chords, super/subscripts (accents and text),
+triplets, general n-plet (triplet, quadruplets, etc.), lyrics,
+transposition dynamics (both absolute and hairpin style)
=item *
=over 4
-=item lilygut(?)
+=item lilygut
On technical details of LilyPond
The GNU LilyPond FAQ list
-
-
-=item http://?
+=item http://
The GNU Music project. GNU LilyPond is part of the GNU Music
project. For more information on the GNU Music project,
horizontal spacing of multiple staffs (april 1996) I coded it (and did
not test it). After starting with this fundamental piece, I slowly
added the stages which come before spacing, and after. A half year
-later later, I had a first working version, (october 1996). I
-announced Patchlevel 0.0.7 (or 8) to the mutex list after asking some
-technical details on spacing; it was downloaded approximately 4 times.
-Then I got the hang of it, and in the subsequent two months, I coded
-until it had doubled in size (pl 23).
+later, I had a first working version, (october 1996). I announced
+Patchlevel 0.0.7 (or 8) to the mutex list after asking some technical
+details on spacing; it was downloaded approximately 4 times. Then I
+got the hang of it, and in the subsequent two months, I coded until it
+had doubled in size (pl 23).
Examples are included with the GNU LilyPond distribution. For the sake of
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 (lists).
-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)
-
=head2 Staff
The staff is a simple container (containing Voices). The so-called
-pl 61.jnc1
- - smarter + faster duration-convert using Array
- - bf: mi2mu compilation/duration-conversions
- - lots faster mi2mu, hopefully does type 1 too...
-pl 60.jnc1
- - mi2mu handles non-quantified rests, try mi2mu -b wtk-i/fugue2.midi
-
-
+pl 63
+ - bf: segfault during MIDI output with mi2mu output.
+ - kludge: parse error beyond eof
+ - don't read ini if toplevel file not found
+ - accumulate \kern in TeX output.
+ - bf: try to prevent long lines; TeX breaks on them.
+ - naming: Pointer->Link, IPointer->Pointer
+ - undocced fix (MB)
+ - GMP manifesto.
+
+pl 61.jcn4
+ - mi2mu -p -s16 fugua2.midi getting better!
+ - bf: Duration_convert quantify threshold down
+ - bf: (on quantify): tcols quantified; no silly voices
+
+pl 61.jcn3
+ - lily parsing speedup: backup rules for lexer.l
+ - bf: mi2mu, using midi_voice list...
+
+pl 61.jcn2
+ - all in all mi2mu speedup of about factor 8 since pl61
+ (fugue.midi 82.72user to 10.30user on a 586.133)
+ what about lily?
+ - binary search on track-columns
+ - mi2mu IP*list to Array (implications?!) conversion
+ - mi2mu parsing speedup: backup rules for midi-lexer.l
+ - bf: zero denominator
+**********
pl 62
- make clean bf: remove lex & yacc files too
- added kludge in case measure too long
- added kludge in case of unconnected columns.
- kludged columns get error marker
- kludged lines get error marker
+
+
+pl 61.jcn1
+ - smarter + faster duration-convert using Array
+ - bf: mi2mu compilation/duration-conversions
+ - lots faster mi2mu, hopefully does type 1 too...
+pl 60.jcn1
+ - mi2mu handles non-quantified rests, try mi2mu -b wtk-i/fugue2.midi
+
+
**********
may 14
******
may 2
-pl 58.jnc1
+pl 58.jcn1
- bf: toccata-fuga-E.ly
pl 57.jcn4
- bugfix Voice_group_regs::get_register_p() now is actually called too
- bugfix init of Text_item::pos_i_
-pl 56.jnc1
+pl 56.jcn1
- toccata-fuga-in-E.ly, excerpts with real-life collisions
- \{l,r}{b,f}{toe,heel} --- using cmsy fonts...
- pedal.ly
- Massive Rest/Stem/Collision/Note_column rewrite: resolve
notehead/rest ambiguities and bugs. eg, [c8 r8 c8]
-pl 54.jnc1
+pl 54.jcn1
- standchen.ly: repeats; lyricii to end
- convert-mudela: help + usage
- fixed midi key/meter-change (triggered by martien.ly) bug
+Features you cannot find in the doco as working, should be mentioned her.
+
This is an assorted collection of stuff that will be done, might be
done, or is an idea that I want to think about
* use Hungarian throughout code
- * rename mf fonts to avoid conflicts with musixtex
- check (c) issues
-
* decent TeX page layout
* per-pstaff item-widths [JCN]
* script priority
- * use own fonts/update musixtex fonts
-
* a Hands on tutorial [HKN]
PROJECTS
* Rewrite Beam and Rhythmic_grouping (hairy)
- [c8. c32 c32]
- interbeam height
+ - doc on Rhythmic_grouping
- general shaving
- use plet grouping
- abbreviations [c2 c2]1/2
- slurs
- dynamics etc.
+ * Redo font support
+ - rename mf fonts to avoid conflicts with musixtex
+ - check (c) issues
+ - use own fonts/update musixtex fonts/find older (c)-less fonts
+ - hack up mf sources for decent spacing info (and then
+ read AFM/TFM directly, for text too)
+
PARSER
* Duration -> Musical_duration, typedef Rational Duration?
\bar || ook dunne streepjes? Sluit de balk niet af! (soms met de
ruimte van een hele maat erachter (bij unmatching staffs)
-Hele rusten ook in andere maatsoort dan 4/4 (en centreren in de maat)
-
noten staan vaak te dicht aan de rechterkant van de maatstreep.
optie om nummers/markers boven maatstrepen te zetten
BUGS
+ * mi2mu nonexist.midi
+
* staccato dot positions.
+ * \meter 4/4; c1. doesn't gen bar.
+
* stacked scripts.
* redo timing stuff <-> pulk to allow \meter 2/4; e2. to work
* half-sharps, half-flats
+ * resync barcheck.
+
* key undo
* unix style paths for LILYINCLUDE env
* indentable stream as baseclass for TeX stream, lily stream, Dstream.
+ * handle EOF graciously in error messages.
+
* caching Item/spanner dimensions.
* key transposition
+ * centered whole rest
+
* caching breakpoints / saving them.
* use dstream feature in mi2mu
* qtor, btor, mtor-> tor( QUIET_ver ), tor( DEBUG_ver ), etc.
+ * use tors feature in lily
* declare notenametab?
- * use tors feature in lily
-
* do conventional keys (C G A, F B E, a e fis, d as des, etc ),
besides lists of flats/sharps
- * update for T70 fonts or newer
-
* midi esp.: use I32 iso int where 32 bits are needed (or assumed...)
* parshape
* configure idealspacing: arithmetic spacing
-
* LilyPond .deb. Other packaging methods?
* detect -pipe
DOC
-
- * beam generation.
-
* all errors
+
+ * config of TeX macros
* a test suite
+ * hacking-HOWTO
+
FUTURE
* auxilliary file for caching info.
* y -dims in internote?
- * hack up mf sources for decent spacing info (and then
- read AFM/TFM directly, for text too)
-
* merge Atom and Symbol?
* merge common code of Item, Atom/Molecule
* Staff_group, Score_request_register.
- * SHIT: meters/bars should be aligned, which is difficult if
+ * Meters/bars should be aligned, which is difficult if
we get different keychanges in different staffs.
* caching breakpoints
#!/usr/bin/perl -w
-# TODO check ret status of various stuff
use FileHandle;
+# do something, check return status
sub my_system
{
my (@cmds) = @_;
#!/usr/bin/perl
+
+
$reldir="~/musix/releases";
+use FileHandle;
+
sub cmpver
{
@versions = sort cmpver @versions;
my $last= (pop @versions);
-print $last;
-system "rm $reldir/zZ*";
+system "rm $reldir/zZ*";
system "> $reldir/zZ_LATEST_IS_$last";
+
+open NEWS, "tar --to-stdout -zxf $reldir/lilypond-$last.tar.gz lilypond-$last/NEWS |";
+input_record_separator NEWS "****";
+$desc = <NEWS>;
+chop ($desc);
+close NEWS;
+ print $desc;
template<class T> struct sstack;
template<class T,class K> struct Assoc;
template<class T> struct List;
+template<class T> struct Link_list;
template<class T> struct Pointer_list;
-template<class T> struct IPointer_list;
template<class T> struct Cursor;
template<class T> struct PCursor;
template<class T> struct Link;
items are always stored as copies in List, but:
#List<String># : copies of #String# stored
#List<String*># : copies of #String*# stored!
- (do not use, use \Ref{Pointer_list} #<String*># instead.)
+ (do not use, use \Ref{Link_list} #<String*># instead.)
{\bf note:}
retrieving "invalid" cursors, i.e.
#include "varray.hh"
+/**
+ an array of pointers.
+
+ TODO
+ should init to 0.
+ */
template<class T>
-class Pointer_array : public Array<T>
+class Link_array : public Array<T>
{
public:
int find_i (T t) const{
return 0;
}
};
+
#endif // PARRAY_HH
#include "plist.hh"
#include "cursor.hh"
-/** cursor to go with Pointer_list.
- don't create Pointer_list<void*>'s.
+/** cursor to go with Link_list.
+ don't create Link_list<void*>'s.
This cursor is just an interface class for Cursor. It takes care of the
appropriate type casts
*/
template<class T>
class PCursor : private Cursor<void *> {
- friend class IPointer_list<T>;
+ friend class Pointer_list<T>;
/// delete contents
void junk();
return remove_p();
}
- Pointer_list<T> &list() { return (Pointer_list<T>&)Cursor<void*>::list(); }
+ Link_list<T> &list() { return (Link_list<T>&)Cursor<void*>::list(); }
PCursor<T> operator++(int) { return Cursor<void*>::operator++(0);}
PCursor<T> operator--(int) { return Cursor<void*>::operator--(0); }
PCursor<T> operator+=(int i) { return Cursor<void*>::operator+=(i);}
PCursor<T> operator-=(int i) { return Cursor<void*>::operator-=(i); }
PCursor<T> operator -(int no) const { return Cursor<void*>::operator-(no);}
int operator -(PCursor<T> op) const { return Cursor<void*>::operator-(op);}
- PCursor<T> operator +( int no) const {return Cursor<void*>::operator+(no);} PCursor(const Pointer_list<T> & l) : Cursor<void*> (l) {}
+ PCursor<T> operator +( int no) const {return Cursor<void*>::operator+(no);} PCursor(const Link_list<T> & l) : Cursor<void*> (l) {}
PCursor() : Cursor<void*> () {}
PCursor( const Cursor<void*>& cursor ) : Cursor<void*>(cursor) { }
void* vptr() const { return *((Cursor<void*> &) *this); }
/**
A list of pointers.
- Use for list of pointers, e.g. Pointer_list<AbstractType*>.
+ Use for list of pointers, e.g. Link_list<AbstractType*>.
This class does no deletion of the pointers, but it knows how to
copy itself (shallow copy). We could have derived it from List<T>,
- but this design saves a lot of code dup; for all Pointer_lists in the
+ but this design saves a lot of code dup; for all Link_lists in the
program only one parent List<void*> is instantiated.
*/
template<class T>
-class Pointer_list : public List<void *>
+class Link_list : public List<void *>
{
public:
PCursor<T> top() const{
return PCursor<T> (List<void*>::bottom());
}
PCursor<T> find(T) const;
- void concatenate(Pointer_list<T> const &s) { List<void*>::concatenate(s); }
- Pointer_list() {}
+ void concatenate(Link_list<T> const &s) { List<void*>::concatenate(s); }
+ Link_list() {}
};
-/** Pointer_list which deletes pointers given to it.
+/** Link_list which deletes pointers given to it.
NOTE:
The copy constructor doesn't do what you'd want:
new T(*cursor)
- You have to copy this yourself, or use the macro Pointer_list__copy
+ You have to copy this yourself, or use the macro Link_list__copy
*/
template<class T>
-class IPointer_list : public Pointer_list<T> {
+class Pointer_list : public Link_list<T> {
public:
- IPointer_list(IPointer_list const &) { set_empty(); }
- IPointer_list() { }
- ~IPointer_list();
+ Pointer_list(Pointer_list const &) { set_empty(); }
+ Pointer_list() { }
+ ~Pointer_list();
};
-#define IPointer_list__copy(T, to, from, op) \
+#define Pointer_list__copy(T, to, from, op) \
for (PCursor<T> _pc_(from); _pc_.ok(); _pc_++)\
to.bottom().add(_pc_->op)\
\
template<class T>
-void PL_copy(IPointer_list<T*> &dst,IPointer_list<T*> const&src);
+void PL_copy(Pointer_list<T*> &dst,Pointer_list<T*> const&src);
/* -*-c++-*-
plist.icc -- part of flowerlib
- (c) 1996 Han-Wen Nienhuys& Jan Nieuwenhuizen
+ (c) 1996,1997 Han-Wen Nienhuys& Jan Nieuwenhuizen
*/
#ifndef PLIST_INL
template<class T>
void
-PL_copy(IPointer_list<T*> &to, IPointer_list<T*> const&src)
+PL_copy(Pointer_list<T*> &to, Pointer_list<T*> const&src)
{
for (PCursor<T*> pc(src); pc.ok(); pc++) {
T *q = pc;
#include "plist.hh"
-#define PL_instantiate(a) template class Pointer_list<a*>; \
+#define PL_instantiate(a) template class Link_list<a*>; \
template class PCursor<a*>;
#define IPL_instantiate(a) PL_instantiate(a); \
- template class IPointer_list<a*>
+ template class Pointer_list<a*>
template<class T>
-IPointer_list<T>::~IPointer_list()
+Pointer_list<T>::~Pointer_list()
{
PCursor<T> c( *this );
while (c.ok()) {
template<class T>
PCursor<T>
-Pointer_list<T>::find(T what ) const
+Link_list<T>::find(T what ) const
{
PCursor<T> i(*this);
for (; i.ok(); i++)
(*this)[i]=(*this)[j];
(*this)[j]=t;
}
- bool empty() { return !size_; }
+ bool empty() const { return !size_; }
void insert(T k, int j) {
assert(j >=0 && j<= size_);
set_size(size_+1);
Duration dur = mom2standardised_dur( mom );
-// if ( dur.mom() == mom )
- if ( dur.length() == mom )
+// if ( !dur.mom() || ( dur.mom() == mom ) )
+ if ( !dur.length() || ( dur.length() == mom ) )
return dur;
assert( midi_as_plet_b_s );
for ( int i = 0; i < dur_array_s.size() - 1; i++ ) {
Moment lower_mom = dur2_mom( dur_array_s[ i ] );
if ( mom <= lower_mom ) {
- if ( i || ( mom / lower_mom > Moment( 3, 4 ) ) )
+ // all arbitrary, but 1/4 will get rid of the noise...
+// if ( i || ( mom / lower_mom > Moment( 3, 4 ) ) )
+//kinda ok if ( i || ( mom / lower_mom > Moment( 2, 4 ) ) )
+ if ( i || ( mom / lower_mom > Moment( 2, 6 ) ) )
return dur_array_s[ i ];
else
return Duration( 0 );
{
Moment mom( ticks_i, Duration::division_1_i_s );
Duration dur = mom2standardised_dur( mom );
-
-// if ( dur.mom() != mom )
- if ( dur.length() != mom )
- warning( String( "duration not exact: " ) + String( (Real)mom ) );
return dur;
}
plet_.type_i_ = t;
}
+void
+Duration::set_plet(Duration d)
+{
+ plet_.iso_i_ = d.plet_.iso_i_;
+ plet_.type_i_ = d.plet_.type_i_;
+}
+
void
Duration::set_ticks( int ticks_i )
{
{
Source_file * sl = global_sources->get_file_l(s);
if (!sl) {
- LexerError("can't find file");
+ LexerError("Can't find file `" + s+ "'");
return;
- }
+ } else
+
+
char_count_stack_.push(0);
if (yy_current_buffer)
state_stack_.push(yy_current_buffer);
Source_file*
Includable_lexer::source_file_l()const
{
- return include_stack_.top();
+ if (include_stack_.empty())
+ return 0;
+ else
+ return include_stack_.top();
}
bool plet_b();
String str()const;
void set_plet(int,int );
+ void set_plet(Duration );
static bool duration_type_b(int t);
void set_ticks( int ticks_i );
Moment length() const ; // zo naai mij
/*
- includable-lexer.hh -- declare
+ includable-lexer.hh -- declare Includable_lexer
source file of the LilyPond music typesetter
#ifndef INCLUDABLE_LEXER_HH
#define INCLUDABLE_LEXER_HH
-#include "string.hh"
+
#include <FlexLexer.h>
+
+#include "string.hh"
#include "varray.hh"
#include "fproto.hh"
#include "proto.hh"
Array<Source_file*> include_stack_;
Array<int> char_count_stack_;
public:
+
Source_file* source_file_l()const;
void new_input(String s,Sources*);
Includable_lexer();
private:
const File_path * path_C_;
void add( Source_file* sourcefile_p );
- IPointer_list<Source_file*> sourcefile_p_iplist_;
+ Pointer_list<Source_file*> sourcefile_p_iplist_;
bool binary_b_ ;
};
String str = "";
if ( source_file_l_ ) {
- str += source_file_l_->file_line_no_str(defined_ch_C_) + String(": ");
+ str += location_str() + String(": ");
}
str += message_str;
MAJOR_VERSION = 0
MINOR_VERSION = 0
-PATCH_LEVEL = 62
+PATCH_LEVEL = 63
# use to send patches, always empty for released version:
# include separator: ".postfix", "-pl" makes rpm barf
make sure that they reach the beam and that point in the correct
direction */
struct Beam: public Directional_spanner {
- Pointer_list<Stem*> stems;
+ Link_list<Stem*> stems;
/// the slope of the beam in posns / point (dimension)
Real slope;
#include "voice.hh"
#include "moment.hh"
-struct Voice_list : public Pointer_list<Voice*> {
+struct Voice_list : public Link_list<Voice*> {
void translate_time(Moment dt);
};
/// Complex_music consists of multiple voices
struct Complex_music : Input_music {
- IPointer_list<Input_music*> elts;
+ Pointer_list<Input_music*> elts;
/* *************** */
virtual void transpose(Melodic_req const&) const ;
virtual void set_default_group(String g);
#include "input.hh"
struct Input_register : Input {
- IPointer_list<Input_register*> ireg_list_;
+ Pointer_list<Input_register*> ireg_list_;
String name_str_;
void add(Input_register*);
/// paper_, staffs_ and commands_ form the problem definition.
Paper_def *paper_p_;
Midi_def* midi_p_;
- IPointer_list<Input_staff*> staffs_;
+ Pointer_list<Input_staff*> staffs_;
/* *************************************************************** */
class Input_staff:public Input {
public:
- IPointer_list<Input_music*> music_;
+ Pointer_list<Input_music*> music_;
Input_register * ireg_p_;
/* *************** */
#ifndef LOCALKEYREG_HH
#define LOCALKEYREG_HH
+
#include "register.hh"
#include "key.hh"
#include "parray.hh"
Key const *key_C_;
Array<Note_req* > mel_l_arr_;
Array<Item* > support_l_arr_;
- Pointer_array<Item * > forced_l_arr_;
- Pointer_array<Item *> tied_l_arr_;
+ Link_array<Item * > forced_l_arr_;
+ Link_array<Item *> tied_l_arr_;
/* *************** */
virtual void process_requests();
virtual void acknowledge_element(Staff_elem_info);
/** a group of individually translated symbols. You can add molecules
to the top, to the right, etc. */
struct Molecule {
- IPointer_list<Atom*> ats; // change to List<Atom>?
+ Pointer_list<Atom*> ats; // change to List<Atom>?
/* *************** */
class PCol {
public:
- Pointer_list<Item const *> its;
- Pointer_list<Spanner const *> stoppers, starters;
+ Link_list<Item const *> its;
+ Link_list<Spanner const *> stoppers, starters;
/** prebreak is put before end of line.
if broken here, then (*this) column is discarded, and prebreak
Paper_def *paper_l_;
/// the columns, ordered left to right
- IPointer_list<PCol *> cols;
+ Pointer_list<PCol *> cols;
/// the idealspacings, no particular order
- IPointer_list<Idealspacing*> suz;
+ Pointer_list<Idealspacing*> suz;
/// the staffs ordered top to bottom
- IPointer_list<PStaff*> staffs;
+ Pointer_list<PStaff*> staffs;
/// all symbols in score. No particular order.
- IPointer_list<Item*> its;
+ Pointer_list<Item*> its;
/// if broken, the different lines
- IPointer_list<Line_of_score*> lines;
+ Pointer_list<Line_of_score*> lines;
/// crescs etc; no particular order
- IPointer_list<Spanner *> spanners;
+ Pointer_list<Spanner *> spanners;
/// broken spanners
- IPointer_list<Spanner*> broken_spans;
+ Pointer_list<Spanner*> broken_spans;
/* *************** */
/* CONSTRUCTION */
PScore * pscore_l_;
- Pointer_list<Spanner const *> spans;
- Pointer_list<Item*> its;
+ Link_list<Spanner const *> spans;
+ Link_list<Item*> its;
/* *************** */
void add(Item*i);
class Pulk_voices
{
PQueue< Voice_l > voice_pq_;
- IPointer_list< Pulk_voice * > pulk_p_list_;
- Pointer_list<Staff *> staff_l_list_;
+ Pointer_list< Pulk_voice * > pulk_p_list_;
+ Link_list<Staff *> staff_l_list_;
Moment next_mom_;
public:
Moment last_;
bool ok() const;
Moment next_mom() { return next_mom_; }
- Pulk_voices(Pointer_list<Staff*> const&);
+ Pulk_voices(Link_list<Staff*> const&);
void get_aligned_request(Request_column *col_l );
};
*/
class Register_group_register : public Request_register {
protected:
- IPointer_list<Request_register*> reg_list_;
+ Pointer_list<Request_register*> reg_list_;
virtual void do_print()const;
public:
*/
class Request_column
{
- IPointer_list<Staff_column*> staff_cols_;
+ Pointer_list<Staff_column*> staff_cols_;
Array<Staff_column*> staff_col_l_arr_;
+ Moment when_;
public:
Score_column *musical_column_l_, *command_column_l_;
- Request_column(Pointer_list<Staff*> const& );
+ Request_column(Link_list<Staff*> const& );
bool used_b()const;
Moment when();
void add_reqs(int staff_idx, Array<Request*> const&);
/// paper_, staffs_ and commands_ form the problem definition.
Paper_def *paper_p_;
Midi_def *midi_p_;
- IPointer_list<Staff*> staffs_;
+ Pointer_list<Staff*> staffs_;
/// "runtime" fields for setting up spacing
- IPointer_list<Request_column*> rcols_;
+ Pointer_list<Request_column*> rcols_;
- IPointer_list<Score_column*> cols_;
+ Pointer_list<Score_column*> cols_;
PScore *pscore_p_;
Input input_;
/// the columns of a score that form one line.
struct
Line_of_score {
- Pointer_list<PCol *> cols;
+ Link_list<PCol *> cols;
bool error_mark_b_;
// need to store height of each staff.
- IPointer_list<Line_of_staff*> staffs;
+ Pointer_list<Line_of_staff*> staffs;
PScore * pscore_l_; // needed to generate staffs
/* *************** */
public:
Input_register * ireg_p_;
- Pointer_list<Voice*> voice_list_;
+ Link_list<Voice*> voice_list_;
/// runtime field
- Pointer_list<Staff_column*> cols_;
+ Link_list<Staff_column*> cols_;
Score *score_l_;
PScore *pscore_l_;
/* *************************************************************** */
- void add(const Pointer_list<Voice*> &s);
+ void add(const Link_list<Voice*> &s);
void add_voice(Voice *v_p);
Paper_def*paper()const;
It counts braces to prevent nesting errors, and
it will add a comment sign before each newline.
*/
-struct Tex_stream {
+class Tex_stream {
+ void break_line();
+public:
bool outputting_comment;
ostream *os;
int nest_level;
+ /// to check linelen in output. TeX has limits.
+ int line_len_i_;
/// open a file for writing
Tex_stream(String filename);
Voice_element */
Moment duration_;
Voice const *voice_C_;
- IPointer_list<Request*> req_p_list_;
+ Pointer_list<Request*> req_p_list_;
Request * principal_req_l_;
/* *************** */
/** the elements, earliest first.
Please use the member #add()# to add a new element
*/
- IPointer_list<Voice_element *> elts_;
+ Pointer_list<Voice_element *> elts_;
Moment start_;
/* *************** */
*/
+/*
+ backup rules
+
+ after making a change to the lexer rules, run
+ flex -b <this lexer file>
+ and make sure that
+ lex.backup
+ contains no backup states, but only the reminder
+ Compressed tables always back up.
+ (don-t forget to rm lex.yy.cc :-)
+ */
+
+
#include <stdio.h>
#include "string.hh"
}
%[^{\n].*\n {
}
+ %[^{\n] { // backup rule
+ }
%\n {
}
+ %[^{\n].* {
+ }
{WHITE}+ {
}
new_input(s,source_l_g);
yy_pop_state();
}
+<incl>\"[^"]* { // backup rule
+ cerr << "missing end quote" << endl;
+ exit( 1 );
+}
<notes>{RESTNAME} {
const char *s = YYText();
yylval.string = new String (s);
s=s.left_str(s.length_i() - 1);
return scan_bare_word(s);
}
+<INITIAL,lyrics,notes>\\\${BLACK}* { // backup rule
+ cerr << "white expected" << endl;
+ exit( 1 );
+}
+<INITIAL,lyrics,notes>\${BLACK}* { // backup rule
+ cerr << "white expected" << endl;
+ exit( 1 );
+}
<notes>{
{ALPHAWORD}/\' {
post_quotes_b_ = true;
return REAL;
}
+{INT}\. { // backup rule
+ cerr << "int. encountered" << endl;
+ exit( 1 );
+}
+
[{}] {
mtor << "parens\n";
lexer_p_->set_debug( !monitor->silence(s+"Lexer") && check_debug);
#endif
}
+
void
My_lily_parser::print_declarations()
{
void
My_lily_parser::parse_file(String init, String s)
{
- *mlog << "Parsing ... ";
lexer_p_ = new My_lily_lexer;
init_str_ = init;
+
+
+ *mlog << "Parsing ... ";
lexer_p_->new_input(s, source_l_);
+ if (!lexer_p_->source_file_l()) {
+ warning("Can not find toplevel file. Ignoring " + s);
+ return;
+ }
do_yyparse();
print_declarations();
$$ = new Duration;
if ( !Duration::duration_type_b($1) )
THIS->parser_error("Not a duration");
- else
+ else {
$$->type_i_ = $1;
+ $$->set_plet(THIS->default_duration_);
+ }
}
| explicit_duration DOTS {
$$->dots_i_ = $2;
#include "request-column.hh"
#include "debug.hh"
-Pulk_voices::Pulk_voices(Pointer_list<Staff*> const& l)
+Pulk_voices::Pulk_voices(Link_list<Staff*> const& l)
: staff_l_list_(l)
{
int staff_i = 0;
Moment
Request_column::when()
{
-
- return(command_column_l_)? command_column_l_->when(): musical_column_l_->when();
+ if (command_column_l_ || musical_column_l_)
+ when_ = (command_column_l_)? command_column_l_->when()
+ : musical_column_l_->when();
+
+ return when_;
}
void
staff_col_l_arr_[idx]->add_reqs(req_l_arr);
}
-Request_column::Request_column(Pointer_list<Staff*> const& list )
+Request_column::Request_column(Link_list<Staff*> const& list )
{
musical_column_l_ = command_column_l_ =0;
iter(list.top(), j);
staff_cols_.bottom().add(col_p);
j->add_col(col_p);
}
+ when_ = 0;
}
+
void
Request_column::set_score_cols(Score_column* c1, Score_column *c2)
{
i->clean_cols();
for (iter_top(rcols_,i); i.ok(); i++) {
+ i->when(); // update cache, ugh
if (!i->command_column_l_->used_b()) {
i->command_column_l_ = 0;
}
void
-Staff::add(Pointer_list<Voice*> const &l)
+Staff::add(Link_list<Voice*> const &l)
{
for (iter_top(l,i); i.ok(); i++)
voice_list_.bottom().add(i);
iter_top(line_of_score_l_->cols,cc);
Real lastpos=cc->hpos;
+
// all items in the current line & staff.
for (; cc.ok(); cc++) {
- Real delta=cc->hpos - lastpos;
- lastpos = cc->hpos;
-
- // moveover
- if (delta)
- s +=String( "\\kern ") + print_dimen(delta);
+ String chunk_str;
+
+ Real delta = cc->hpos - lastpos;
+
+
if (cc->error_mark_b_) {
- s += String("\\columnerrormark");
+ chunk_str += String("\\columnerrormark");
}
// now output the items.
for (iter_top(cc->its,i); i.ok(); i++) {
if (i->pstaff_l_ == pstaff_l_)
- s += i->TeXstring();
+ chunk_str += i->TeXstring();
}
// spanners.
for (iter_top(cc->starters,i); i.ok(); i++)
if (i->pstaff_l_ == pstaff_l_)
- s += i->TeXstring();
+ chunk_str += i->TeXstring();
+
+ if (chunk_str!="") {
+ // moveover
+ if (delta)
+ s +=String( "\\kern ") + print_dimen(delta);
+ s += chunk_str;
+ lastpos = cc->hpos;
+ }
}
}
s+="\\hss}\\vss}";
/*
- template4.cc -- instantiate Pointer_list baseclass.
+ template4.cc -- instantiate Link_list baseclass.
source file of the LilyPond music typesetter
#include "tex-stream.hh"
#include "debug.hh"
+const int MAXLINELEN = 200;
+
Tex_stream::Tex_stream(String filename)
{
os = new ofstream(filename);
if (!*os)
error("can't open `" + filename+"\'");
nest_level = 0;
+ line_len_i_ = 0;
outputting_comment=false;
header();
}
}
continue;
}
+ line_len_i_ ++;
switch(*cp)
{
case '%':
/* FALLTHROUGH */
case '\n':
- *os << "%\n";
- *os << String(' ', nest_level);
+ break_line();
break;
+ case ' ':
+ *os << ' ';
+ if (line_len_i_ > MAXLINELEN)
+ break_line();
+
+ break;
default:
*os << *cp;
break;
return *this;
}
+void
+Tex_stream::break_line()
+{
+ *os << "%\n";
+ *os << String(' ', nest_level);
+ line_len_i_ = 0;
+}
/* *************************************************************** */
$(outdir)/%.cc: %.l
$(FLEX) -Cfe -p -p -t $< > $@
+# could be faster:
+# $(FLEX) -8 -Cf -t $< > $@
$(outdir)/%.text: $(outdir)/%.1
groff -man -Tascii $< > $@
Begin3
Title: LilyPond
-Version: 0.0.62
-Entered-date: 05/14/97
+Version: 0.0.63
+Entered-date: 05/15/97
Description: LilyPond is a program which converts a music-script (mudela) into
TeX output, or MIDI to produce multi-staff scores. Features include multiple
meters, clefs, keys, lyrics, versatile input-language, cadenzas
jan@digicash.com (Jan Nieuwenhuizen)
Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys)
Primary-site: pcnov095.win.tue.nl /pub/lilypond/
- 300k lilypond-0.0.62.tar.gz
+ 300k lilypond-0.0.63.tar.gz
Alternate-site:
Original-site:
Platform: unix/win32, GNU C++
Name: lilypond
-Version: 0.0.62
+Version: 0.0.63
Release: 1
Copyright: GPL
Group: Applications/Publishing
-Source0: pcnov095.win.tue.nl:/pub/lilypond/lilypond-0.0.62.tar.gz
+Source0: pcnov095.win.tue.nl:/pub/lilypond/lilypond-0.0.63.tar.gz
Summary: A preprocessor to make TeX typeset music.
URL: http://www.stack.nl/~hanwen/lilypond
Packager: Han-Wen Nienhuys <hanwen@stack.nl>
strip bin/lilypond bin/mi2mu
make prefix="$RPM_BUILD_ROOT/usr" install
%files
-%doc Documentation/out/AUTHORS.text Documentation/out/CodingStyle.text Documentation/out/INSTALL.text Documentation/out/MANIFESTO.text Documentation/out/convert-mudela.text Documentation/out/error.text Documentation/out/faq.text Documentation/out/index.text Documentation/out/language.text Documentation/out/lilygut.text Documentation/out/lilypond.text Documentation/out/mi2mu.text Documentation/out/mudela.text input/cadenza.ly input/collisions.ly input/coriolan-alto.ly input/error.ly input/header.ly input/keys.ly input/kortjakje.ly input/pedal.ly input/rhythm.ly input/scales.ly input/scripts.ly input/scsii-menuetto.ly input/scsii-menuetto.tex input/slurs.ly input/standchen.ly input/standchen.tex input/toccata-fuga-E.ly input/twinkle.ly input/wohltemperirt.ly Documentation/lelie_logo.gif
+%doc Documentation/out/AUTHORS.text Documentation/out/CodingStyle.text Documentation/out/INSTALL.text Documentation/out/MANIFESTO.text Documentation/out/convert-mudela.text Documentation/out/error.text Documentation/out/faq.text Documentation/out/gnu-music.text Documentation/out/index.text Documentation/out/language.text Documentation/out/lilygut.text Documentation/out/lilyliterature.text Documentation/out/lilypond.text Documentation/out/mi2mu.text Documentation/out/mudela.text input/cadenza.ly input/collisions.ly input/coriolan-alto.ly input/error.ly input/header.ly input/keys.ly input/kortjakje.ly input/pedal.ly input/rhythm.ly input/scales.ly input/scripts.ly input/scsii-menuetto.ly input/scsii-menuetto.tex input/slurs.ly input/standchen.ly input/standchen.tex input/toccata-fuga-E.ly input/twinkle.ly input/wohltemperirt.ly Documentation/lelie_logo.gif
/usr/bin/convert-mudela
/usr/bin/lilypond
/usr/lib/libflower.so
MAJOR_VERSION = 0
MINOR_VERSION = 0
-PATCH_LEVEL = 15
+PATCH_LEVEL = 16
# use to send patches, always empty for released version:
MY_PATCH_LEVEL =
#
#undef mtor
#endif
+#define MVOICE_LIST
+
#include "string.hh"
#include "string-convert.hh"
void process();
private:
- IPointer_list<Midi_track*> midi_track_p_list_;
+ Pointer_list<Midi_track*> midi_track_p_list_;
int format_i_;
int tracks_i_;
int tempo_i_;
int number_i_;
private:
- void add_begin_at( Pointer_list<Midi_voice*>& open_voices_r, Moment mom );
+#ifdef MVOICE_LIST
+ void add_begin_at( Link_list<Midi_voice*>& open_voices_r, Moment mom );
+#else
+ void add_begin_at( Array<Midi_voice*>& open_voices_r, Moment mom );
+#endif
int check_begin_bar_i( Moment now_mom, int open_bar_i );
int check_end_bar_i( Moment now_mom, int open_bar_i );
Midi_voice* get_free_midi_voice_l( Moment mom );
- void remove_end_at( Pointer_list<Midi_voice*>& open_voices_r, Moment mom );
+#ifdef MVOICE_LIST
+ void remove_end_at( Link_list<Midi_voice*>& open_voices_r, Moment mom );
+#else
+ void remove_end_at( Array<Midi_voice*>& open_voices_r, Moment mom );
+#endif
void output_mudela_begin_bar( Lily_stream& lily_stream_r, Moment now_mom, int bar_i );
void output_mudela_rest( Lily_stream& lily_stream_r, Moment begin_mom, Moment end_mom );
void output_mudela_rest_remain( Lily_stream& lily_stream_r, Moment mom );
- IPointer_list<Track_column*> tcol_p_list_;
- IPointer_list<Midi_voice*> midi_voice_p_list_;
+#ifdef TCOL_LIST
+#warning using track_column list
+ Pointer_list<Track_column*> tcol_p_list_;
+#else
+ Array<Track_column*> tcol_p_array_;
+#endif
+#ifdef MVOICE_LIST
+#warning using midi_voice list
+ Pointer_list<Midi_voice*> midi_voice_p_list_;
+#else
+ Array<Midi_voice*> midi_voice_p_array_;
+#endif
};
#endif // MIDI_TRACK_HH
Moment begin_mom();
Moment end_mom();
- String mudela_str( Moment to_mom, Moment to_mom, bool multiple_bo );
- // ARE you sure? ^^ ^^
+ String mudela_str( Moment from_mom, Moment to_mom, bool multiple_bo );
private:
- int events_i_;
- Moment end_mom_;
- Moment begin_mom_;
- IPointer_list<Midi_event*> midi_event_p_list_;
+ int events_i_;
+ Moment end_mom_;
+ Moment begin_mom_;
+#ifdef MEVENT_LIST
+#error using list
+ Pointer_list<Midi_event*> midi_event_p_list_;
+#else
+ Array<Midi_event*> midi_event_p_array_;
+#endif
};
#endif // MIDI_VOICE_HH
Moment mom();
//private:
- IPointer_list<Midi_event*> midi_event_p_list_;
+#ifdef MEVENT_LIST
+#error using list
+ Pointer_list<Midi_event*> midi_event_p_list_;
+#else
+ Array<Midi_event*> midi_event_p_array_;
+#endif
Moment mom_;
};
0,0,0
};
Getopt_long getopt_long( argc_i, argv_sz_a, long_option_init_a );
- identify();
String output_str;
while ( Long_option_init* long_option_init_p = getopt_long() )
level_ver = DEBUG_ver;
break;
case 'h':
+ identify();
usage();
exit( 0 );
break;
case 's': {
int i = String_convert::dec2_i( getopt_long.optarg );
if ( !i ) {
+ identify();
usage();
exit( 2 ); //usage
}
level_ver = VERBOSE_ver;
break;
case 'w':
+ identify();
notice();
exit( 0 );
break;
break;
}
+ // flag -q must be checked first
+ identify();
+
char* arg_sz = 0;
while ( ( arg_sz = getopt_long.get_next_arg() ) ) {
My_midi_parser midi_parser( arg_sz, & source );
%{//-*-Fundamental-*-
// midi-lexer.l
+/*
+ backup rules
+
+ after making a change to the lexer rules, run
+ flex -b <this lexer file>
+ and make sure that
+ lex.backup
+ contains no backup states, but only the reminder
+ Compressed tables always back up.
+ (don-t forget to rm lex.yy.cc :-)
+ */
#include "mi2mu.hh"
#include "midi-parser.hh"
U8 [\x00-\xff]
I8 {U8}
INT16 {U8}{U8}
+BACKUP_INT16_0 {U8}
INT32 {INT16}{INT16}
+BACKUP_INT32_0 {U8}
+BACKUP_INT32_1 {U8}{U8}
+BACKUP_INT32_2 {INT16}{U8}
INT7_8UNSET [\x00-\x7f]
INT7_8SET [\x80-\xff]
VARINT {INT7_8SET}{0,3}{INT7_8UNSET}
+BACKUP_VARINT_0 {INT7_8SET}
+BACKUP_VARINT_1 {INT7_8SET}{INT7_8SET}
+BACKUP_VARINT_2 {INT7_8SET}{INT7_8SET}{INT7_8SET}
HEADER MThd
TRACK MTrk
+BACKUP_TOP_0 MT
+BACKUP_TOP_1 MTh
+BACKUP_TOP_2 MTr
XRUNNING_STATUS [\x30-\x4f]
RUNNING_STATUS [\x00-\x5f]
%%
-{HEADER}/{INT32} { // using /{INT32}; longer match than {INT32}
+{HEADER} { // huh? using {HEADER}/{INT32}; longer match than {INT32}
tor( DEBUG_ver ) << "lex: header" << endl;
yy_push_state( int16 );
yy_push_state( int16 );
return HEADER;
}
-{TRACK}/{INT32} { // using /{INT32}; longer match than {INT32}
+{TRACK} { // huh? using {TRACK}/{INT32}; longer match than {INT32}
tor( DEBUG_ver ) << "lex: track" << endl;
yy_push_state( track );
yy_push_state( int32 );
return TRACK;
}
{U8} {
- error( String( "top level: illegal byte: " )
+ error( String( "top level: header expected: " )
+ String_convert::bin2hex_str( String( *YYText() ) ) );
exit( 1 );
}
+{BACKUP_TOP_0} {
+ error( String( "top level: header expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
+{BACKUP_TOP_1} {
+ error( String( "top level: header expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
+{BACKUP_TOP_2} {
+ error( String( "top level: header expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
<int32>{INT32} { // really signed?
tor( DEBUG_ver ) << "lex: int32" << endl;
assert( YYLeng() == 4 );
yy_pop_state();
return INT32;
}
+<int32>{BACKUP_INT32_0} {
+ error( String( "int32: int32 expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
+<int32>{BACKUP_INT32_1} {
+ error( String( "int32: int32 expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
+<int32>{BACKUP_INT32_2} {
+ error( String( "int32: int32 expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
<int16>{INT16} { // really signed?
tor( DEBUG_ver ) << "lex: int16" << endl;
assert( YYLeng() == 2 );
String str( (Byte const*)YYText(), YYLeng() );
- yylval.i = String_convert::bin2_i( str );
+ yylval.i = (short)String_convert::bin2_i( str );
yy_pop_state();
return INT16;
}
+<int16>{BACKUP_INT16_0} {
+ error( String( "int16: int16 expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
<i8>{I8} {
tor( DEBUG_ver ) << "lex: i8" << endl;
assert( YYLeng() == 1 );
+ String_convert::bin2hex_str( String( *YYText() ) ) );
exit( 1 );
}
+<track>{BACKUP_VARINT_0}{U8} {
+ error( String( "track: varint expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
+<track>{BACKUP_VARINT_1}{U8} {
+ error( String( "track: varint expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
+<track>{BACKUP_VARINT_2}{U8} {
+ error( String( "track: varint expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
<event>{RUNNING_STATUS} {
// yylval.byte = *(Byte*)YYText();
yylval.i = *(Byte*)YYText();
+ String_convert::bin2hex_str( String( *YYText() ) ) );
exit( 1 );
}
+<data>{BACKUP_VARINT_0}{U8} {
+ error( String( "data: varint expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
+<data>{BACKUP_VARINT_1}{U8} {
+ error( String( "data: varint expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
+<data>{BACKUP_VARINT_2}{U8} {
+ error( String( "data: varint expected: " )
+ + String_convert::bin2hex_str( String( *( YYText() ) ) ) );
+ exit( 1 );
+}
<<EOF>> {
// tor( NORMAL_ver ) << "<<EOF>>";
name_str_ = track_name_str;
midi_time_p_ = new Midi_time( 4, 2, 24, 8 );
midi_tempo_p_ = new Midi_tempo( 1000000 );
+#ifdef TCOL_LIST
+#error doing list!
tcol_p_list_.bottom().add( new Track_column( Moment( 0 ) ) );
+#else
+ tcol_p_array_.push( new Track_column( Moment( 0 ) ) );
+#endif
}
Midi_track::~Midi_track()
delete midi_tempo_p_;
}
+#ifdef MVOICE_LIST
void
-Midi_track::add_begin_at( Pointer_list<Midi_voice*>& open_voices_r, Moment mom )
+Midi_track::add_begin_at( Link_list<Midi_voice*>& open_voices_r, Moment mom )
{
for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
if ( i->begin_mom() == mom ) {
open_voices_r.bottom().add( *i );
}
}
+#else
+void
+Midi_track::add_begin_at( Array<Midi_voice*>& open_voices_r, Moment mom )
+{
+ for ( int i = 0; i < midi_voice_p_array_.size(); i++ )
+ if ( midi_voice_p_array_[ i ]->begin_mom() == mom ) {
+ tor( DEBUG_ver ) << "open_voices (" << open_voices_r.size() << "): +1\n";
+ open_voices_r.push( midi_voice_p_array_[ i ] );
+ }
+}
+#endif
void
Midi_track::add_event( Moment mom, Midi_event* midi_event_p )
{
// heu..
Moment mom = 0.0;
+#ifdef MVOICE_LIST
for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
mom = i->end_mom() >? mom;
+#else
+ for ( int i = 0; i < midi_voice_p_array_.size(); i++ )
+ mom = midi_voice_p_array_[ i ]->end_mom() >? mom;
+#endif
return mom;
}
Midi_voice*
Midi_track::get_free_midi_voice_l( Moment mom )
{
- for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
+#ifdef MVOICE_LIST
+ Real f = mom;
+ for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ ) {
+ Real e = i->end_mom();
if ( i->end_mom() == mom )
return *i;
+ }
Midi_voice* midi_voice_p = new Midi_voice( mom );
Midi_voice* midi_voice_l = midi_voice_p;
midi_voice_p_list_.bottom().add( midi_voice_p );
return midi_voice_l;
+#else
+ Real f = mom;
+ for ( int i = 0; i < midi_voice_p_array_.size(); i++ ) {
+ Real e = i->end_mom();
+ if ( midi_voice_p_array_[ i ]->end_mom() == mom )
+ return midi_voice_p_array_[ i ];
+ }
+
+ Midi_voice* midi_voice_p = new Midi_voice( mom );
+ Midi_voice* midi_voice_l = midi_voice_p;
+ midi_voice_p_array_.push( midi_voice_p );
+ return midi_voice_l;
+#endif
}
String
{
// Moment begin_mom = Midi_track::end_mom() + 1;
Moment begin_mom = Midi_track::end_mom();
+#ifdef MVOICE_LIST
for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
-// if ( i->begin_mom() >= now_mom )
+// if ( i->begin_mom() >= now_mom )// well, which one ?
if ( i->begin_mom() > now_mom )
begin_mom = begin_mom <? i->begin_mom();
+#else
+ for ( int i = 0; i < midi_voice_p_array_.size(); i++ )
+ if ( midi_voice_p_array_[ i ]->begin_mom() >= now_mom ) // well, which one ?
+ if ( midi_voice_p_array_[ i ]->begin_mom() > now_mom )
+// begin_mom = begin_mom <? midi_voice_p_array_[ i ]->begin_mom();
+#endif
return begin_mom;
}
Midi_track::next_end_mom( Moment now_mom )
{
Moment end_mom = Midi_track::end_mom();
+#ifdef MVOICE_LIST
for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
if ( i->end_mom() > now_mom )
end_mom = end_mom <? i->end_mom();
+#else
+ for ( int i = 0; i < midi_voice_p_array_.size(); i++ )
+// if ( midi_voice_p_array_[ i ]->end_mom() >= now_mom )
+ if ( midi_voice_p_array_[ i ]->end_mom() > now_mom )
+ end_mom = end_mom <? midi_voice_p_array_[ i ]->end_mom();
+#endif
return end_mom;
}
/*
columns to voices
*/
- int bar_i = 1;
+// int bar_i = 1;
+ int bar_i = 0;
+#ifdef TCOL_LIST
for ( PCursor<Track_column*> i( tcol_p_list_.top() ); i.ok(); i++ ) {
int begin_bar_i = check_begin_bar_i( i->mom(), bar_i );
if ( begin_bar_i )
get_free_midi_voice_l( i->mom() )->add_event( i->midi_event_p_list_.top().remove_p() );
bar_i = check_end_bar_i( i->mom(), bar_i );
}
+#else
+ for ( int i = 0; i < tcol_p_array_.size(); i++ ) {
+ Track_column* tcol_l = tcol_p_array_[ i ];
+ int begin_bar_i = check_begin_bar_i( tcol_l->mom(), bar_i );
+ if ( begin_bar_i )
+ tor( NORMAL_ver ) << begin_bar_i << flush;
+#ifdef MEVENT_LIST
+ while ( tcol_l->midi_event_p_list_.size() )
+ get_free_midi_voice_l( tcol_l->mom() )->add_event( tcol_l->midi_event_p_list_.top().remove_p() );
+#else
+ // what's efficient here?
+#if 0 // heu, what's different here?
+ while ( tcol_l->midi_event_p_array_.size() ) {
+ get_free_midi_voice_l( tcol_l->mom() )->add_event( tcol_l->midi_event_p_array_[ 0 ] );
+ tcol_l->midi_event_p_array_.del( 0 );
+ }
+#else
+ for ( int i = 0; i < tcol_l->midi_event_p_array_.size(); i++ ) {
+ get_free_midi_voice_l( tcol_l->mom() )->add_event( tcol_l->midi_event_p_array_[ i ] );
+ tcol_l->midi_event_p_array_[ i ] = 0;
+ }
+ tcol_l->midi_event_p_array_.clear();
+#endif
+#endif
+ bar_i = check_end_bar_i( tcol_l->mom(), bar_i );
+ }
+#endif
tor( DEBUG_ver ) << "ends: " << endl;
int n = 0;
+#ifdef MVOICE_LIST
for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
tor( VERBOSE_ver ) << "voice " << n++ << ": " << i->end_mom() << endl;
+#else
+ for ( int i = 0; i < midi_voice_p_array_.size(); i++ )
+ tor( VERBOSE_ver ) << "voice " << n++ << ": " << midi_voice_p_array_[ i ]->end_mom() << endl;
+#endif
tor( DEBUG_ver ) << ":sdne" << endl;
}
lily_stream_r << "% instrument:" << instrument_str_;
lily_stream_r.newline();
+// int bar_i = 1;
int bar_i = 0;
- Pointer_list<Midi_voice*> open_voices;
+#ifdef MVOICE_LIST
+ Link_list<Midi_voice*> open_voices;
+#else
+ Array<Midi_voice*> open_voices;
+#endif
Moment now_mom = 0.0;
Real now_f = now_mom;
Real begin_f = 0;
if ( start_of_track_bo ) {
start_of_track_bo = false;
String str;
+#ifdef MVOICE_LIST
for ( PCursor<Midi_voice*> i( open_voices.top() ); i.ok(); i++ )
lily_stream_r << i->mudela_str( now_mom, then_mom, open_voices.size() - 1 );
+#else
+ for ( int i = 0; i < open_voices.size(); i++ )
+ lily_stream_r << open_voices[ i ]->mudela_str( now_mom, then_mom, open_voices.size() - 1 );
+#endif
if ( str.length_i() )
lily_stream_r << str;
else
output_mudela_rest( lily_stream_r, now_mom, then_mom );
}
else {
+#ifdef MVOICE_LIST
for ( PCursor<Midi_voice*> i( open_voices.top() ); i.ok(); i++ )
lily_stream_r << i->mudela_str( now_mom, then_mom, open_voices.size() - 1 );
+#else
+ for ( int i = 0; i < open_voices.size(); i++ )
+ lily_stream_r << open_voices[ i ]->mudela_str( now_mom, then_mom, open_voices.size() - 1 );
+#endif
if ( !open_voices.size() )
output_mudela_rest( lily_stream_r, now_mom, then_mom );
}
now_mom = then_mom;
}
- bar_i++;
- tor( NORMAL_ver ) << '[' << bar_i << ']' << flush;
+// bar_i++;
+// tor( NORMAL_ver ) << '[' << bar_i << ']' << flush;
lily_stream_r.tnedni();
lily_stream_r << "} % " << name_str();
output_mudela_begin_bar( lily_stream_r, now_mom, begin_bar_i );
lily_stream_r << "r1 ";
// *lily_stream_r.os_p_ << flush;
- tor( NORMAL_ver ) << begin_bar_i << flush;
+ if ( begin_bar_i )
+ tor( NORMAL_ver ) << begin_bar_i << flush;
bar_i = check_end_bar_i( now_mom, bar_i );
now_mom += bar_mom;
}
lily_stream_r << "r" << dur.str() << " ";
}
+
+#ifdef MVOICE_LIST
void
-Midi_track::remove_end_at( Pointer_list<Midi_voice*>& open_voices_r, Moment mom )
+Midi_track::remove_end_at( Link_list<Midi_voice*>& open_voices_r, Moment mom )
{
for ( PCursor<Midi_voice*> i( open_voices_r.top() ); i.ok(); i++ )
// if ( i->end_mom() == mom ) { }
break;
}
}
+#else
+void
+Midi_track::remove_end_at( Array<Midi_voice*>& open_voices_r, Moment mom )
+{
+ for ( int i = 0; i < open_voices_r.size(); i++ )
+ if ( midi_voice_p_array_[ i ]->end_mom() <= mom ) {
+ tor( DEBUG_ver ) << "open_voices (" << open_voices_r.size() << "): -1\n";
+ open_voices_r[ i ] = 0;
+// open_voices_r.del( i-- );
+ open_voices_r.del( i );
+ }
+}
+#endif
void
Midi_track::set_tempo( int useconds_per_4_i )
Track_column*
Midi_track::tcol_l( Moment mom )
{
+#ifdef TCOL_LIST
for ( PCursor<Track_column*> i( tcol_p_list_.top() ); i.ok(); i++ ) {
- if ( i->mom() == mom )
- return *i;
- if ( i->mom() > mom ) {
+ if ( i->mom() > mom ) { //not used, let's use array!
+ assert( 0 );
Track_column* tcol_p = new Track_column( mom );
i.insert( tcol_p );
return tcol_p;
}
+ if ( i->mom() == mom )
+ return *i;
}
Track_column* tcol_p = new Track_column( mom );
tcol_p_list_.bottom().add( tcol_p );
return tcol_p;
+#elif 0
+ for ( int i = 0; i < tcol_p_array_.size(); i++ )
+ if ( tcol_p_array_[ i ]->mom() == mom )
+ return tcol_p_array_[ i ];
+
+ Track_column* tcol_p = new Track_column( mom );
+ tcol_p_array_.push( tcol_p );
+ return tcol_p;
+#else
+ /*
+ as "insert" is never called, the right column will
+ always be found, unless mom > tcol_p_array[ i ]->mom().
+ */
+ int upper_i = max( 0, tcol_p_array_.size() - 1 );
+ int lower_i = 0;
+ int i = upper_i;
+ while ( 1 ) {
+ Moment i_mom = tcol_p_array_[ i ]->mom();
+ if ( i_mom == mom )
+ return tcol_p_array_[ i ];
+ if ( mom < i_mom )
+ upper_i = i;
+ else
+ lower_i = i;
+ if ( ( upper_i == lower_i ) || ( i == tcol_p_array_.size() - 1 ) ) {
+// huh? assert ( upper_i == tcol_p_array_.size() );
+ Track_column* tcol_p = new Track_column( mom );
+ tcol_p_array_.push( tcol_p );
+ return tcol_p;
+ }
+ i = ( upper_i + lower_i + 1 ) / 2;
+ }
+ assert( 0 );
+ return 0;
+#endif
}
void
Midi_voice::add_event( Midi_event* midi_event_p )
{
+#ifdef MEVENT_LIST
midi_event_p_list_.bottom().add( midi_event_p );
+#else
+ midi_event_p_array_.push( midi_event_p );
+#endif
}
Moment
Moment
Midi_voice::end_mom()
{
+#ifdef MEVENT_LIST
// if ( events_i_ == midi_event_p_list_.length_i() )
if ( events_i_ == midi_event_p_list_.size() )
return end_mom_;
// events_i_ = midi_event_p_list_.length_i();
events_i_ = midi_event_p_list_.size();
return end_mom_;
+#else
+ if ( events_i_ == midi_event_p_array_.size() )
+ return end_mom_;
+ Moment now_mom = begin_mom_;
+ tor( DEBUG_ver ) << now_mom << ", ";
+ for ( int i = 0; i < midi_event_p_array_.size(); i++ ) {
+ tor( DEBUG_ver ) << now_mom << ", ";
+ now_mom += midi_event_p_array_[ i ]->mom();
+ }
+ tor( DEBUG_ver ) << endl;
+ end_mom_ = now_mom;
+ events_i_ = midi_event_p_array_.size();
+ return end_mom_;
+#endif
}
String
{
String str;
- if ( begin_mom() >= to_mom )
+// if ( begin_mom() >= to_mom )
+ if ( begin_mom() > to_mom )
return "";
- if ( end_mom() <= from_mom )
+// if ( end_mom() <= from_mom )
+ if ( end_mom() < from_mom )
return "";
Moment now_mom = begin_mom();
+#ifdef MEVENT_LIST
PCursor<Midi_event*> i( midi_event_p_list_.top() );
for ( ; i.ok() && now_mom < from_mom ; i++ )
now_mom += i->mom();
now_mom += i->mom();
str += i->mudela_str( false ) + " ";
}
+#else
+ int i = 0;
+ for ( ; i < midi_event_p_array_.size() && now_mom < from_mom ; i++ )
+ now_mom += midi_event_p_array_[ i ]->mom();
+
+ for ( ; i < midi_event_p_array_.size() && now_mom < to_mom ; i++ ) {
+ now_mom += midi_event_p_array_[ i ]->mom();
+ str += midi_event_p_array_[ i ]->mudela_str( false ) + " ";
+ }
+#endif
if ( str.length_i() && multiple_bo )
str = "{ " + str + "} ";
void
My_midi_parser::forward( int i )
{
- now_i64_ += i;
+ if ( Duration_convert::no_quantify_b_s ) {
+ now_i64_ += i;
+ return;
+ }
+ while ( i > Duration::division_1_i_s ) {
+ now_i64_ += Duration::division_1_i_s;
+ i -= Duration::division_1_i_s;
+ }
+ Duration dur = Duration_convert::ticks2standardised_dur( i );
+ now_i64_ += Duration_convert::dur2ticks_i( dur );
}
Moment
Duration dur( 0 );
if ( Duration_convert::no_quantify_b_s )
dur = Duration_convert::ticks2_dur( (I64)now_i64_ - start_i64 );
- else
+ else {
dur = Duration_convert::ticks2standardised_dur( (I64)now_i64_ - start_i64 );
+ // checking myself iso using tor saves some time
+ if ( level_ver >= VERBOSE_ver ) {
+ Moment mom( (I64)now_i64_ - start_i64, Duration::division_1_i_s );
+ if ( dur.length() != mom )
+ warning( String( "duration not exact: " ) + String( (Real)mom ) );
+ }
+ }
return new Midi_note( midi_key_p_->notename_str( pitch_i ), dur );
}
#include "plist.hh"
#include "plist.tcc"
-IPL_instantiate(Midi_event);
+//IPL_instantiate(Midi_event);
IPL_instantiate(Midi_track);
-PL_instantiate(Midi_voice);
-IPL_instantiate(Midi_voice);
-IPL_instantiate(Track_column);
+// PL_instantiate(Midi_voice);
+// IPL_instantiate(Midi_voice);
+//IPL_instantiate(Track_column);
void
Track_column::add_event( Midi_event* midi_event_p )
{
+#ifdef MEVENT_LIST
midi_event_p_list_.bottom().add( midi_event_p );
+#else
+ midi_event_p_array_.push( midi_event_p );
+#endif
}
Moment
% TeXbook ex 7.7
\def\ifundefined#1{\expandafter\ifx\csname#1\endcsname\relax}
+% skip if included already
\def\SkipLilydefs{\endinput}
\ifundefined{EndLilyPondOutput}
\def\EndLilyPondOutput{\csname bye\endcsname}
\SkipLilydefs
% should use \endinput
- \def\mdef#1#2{\def#1{\mchar{#2}}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% macros to shorten other definitions
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\mdef#1#2{\def#1{\mchar{#2}}}
\def\mchar#1{\musicfnt\char#1}
\def\rationalmultiply#1*#2/#3{\multiply #1 by #2 \divide #1 by #3}
\def\maccentraise#1#2{\dimen0=\noteheight
\def\rightalign#1{\hbox to 0pt{\hss#1}}
-%% musix defs
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% set up dimensions
\parindent=0pt
\newdimen\smallspace
\newdimen\interlinedist
- \newcount\n
- \newdimen\balkhoog
- \newdimen\notewidth
- \newdimen\noteheight
- \newdimen\notewidthhalf
- \newdimen\notewidthdouble
- \newdimen\staffrulethickness
- \newdimen\interstaffrule
+\newcount\n
+\newdimen\balkhoog
+\newdimen\notewidth
+\newdimen\noteheight
+\newdimen\notewidthhalf
+\newdimen\notewidthdouble
+\newdimen\staffrulethickness
+\newdimen\interstaffrule
\newdimen\balkhalf
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% set fonts and primary dimensions
\def\musixtwentydefs{
\font\textfont=cmr10
\font\meterfont=cmbx12
\musixcalc
}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% do derivative calcs
+
\def\musixcalc{
\interlinedist=\fontdimen5\musicfnt
\smallspace=.3\interlinedist
\balkhalf=\balkhoog
\rationalmultiply\balkhalf*1/2
}
-% \def\dyn{\italicfont}
+
+% dynamics take extra kerning
\def\dyn{\dynfont}
\def\kdynf{\dynfont f\kern-.1ex}
\def\kdynm{\dynfont m\kern-.15ex}
\def\dynff{\dynf\kdynf}
\def\dynfff{\dynff\kdynf}
-\def\slurcharh#1{{\slurhfont\char#1}}
-\def\slurcharu#1{{\slurufont\char#1}}
-\def\slurchard#1{{\slurdfont\char#1}}
-\def\hslurcharh#1{{\hslurhfont\char#1}}
-\def\hslurcharu#1{{\hslurufont\char#1}}
-\def\hslurchard#1{{\hslurdfont\char#1}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% provide interface to musixtex fonts
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\mdef\quartball{'007}
\mdef\halfball{'010}
\mdef\wholeball{'011}
\mdef\uhundredtwentyeighthflag{44}
\maccentdef\repeatcolon{55}{2/1}
-\def\emptybar{}
-
-\def\thinbar{\vrule height\balkhoog}
-\def\thickbar{\vrule height\balkhoog width 2\smallspace}
-\def\maatstreep{\thinbar}
-%? what-s wrong with rightalign?
-\def\finishbar{\rightalign{\thinbar\kern\smallspace\thickbar}}
-%%% \def\finishbar{\hss\rightalign{\thinbar\kern\smallspace\thickbar}}
-% \def\repeatstopbar{\rightalign{\repeatcolon\hskip2\smallspace\thinbar\hskip\smallspace\thickbar}}
-\def\repeatstopbar{\hss\rightalign{\repeatcolon\hskip2\smallspace\thinbar\hskip\smallspace\thickbar}}
-\def\repeatstartbar{\hbox{\thickbar\kern\smallspace\thinbar\kern2\smallspace\repeatcolon}}
-\def\repeatstopstart{\hbox{\repeatcolon\kern2\smallspace\thinbar\kern\smallspace\thickbar\kern\smallspace\thickbar\kern\smallspace\thinbar\kern2\smallspace\repeatcolon}}
-\def\doublebar{\hbox{\thinbar\hskip\smallspace\thinbar}}
-
-%compatability
-\def\repeatbar{\repeatstopbar}
-\def\startrepeat{\repeatstartbar}
-\def\repeatbarstartrepeat{\repeatstopstart}
-
-\def\generalmeter#1#2{\botalign{\vbox to\balkhalf{\vss \meterfont#1}%
- \nointerlineskip
- \vbox to \balkhalf{\vss\meterfont #2}}}
-\def\defaultlineseparator{\vbox{\mussepline\vskip -5pt\mussepline}}
-\def\lineseparator{\defaultlineseparator}
-\def\beauty{%
- \par\vskip 10pt plus 30pt minus 10pt\par
- \hskip -5pt\lineseparator
- \par\vskip 10pt plus 30pt minus 10pt\par
-}
-
-\def\interstaffline{%
- \vskip 10pt
-}
-\def\ugly{\nointerlineskip\par
-\vskip 40pt\par\vbox{\leftalign{\vrule width30pt height1pt}}\par\vskip 40pt
-}
-\def\interscoreline{\beauty}
-
-
-\def\lines#1#2{%
- \vbox{\kern-\interstaffrule
- \n=0\nointerlineskip%
- \loop\ifnum\n<#1\advance\n by1%
- \kern\interstaffrule
- \hrule height \staffrulethickness width#2
- \repeat
- }}
-
-\def\toplines#1{ % why space needed here?
- \topalign{\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}}}
-\def\botlines#1{ % idem ditto
- \botalign{\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}}}
-
-%
-% a staffsymbol with #1 lines, width #2
-% bottom at baseline
-\def\linestafsym#1#2{\leftalign{\botalign{\lines{#1}{#2}}}}
-
\def\eighthflag{\topalign{\ueighthflag}}
\def\sixteenthflag{\topalign{\usixteenthflag}}
\def\thirtysecondflag{\topalign{\uthirtysecondflag}}
\def\toeheel{\vbox{\mytoe\myheel}}
%%
+\def\emptybar{}
+
+\def\thinbar{\vrule height\balkhoog}
+\def\thickbar{\vrule height\balkhoog width 2\smallspace}
+\def\maatstreep{\thinbar}
+
+%? what-s wrong with rightalign?
+\def\finishbar{\rightalign{\thinbar\kern\smallspace\thickbar}}
+
+%%% \def\finishbar{\hss\rightalign{\thinbar\kern\smallspace\thickbar}}
+% \def\repeatstopbar{\rightalign{\repeatcolon\hskip2\smallspace\thinbar\hskip\smallspace\thickbar}}
+
+\def\repeatstopbar{\hss\rightalign{\repeatcolon\hskip2\smallspace\thinbar\hskip\smallspace\thickbar}}
+\def\repeatstartbar{\hbox{\thickbar\kern\smallspace\thinbar\kern2\smallspace\repeatcolon}}
+\def\repeatstopstart{\hbox{\repeatcolon\kern2\smallspace\thinbar\kern\smallspace\thickbar\kern\smallspace\thickbar\kern\smallspace\thinbar\kern2\smallspace\repeatcolon}}
+\def\doublebar{\hbox{\thinbar\hskip\smallspace\thinbar}}
+
+%compatibility
+\def\repeatbar{\repeatstopbar}
+\def\startrepeat{\repeatstartbar}
+\def\repeatbarstartrepeat{\repeatstopstart}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% parametric symbols
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def\slurcharh#1{{\slurhfont\char#1}}
+\def\slurcharu#1{{\slurufont\char#1}}
+\def\slurchard#1{{\slurdfont\char#1}}
+\def\hslurcharh#1{{\hslurhfont\char#1}}
+\def\hslurcharu#1{{\hslurufont\char#1}}
+\def\hslurchard#1{{\hslurdfont\char#1}}
+% stacked numbers
+\def\generalmeter#1#2{\botalign{\vbox to\balkhalf{\vss \meterfont#1}%
+ \nointerlineskip
+ \vbox to \balkhalf{\vss\meterfont #2}}}
+
+% stacked horizontal lines
+\def\lines#1#2{%
+ \vbox{\kern-\interstaffrule
+ \n=0\nointerlineskip%
+ \loop\ifnum\n<#1\advance\n by1%
+ \kern\interstaffrule
+ \hrule height \staffrulethickness width#2
+ \repeat
+ }}
+
+\def\toplines#1{ % why space needed here?
+ \topalign{\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}}}
+\def\botlines#1{ % idem ditto
+ \botalign{\hbox{\kern-\notewidth\lines{#1}{\notewidthdouble}}}}
+
+%
+% a staffsymbol with #1 lines, width #2
+% bottom at baseline
+\def\linestafsym#1#2{\leftalign{\botalign{\lines{#1}{#2}}}}
+
\def\stem#1#2{\vrule height#2 depth-#1}
\def\placebox#1#2#3{%
\def\setitalic#1{\italicfont #1}
\def\setdynamic#1{\dynfont #1}
-
+% the interline symbol. Redefine to remove it.
+\def\defaultlineseparator{\vbox{\mussepline\vskip -5pt\mussepline}}
+\def\lineseparator{\defaultlineseparator}
+\def\beauty{%
+ \par\vskip 10pt plus 30pt minus 10pt\par
+ \hskip -5pt\lineseparator
+ \par\vskip 10pt plus 30pt minus 10pt\par
+}
+
+% redefine if not happy with interline spacing
+%
+\def\interstaffline{%
+ \vskip 10pt
+}
+\def\interscoreline{\beauty}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% big fat marks, if errors are detected.
\def\columnerrormark{\placebox{-5pt}{0pt}{\bf C!}}
-\def\linescoreerrormark{\placebox{0pt}{-10pt}{\bf L!}}
+\def\scorelineerrormark{\placebox{0pt}{-10pt}{\bf L!}}