From b75137963d1390716d79dab8fd593daa2d56c94f Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Thu, 15 May 1997 15:26:54 +0200 Subject: [PATCH] release: 0.0.63 --- .version | 2 +- Documentation/CodingStyle.pod | 24 +++ Documentation/faq.pod | 4 +- Documentation/gnu-music.pod | 174 ++++++++++++++++ Documentation/index.pod | 20 +- Documentation/lilygut.pod | 348 +++++++++++++++---------------- Documentation/lilyliterature.pod | 143 +++++++++++++ Documentation/lilypond.pod | 23 +- Documentation/mudela.pod | 62 ------ NEWS | 52 ++++- TODO | 45 ++-- bin/make_website | 2 +- bin/show-latest | 14 +- flower/include/fproto.hh | 2 +- flower/include/list.hh | 2 +- flower/include/parray.hh | 9 +- flower/include/pcursor.hh | 10 +- flower/include/plist.hh | 26 +-- flower/include/plist.icc | 4 +- flower/include/plist.tcc | 8 +- flower/include/varray.hh | 2 +- lib/duration-convert.cc | 13 +- lib/duration.cc | 7 + lib/includable-lexer.cc | 11 +- lib/include/duration.hh | 1 + lib/include/includable-lexer.hh | 7 +- lib/include/source.hh | 2 +- lib/input.cc | 2 +- lily/.version | 2 +- lily/include/beam.hh | 2 +- lily/include/input-music.hh | 4 +- lily/include/input-register.hh | 2 +- lily/include/input-score.hh | 2 +- lily/include/input-staff.hh | 2 +- lily/include/local-key-reg.hh | 5 +- lily/include/molecule.hh | 2 +- lily/include/p-col.hh | 4 +- lily/include/p-score.hh | 14 +- lily/include/p-staff.hh | 4 +- lily/include/pulk-voices.hh | 6 +- lily/include/register-group.hh | 2 +- lily/include/request-column.hh | 5 +- lily/include/score.hh | 6 +- lily/include/scoreline.hh | 4 +- lily/include/staff.hh | 6 +- lily/include/tex-stream.hh | 6 +- lily/include/voice-element.hh | 2 +- lily/include/voice.hh | 2 +- lily/lexer.l | 34 +++ lily/my-lily-parser.cc | 9 +- lily/parser.y | 4 +- lily/pulk-voices.cc | 2 +- lily/request-column.cc | 11 +- lily/score.cc | 1 + lily/staff.cc | 2 +- lily/staffline.cc | 26 ++- lily/template4.cc | 2 +- lily/tex-stream.cc | 20 +- make/Rules.make | 2 + make/lilypond.lsm | 6 +- make/lilypond.spec | 6 +- mi2mu/.version | 2 +- mi2mu/include/mi2mu.hh | 2 + mi2mu/include/midi-score.hh | 2 +- mi2mu/include/midi-track.hh | 26 ++- mi2mu/include/midi-voice.hh | 16 +- mi2mu/include/track-column.hh | 7 +- mi2mu/main.cc | 7 +- mi2mu/midi-lexer.l | 94 ++++++++- mi2mu/midi-track.cc | 179 ++++++++++++++-- mi2mu/midi-voice.cc | 36 +++- mi2mu/my-midi-parser.cc | 20 +- mi2mu/template.cc | 8 +- mi2mu/track-column.cc | 4 + tex/lilyponddefs.tex | 179 +++++++++------- 75 files changed, 1291 insertions(+), 517 deletions(-) create mode 100644 Documentation/gnu-music.pod create mode 100644 Documentation/lilyliterature.pod diff --git a/.version b/.version index 15ce19b5db..e94c2e0851 100644 --- a/.version +++ b/.version @@ -1,6 +1,6 @@ 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 diff --git a/Documentation/CodingStyle.pod b/Documentation/CodingStyle.pod index 4592783fb2..418575cd39 100644 --- a/Documentation/CodingStyle.pod +++ b/Documentation/CodingStyle.pod @@ -45,6 +45,19 @@ extension ".cc". 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 @@ -59,6 +72,7 @@ in emacs: '(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) @@ -398,3 +412,13 @@ Variable bar: an C that you must not delete =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. + + diff --git a/Documentation/faq.pod b/Documentation/faq.pod index d632d7e79e..e6ade53053 100644 --- a/Documentation/faq.pod +++ b/Documentation/faq.pod @@ -109,9 +109,9 @@ to associate one Request with one Item or Spanner. =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? diff --git a/Documentation/gnu-music.pod b/Documentation/gnu-music.pod new file mode 100644 index 0000000000..33a3aee7b3 --- /dev/null +++ b/Documentation/gnu-music.pod @@ -0,0 +1,174 @@ +=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 + diff --git a/Documentation/index.pod b/Documentation/index.pod index 12a1e83139..4dd3193944 100644 --- a/Documentation/index.pod +++ b/Documentation/index.pod @@ -56,6 +56,20 @@ internal structures. +=item * + +resources on music typesetting + + +=item * + +manual page for mi2mu, the MIDI convertor. + + =item * @@ -138,12 +152,6 @@ The DOC++ documentation of the C++ sources. =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 diff --git a/Documentation/lilygut.pod b/Documentation/lilygut.pod index 7dc7ab6761..9bd3013c12 100644 --- a/Documentation/lilygut.pod +++ b/Documentation/lilygut.pod @@ -10,43 +10,168 @@ some are large comments taken away from the headers You should use doc++ to take a peek at the sources. -[have to do more doco; see TODO] +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 } + +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 which contains the +C. The staff decides whether to to honor the request, +ignore it, or merge it with other requests. Merging of requests is +preferably done with other requests done by members of the same +voicegroups (beams, brackets, stems) + +The result of a request will be an C or a C, which +will be put on a C. Note that the C and the original +C need not have anything in common. For example, the +``double'' piano Staff could interpret commands which juggle +melodies across the left and right hand, and may put the result in +two five-line PStaffs (maybe with extra PStaffs to carry the dynamic +signs and any lyric. + +The class C should be thought as a container for the +Cs, and an interpreter for Cs. +Different staffs can produce different outputs; a melodious voice +which is put into a percussion-Staff, will be typeset as the rythm of +that voice. + +After C made up her mind, the resultant items and +spanners are put on the PScore. + Some of the important requests are: =over 4 @@ -91,32 +216,19 @@ Dynamic changes can occur in a smaller time than the length of its note, therefore fore each C request carries a time, measured from the start of its note. -=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 or a C, which -will be put on a C. Note that the C and the original -C need not have anything in common. For example, the -``double'' piano Staff could interpret commands which juggle -melodies across the left and right hand, and may put the result in -two five-line PStaffs (maybe with extra PStaffs to carry the dynamic -signs and any lyric. +=head2 Voice -The class C should be thought as a container for the -Cs, and an interpreter for Cs. -Different staffs can produce different outputs; a melodious voice -which is put into a percussion-Staff, will be typeset as the rythm of -that voice. +Voice is a list of Voice_elements together with a starting time. -After C 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 @@ -168,6 +280,8 @@ created. To decide on merging, C has grouped several registers. There are a few groups: +=over 4 + =item * Staff wide, contains @@ -193,15 +307,26 @@ Voice, 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, F] +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? @@ -226,16 +351,10 @@ 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 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 @@ -298,139 +417,8 @@ uses the concept of pre- and post-breaks. minimum distance to other columns, to prevent symbols from running into symbols of other columns.) -=head1 SEE ALSO - -=head2 References - -[partly by Mark Basinski ] - -Herbert Chlapik, 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 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 - -... 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 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. diff --git a/Documentation/lilyliterature.pod b/Documentation/lilyliterature.pod new file mode 100644 index 0000000000..5ca92764bb --- /dev/null +++ b/Documentation/lilyliterature.pod @@ -0,0 +1,143 @@ +=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 ] + +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 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 + +... 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 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. + + + diff --git a/Documentation/lilypond.pod b/Documentation/lilypond.pod index bd8da80a06..dcbaab0d00 100644 --- a/Documentation/lilypond.pod +++ b/Documentation/lilypond.pod @@ -20,7 +20,6 @@ Typesetting music is a complex task, whereas the message that printed music conveys is usually a simple one. GNU LilyPond is a try at providing a simple interface for setting music. - =head1 OPTIONS =over 5 @@ -93,9 +92,9 @@ multiple stafftypes (melodic, rhythmic) [broken from pl28 on] =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 * @@ -244,7 +243,7 @@ B an (one) additional directory for finding lilypond data. =over 4 -=item lilygut(?) +=item lilygut On technical details of LilyPond @@ -260,9 +259,7 @@ Goals of the GNU LilyPond project. 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, @@ -337,8 +334,8 @@ After long and hard thinking, I came up with an algorithm for the 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). diff --git a/Documentation/mudela.pod b/Documentation/mudela.pod index 5908a64610..29c37bcc11 100644 --- a/Documentation/mudela.pod +++ b/Documentation/mudela.pod @@ -525,68 +525,6 @@ In concrete, a piece of Mudela has the following structure: 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 } - -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 which contains the -C. The staff decides whether to to honor the request, -ignore it, or merge it with other requests. Merging of requests is -preferably done with other requests done by members of the same -voicegroups (beams, brackets, stems) - =head2 Staff The staff is a simple container (containing Voices). The so-called diff --git a/NEWS b/NEWS index aafcdc5d14..f2495c5234 100644 --- a/NEWS +++ b/NEWS @@ -1,17 +1,47 @@ -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 @@ -56,7 +86,7 @@ pl 59 ****** may 2 -pl 58.jnc1 +pl 58.jcn1 - bf: toccata-fuga-E.ly pl 57.jcn4 @@ -93,7 +123,7 @@ pl 57 - 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 @@ -116,7 +146,7 @@ pl 56 - 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 diff --git a/TODO b/TODO index 75162b7604..2a42edee5a 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,5 @@ +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 @@ -13,17 +15,12 @@ IMPORTANT * 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 @@ -56,6 +53,7 @@ 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 @@ -68,6 +66,13 @@ PROJECTS - 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? @@ -77,8 +82,6 @@ HKN buglist: \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 @@ -105,8 +108,12 @@ gedrukt. 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 @@ -175,31 +182,34 @@ SMALLISH PROJECTS * 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 @@ -228,20 +238,20 @@ SMALLISH PROJECTS * 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. @@ -296,9 +306,6 @@ IDEAS * 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 @@ -306,7 +313,7 @@ IDEAS * 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 diff --git a/bin/make_website b/bin/make_website index 0f9ad202fc..c9fc73dfb4 100755 --- a/bin/make_website +++ b/bin/make_website @@ -1,9 +1,9 @@ #!/usr/bin/perl -w -# TODO check ret status of various stuff use FileHandle; +# do something, check return status sub my_system { my (@cmds) = @_; diff --git a/bin/show-latest b/bin/show-latest index 7aacb57ff6..066a26fe3b 100755 --- a/bin/show-latest +++ b/bin/show-latest @@ -1,6 +1,10 @@ #!/usr/bin/perl + + $reldir="~/musix/releases"; +use FileHandle; + sub cmpver { @@ -26,8 +30,14 @@ while () { @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 = ; +chop ($desc); +close NEWS; + print $desc; diff --git a/flower/include/fproto.hh b/flower/include/fproto.hh index ef4c6422b2..d5bf68034b 100644 --- a/flower/include/fproto.hh +++ b/flower/include/fproto.hh @@ -21,8 +21,8 @@ template struct Array; template struct sstack; template struct Assoc; template struct List; +template struct Link_list; template struct Pointer_list; -template struct IPointer_list; template struct Cursor; template struct PCursor; template struct Link; diff --git a/flower/include/list.hh b/flower/include/list.hh index cdf57ced99..343ccffcbc 100644 --- a/flower/include/list.hh +++ b/flower/include/list.hh @@ -15,7 +15,7 @@ template class Link; items are always stored as copies in List, but: #List# : copies of #String# stored #List# : copies of #String*# stored! - (do not use, use \Ref{Pointer_list} ## instead.) + (do not use, use \Ref{Link_list} ## instead.) {\bf note:} retrieving "invalid" cursors, i.e. diff --git a/flower/include/parray.hh b/flower/include/parray.hh index ed12074055..e003d46223 100644 --- a/flower/include/parray.hh +++ b/flower/include/parray.hh @@ -12,8 +12,14 @@ #include "varray.hh" +/** + an array of pointers. + + TODO + should init to 0. + */ template -class Pointer_array : public Array +class Link_array : public Array { public: int find_i (T t) const{ @@ -31,4 +37,5 @@ public: return 0; } }; + #endif // PARRAY_HH diff --git a/flower/include/pcursor.hh b/flower/include/pcursor.hh index dffe02b9ef..6144152614 100644 --- a/flower/include/pcursor.hh +++ b/flower/include/pcursor.hh @@ -10,14 +10,14 @@ #include "plist.hh" #include "cursor.hh" -/** cursor to go with Pointer_list. - don't create Pointer_list's. +/** cursor to go with Link_list. + don't create Link_list's. This cursor is just an interface class for Cursor. It takes care of the appropriate type casts */ template class PCursor : private Cursor { - friend class IPointer_list; + friend class Pointer_list; /// delete contents void junk(); @@ -36,14 +36,14 @@ public: return remove_p(); } - Pointer_list &list() { return (Pointer_list&)Cursor::list(); } + Link_list &list() { return (Link_list&)Cursor::list(); } PCursor operator++(int) { return Cursor::operator++(0);} PCursor operator--(int) { return Cursor::operator--(0); } PCursor operator+=(int i) { return Cursor::operator+=(i);} PCursor operator-=(int i) { return Cursor::operator-=(i); } PCursor operator -(int no) const { return Cursor::operator-(no);} int operator -(PCursor op) const { return Cursor::operator-(op);} - PCursor operator +( int no) const {return Cursor::operator+(no);} PCursor(const Pointer_list & l) : Cursor (l) {} + PCursor operator +( int no) const {return Cursor::operator+(no);} PCursor(const Link_list & l) : Cursor (l) {} PCursor() : Cursor () {} PCursor( const Cursor& cursor ) : Cursor(cursor) { } void* vptr() const { return *((Cursor &) *this); } diff --git a/flower/include/plist.hh b/flower/include/plist.hh index afbf942c73..469a8d444a 100644 --- a/flower/include/plist.hh +++ b/flower/include/plist.hh @@ -12,14 +12,14 @@ /** A list of pointers. - Use for list of pointers, e.g. Pointer_list. + Use for list of pointers, e.g. Link_list. This class does no deletion of the pointers, but it knows how to copy itself (shallow copy). We could have derived it from List, - 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 is instantiated. */ template -class Pointer_list : public List +class Link_list : public List { public: PCursor top() const{ @@ -29,11 +29,11 @@ class Pointer_list : public List return PCursor (List::bottom()); } PCursor find(T) const; - void concatenate(Pointer_list const &s) { List::concatenate(s); } - Pointer_list() {} + void concatenate(Link_list const &s) { List::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: @@ -41,25 +41,25 @@ class Pointer_list : public List 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 IPointer_list : public Pointer_list { +class Pointer_list : public Link_list { 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 _pc_(from); _pc_.ok(); _pc_++)\ to.bottom().add(_pc_->op)\ \ template -void PL_copy(IPointer_list &dst,IPointer_list const&src); +void PL_copy(Pointer_list &dst,Pointer_list const&src); diff --git a/flower/include/plist.icc b/flower/include/plist.icc index f24e0ddf45..80ce1ba198 100644 --- a/flower/include/plist.icc +++ b/flower/include/plist.icc @@ -1,7 +1,7 @@ /* -*-c++-*- plist.icc -- part of flowerlib - (c) 1996 Han-Wen Nienhuys& Jan Nieuwenhuizen + (c) 1996,1997 Han-Wen Nienhuys& Jan Nieuwenhuizen */ #ifndef PLIST_INL @@ -9,7 +9,7 @@ template void -PL_copy(IPointer_list &to, IPointer_list const&src) +PL_copy(Pointer_list &to, Pointer_list const&src) { for (PCursor pc(src); pc.ok(); pc++) { T *q = pc; diff --git a/flower/include/plist.tcc b/flower/include/plist.tcc index 7129cdbe3d..2f75d08adf 100644 --- a/flower/include/plist.tcc +++ b/flower/include/plist.tcc @@ -1,12 +1,12 @@ #include "plist.hh" -#define PL_instantiate(a) template class Pointer_list; \ +#define PL_instantiate(a) template class Link_list; \ template class PCursor; #define IPL_instantiate(a) PL_instantiate(a); \ - template class IPointer_list + template class Pointer_list template -IPointer_list::~IPointer_list() +Pointer_list::~Pointer_list() { PCursor c( *this ); while (c.ok()) { @@ -16,7 +16,7 @@ IPointer_list::~IPointer_list() template PCursor -Pointer_list::find(T what ) const +Link_list::find(T what ) const { PCursor i(*this); for (; i.ok(); i++) diff --git a/flower/include/varray.hh b/flower/include/varray.hh index 4f67d3aac4..105d96ac27 100644 --- a/flower/include/varray.hh +++ b/flower/include/varray.hh @@ -148,7 +148,7 @@ public: (*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); diff --git a/lib/duration-convert.cc b/lib/duration-convert.cc index 882d275b3c..1b738507af 100644 --- a/lib/duration-convert.cc +++ b/lib/duration-convert.cc @@ -93,8 +93,8 @@ Duration_convert::mom2_dur( Moment mom ) 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 ); @@ -121,7 +121,10 @@ Duration_convert::mom2standardised_dur( Moment mom ) 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 ); @@ -192,10 +195,6 @@ Duration_convert::ticks2standardised_dur( int ticks_i ) { 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; } diff --git a/lib/duration.cc b/lib/duration.cc index 64902fa73c..8c08c12802 100644 --- a/lib/duration.cc +++ b/lib/duration.cc @@ -58,6 +58,13 @@ Duration::set_plet(int i, int t) 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 ) { diff --git a/lib/includable-lexer.cc b/lib/includable-lexer.cc index 2f8d33f461..61f1c1b613 100644 --- a/lib/includable-lexer.cc +++ b/lib/includable-lexer.cc @@ -21,9 +21,11 @@ Includable_lexer::new_input(String s, Sources * global_sources) { 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); @@ -79,5 +81,8 @@ Includable_lexer::add_lexed_char(int count) Source_file* Includable_lexer::source_file_l()const { - return include_stack_.top(); + if (include_stack_.empty()) + return 0; + else + return include_stack_.top(); } diff --git a/lib/include/duration.hh b/lib/include/duration.hh index c07dcefc60..c8554f343a 100644 --- a/lib/include/duration.hh +++ b/lib/include/duration.hh @@ -44,6 +44,7 @@ struct Duration { 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 diff --git a/lib/include/includable-lexer.hh b/lib/include/includable-lexer.hh index a5416ef45a..a84f736c48 100644 --- a/lib/include/includable-lexer.hh +++ b/lib/include/includable-lexer.hh @@ -1,5 +1,5 @@ /* - includable-lexer.hh -- declare + includable-lexer.hh -- declare Includable_lexer source file of the LilyPond music typesetter @@ -9,8 +9,10 @@ #ifndef INCLUDABLE_LEXER_HH #define INCLUDABLE_LEXER_HH -#include "string.hh" + #include + +#include "string.hh" #include "varray.hh" #include "fproto.hh" #include "proto.hh" @@ -28,6 +30,7 @@ protected: Array include_stack_; Array char_count_stack_; public: + Source_file* source_file_l()const; void new_input(String s,Sources*); Includable_lexer(); diff --git a/lib/include/source.hh b/lib/include/source.hh index 58ac1e7ae4..99e15e56f5 100644 --- a/lib/include/source.hh +++ b/lib/include/source.hh @@ -19,7 +19,7 @@ public: private: const File_path * path_C_; void add( Source_file* sourcefile_p ); - IPointer_list sourcefile_p_iplist_; + Pointer_list sourcefile_p_iplist_; bool binary_b_ ; }; diff --git a/lib/input.cc b/lib/input.cc index 7df11bf2bb..8478810052 100644 --- a/lib/input.cc +++ b/lib/input.cc @@ -41,7 +41,7 @@ Input::message(String message_str)const 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; diff --git a/lily/.version b/lily/.version index 2438befc54..e929572e51 100644 --- a/lily/.version +++ b/lily/.version @@ -1,6 +1,6 @@ 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 diff --git a/lily/include/beam.hh b/lily/include/beam.hh index f1ac0c1eaa..a898628d35 100644 --- a/lily/include/beam.hh +++ b/lily/include/beam.hh @@ -14,7 +14,7 @@ make sure that they reach the beam and that point in the correct direction */ struct Beam: public Directional_spanner { - Pointer_list stems; + Link_list stems; /// the slope of the beam in posns / point (dimension) Real slope; diff --git a/lily/include/input-music.hh b/lily/include/input-music.hh index b34fedc183..df490367b4 100644 --- a/lily/include/input-music.hh +++ b/lily/include/input-music.hh @@ -12,7 +12,7 @@ #include "voice.hh" #include "moment.hh" -struct Voice_list : public Pointer_list { +struct Voice_list : public Link_list { void translate_time(Moment dt); }; @@ -67,7 +67,7 @@ struct Simple_music : Input_music { /// Complex_music consists of multiple voices struct Complex_music : Input_music { - IPointer_list elts; + Pointer_list elts; /* *************** */ virtual void transpose(Melodic_req const&) const ; virtual void set_default_group(String g); diff --git a/lily/include/input-register.hh b/lily/include/input-register.hh index bf945ab100..2ba2c8c2e3 100644 --- a/lily/include/input-register.hh +++ b/lily/include/input-register.hh @@ -16,7 +16,7 @@ #include "input.hh" struct Input_register : Input { - IPointer_list ireg_list_; + Pointer_list ireg_list_; String name_str_; void add(Input_register*); diff --git a/lily/include/input-score.hh b/lily/include/input-score.hh index 6e6a3ceaaf..da3db47208 100644 --- a/lily/include/input-score.hh +++ b/lily/include/input-score.hh @@ -24,7 +24,7 @@ public: /// paper_, staffs_ and commands_ form the problem definition. Paper_def *paper_p_; Midi_def* midi_p_; - IPointer_list staffs_; + Pointer_list staffs_; /* *************************************************************** */ diff --git a/lily/include/input-staff.hh b/lily/include/input-staff.hh index 0bbdc13266..edc2991924 100644 --- a/lily/include/input-staff.hh +++ b/lily/include/input-staff.hh @@ -16,7 +16,7 @@ class Input_staff:public Input { public: - IPointer_list music_; + Pointer_list music_; Input_register * ireg_p_; /* *************** */ diff --git a/lily/include/local-key-reg.hh b/lily/include/local-key-reg.hh index 4921bd03aa..19e11b9d4e 100644 --- a/lily/include/local-key-reg.hh +++ b/lily/include/local-key-reg.hh @@ -7,6 +7,7 @@ #ifndef LOCALKEYREG_HH #define LOCALKEYREG_HH + #include "register.hh" #include "key.hh" #include "parray.hh" @@ -16,8 +17,8 @@ struct Local_key_register : Request_register { Key const *key_C_; Array mel_l_arr_; Array support_l_arr_; - Pointer_array forced_l_arr_; - Pointer_array tied_l_arr_; + Link_array forced_l_arr_; + Link_array tied_l_arr_; /* *************** */ virtual void process_requests(); virtual void acknowledge_element(Staff_elem_info); diff --git a/lily/include/molecule.hh b/lily/include/molecule.hh index 312111bff2..3904acb4bf 100644 --- a/lily/include/molecule.hh +++ b/lily/include/molecule.hh @@ -30,7 +30,7 @@ struct Atom { /** a group of individually translated symbols. You can add molecules to the top, to the right, etc. */ struct Molecule { - IPointer_list ats; // change to List? + Pointer_list ats; // change to List? /* *************** */ diff --git a/lily/include/p-col.hh b/lily/include/p-col.hh index 4a4264a006..71b5887c98 100644 --- a/lily/include/p-col.hh +++ b/lily/include/p-col.hh @@ -22,8 +22,8 @@ class PCol { public: - Pointer_list its; - Pointer_list stoppers, starters; + Link_list its; + Link_list stoppers, starters; /** prebreak is put before end of line. if broken here, then (*this) column is discarded, and prebreak diff --git a/lily/include/p-score.hh b/lily/include/p-score.hh index 15c123fdb6..33e066c3c7 100644 --- a/lily/include/p-score.hh +++ b/lily/include/p-score.hh @@ -25,25 +25,25 @@ struct PScore { Paper_def *paper_l_; /// the columns, ordered left to right - IPointer_list cols; + Pointer_list cols; /// the idealspacings, no particular order - IPointer_list suz; + Pointer_list suz; /// the staffs ordered top to bottom - IPointer_list staffs; + Pointer_list staffs; /// all symbols in score. No particular order. - IPointer_list its; + Pointer_list its; /// if broken, the different lines - IPointer_list lines; + Pointer_list lines; /// crescs etc; no particular order - IPointer_list spanners; + Pointer_list spanners; /// broken spanners - IPointer_list broken_spans; + Pointer_list broken_spans; /* *************** */ /* CONSTRUCTION */ diff --git a/lily/include/p-staff.hh b/lily/include/p-staff.hh index a1c5fb4daa..c4236c874e 100644 --- a/lily/include/p-staff.hh +++ b/lily/include/p-staff.hh @@ -11,8 +11,8 @@ struct PStaff { PScore * pscore_l_; - Pointer_list spans; - Pointer_list its; + Link_list spans; + Link_list its; /* *************** */ void add(Item*i); diff --git a/lily/include/pulk-voices.hh b/lily/include/pulk-voices.hh index e871517388..e6f9be9c11 100644 --- a/lily/include/pulk-voices.hh +++ b/lily/include/pulk-voices.hh @@ -34,15 +34,15 @@ int compare(Voice_l const &p1, Voice_l const &p2); class Pulk_voices { PQueue< Voice_l > voice_pq_; - IPointer_list< Pulk_voice * > pulk_p_list_; - Pointer_list staff_l_list_; + Pointer_list< Pulk_voice * > pulk_p_list_; + Link_list staff_l_list_; Moment next_mom_; public: Moment last_; bool ok() const; Moment next_mom() { return next_mom_; } - Pulk_voices(Pointer_list const&); + Pulk_voices(Link_list const&); void get_aligned_request(Request_column *col_l ); }; diff --git a/lily/include/register-group.hh b/lily/include/register-group.hh index be21d7fd5e..2156dbec80 100644 --- a/lily/include/register-group.hh +++ b/lily/include/register-group.hh @@ -21,7 +21,7 @@ */ class Register_group_register : public Request_register { protected: - IPointer_list reg_list_; + Pointer_list reg_list_; virtual void do_print()const; public: diff --git a/lily/include/request-column.hh b/lily/include/request-column.hh index e3d5d3184e..ad198f3f04 100644 --- a/lily/include/request-column.hh +++ b/lily/include/request-column.hh @@ -18,12 +18,13 @@ */ class Request_column { - IPointer_list staff_cols_; + Pointer_list staff_cols_; Array staff_col_l_arr_; + Moment when_; public: Score_column *musical_column_l_, *command_column_l_; - Request_column(Pointer_list const& ); + Request_column(Link_list const& ); bool used_b()const; Moment when(); void add_reqs(int staff_idx, Array const&); diff --git a/lily/include/score.hh b/lily/include/score.hh index 7376e97976..da38be4b41 100644 --- a/lily/include/score.hh +++ b/lily/include/score.hh @@ -24,12 +24,12 @@ struct Score { /// paper_, staffs_ and commands_ form the problem definition. Paper_def *paper_p_; Midi_def *midi_p_; - IPointer_list staffs_; + Pointer_list staffs_; /// "runtime" fields for setting up spacing - IPointer_list rcols_; + Pointer_list rcols_; - IPointer_list cols_; + Pointer_list cols_; PScore *pscore_p_; Input input_; diff --git a/lily/include/scoreline.hh b/lily/include/scoreline.hh index 814cb7e8c2..15c10f31cf 100644 --- a/lily/include/scoreline.hh +++ b/lily/include/scoreline.hh @@ -13,11 +13,11 @@ /// the columns of a score that form one line. struct Line_of_score { - Pointer_list cols; + Link_list cols; bool error_mark_b_; // need to store height of each staff. - IPointer_list staffs; + Pointer_list staffs; PScore * pscore_l_; // needed to generate staffs /* *************** */ diff --git a/lily/include/staff.hh b/lily/include/staff.hh index 29f6839f73..7811f76c0e 100644 --- a/lily/include/staff.hh +++ b/lily/include/staff.hh @@ -20,9 +20,9 @@ class Staff { public: Input_register * ireg_p_; - Pointer_list voice_list_; + Link_list voice_list_; /// runtime field - Pointer_list cols_; + Link_list cols_; Score *score_l_; PScore *pscore_l_; @@ -30,7 +30,7 @@ public: /* *************************************************************** */ - void add(const Pointer_list &s); + void add(const Link_list &s); void add_voice(Voice *v_p); Paper_def*paper()const; diff --git a/lily/include/tex-stream.hh b/lily/include/tex-stream.hh index 4d5805c556..5f0477a51a 100644 --- a/lily/include/tex-stream.hh +++ b/lily/include/tex-stream.hh @@ -10,10 +10,14 @@ 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); diff --git a/lily/include/voice-element.hh b/lily/include/voice-element.hh index fc85b58e3b..75210c21d0 100644 --- a/lily/include/voice-element.hh +++ b/lily/include/voice-element.hh @@ -24,7 +24,7 @@ public: Voice_element */ Moment duration_; Voice const *voice_C_; - IPointer_list req_p_list_; + Pointer_list req_p_list_; Request * principal_req_l_; /* *************** */ diff --git a/lily/include/voice.hh b/lily/include/voice.hh index 475fc44668..a0aeddf796 100644 --- a/lily/include/voice.hh +++ b/lily/include/voice.hh @@ -18,7 +18,7 @@ struct Voice { /** the elements, earliest first. Please use the member #add()# to add a new element */ - IPointer_list elts_; + Pointer_list elts_; Moment start_; /* *************** */ diff --git a/lily/lexer.l b/lily/lexer.l index 38adcc5fd9..39250c95c4 100644 --- a/lily/lexer.l +++ b/lily/lexer.l @@ -8,6 +8,19 @@ */ +/* + backup rules + + after making a change to the lexer rules, run + flex -b + 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 #include "string.hh" @@ -76,8 +89,12 @@ LYRICS ({AA}|{NATIONAL})[^0-9 \t\n\f]* } %[^{\n].*\n { } + %[^{\n] { // backup rule + } %\n { } + %[^{\n].* { + } {WHITE}+ { } @@ -105,6 +122,10 @@ LYRICS ({AA}|{NATIONAL})[^0-9 \t\n\f]* new_input(s,source_l_g); yy_pop_state(); } +\"[^"]* { // backup rule + cerr << "missing end quote" << endl; + exit( 1 ); +} {RESTNAME} { const char *s = YYText(); yylval.string = new String (s); @@ -121,6 +142,14 @@ LYRICS ({AA}|{NATIONAL})[^0-9 \t\n\f]* s=s.left_str(s.length_i() - 1); return scan_bare_word(s); } +\\\${BLACK}* { // backup rule + cerr << "white expected" << endl; + exit( 1 ); +} +\${BLACK}* { // backup rule + cerr << "white expected" << endl; + exit( 1 ); +} { {ALPHAWORD}/\' { post_quotes_b_ = true; @@ -238,6 +267,11 @@ LYRICS ({AA}|{NATIONAL})[^0-9 \t\n\f]* return REAL; } +{INT}\. { // backup rule + cerr << "int. encountered" << endl; + exit( 1 ); +} + [{}] { mtor << "parens\n"; diff --git a/lily/my-lily-parser.cc b/lily/my-lily-parser.cc index 5d46c7d5b3..5389803e63 100644 --- a/lily/my-lily-parser.cc +++ b/lily/my-lily-parser.cc @@ -36,6 +36,7 @@ My_lily_parser::set_debug() lexer_p_->set_debug( !monitor->silence(s+"Lexer") && check_debug); #endif } + void My_lily_parser::print_declarations() { @@ -60,11 +61,17 @@ My_lily_parser::do_init_file() 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(); diff --git a/lily/parser.y b/lily/parser.y index d92c970123..0eb8d01968 100644 --- a/lily/parser.y +++ b/lily/parser.y @@ -969,8 +969,10 @@ explicit_duration: $$ = 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; diff --git a/lily/pulk-voices.cc b/lily/pulk-voices.cc index dc3c26604e..f2c26cbe25 100644 --- a/lily/pulk-voices.cc +++ b/lily/pulk-voices.cc @@ -13,7 +13,7 @@ #include "request-column.hh" #include "debug.hh" -Pulk_voices::Pulk_voices(Pointer_list const& l) +Pulk_voices::Pulk_voices(Link_list const& l) : staff_l_list_(l) { int staff_i = 0; diff --git a/lily/request-column.cc b/lily/request-column.cc index 47013d222a..9b896cf8f3 100644 --- a/lily/request-column.cc +++ b/lily/request-column.cc @@ -13,8 +13,11 @@ 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 @@ -23,7 +26,7 @@ Request_column::add_reqs(int idx , Array const & req_l_arr) staff_col_l_arr_[idx]->add_reqs(req_l_arr); } -Request_column::Request_column(Pointer_list const& list ) +Request_column::Request_column(Link_list const& list ) { musical_column_l_ = command_column_l_ =0; iter(list.top(), j); @@ -34,7 +37,9 @@ Request_column::Request_column(Pointer_list const& list ) 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) { diff --git a/lily/score.cc b/lily/score.cc index 7441d5c790..8ec3049f48 100644 --- a/lily/score.cc +++ b/lily/score.cc @@ -114,6 +114,7 @@ Score::clean_cols() 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; } diff --git a/lily/staff.cc b/lily/staff.cc index a3f71b0be7..c601837147 100644 --- a/lily/staff.cc +++ b/lily/staff.cc @@ -19,7 +19,7 @@ void -Staff::add(Pointer_list const &l) +Staff::add(Link_list const &l) { for (iter_top(l,i); i.ok(); i++) voice_list_.bottom().add(i); diff --git a/lily/staffline.cc b/lily/staffline.cc index c5e17bc7fc..c4d4861b8c 100644 --- a/lily/staffline.cc +++ b/lily/staffline.cc @@ -33,26 +33,34 @@ Line_of_staff::TeXstring() const 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}"; diff --git a/lily/template4.cc b/lily/template4.cc index 399b9ed384..8be96a30f4 100644 --- a/lily/template4.cc +++ b/lily/template4.cc @@ -1,5 +1,5 @@ /* - template4.cc -- instantiate Pointer_list baseclass. + template4.cc -- instantiate Link_list baseclass. source file of the LilyPond music typesetter diff --git a/lily/tex-stream.cc b/lily/tex-stream.cc index 5e2e959181..dfa56b1b4d 100644 --- a/lily/tex-stream.cc +++ b/lily/tex-stream.cc @@ -14,12 +14,15 @@ #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(); } @@ -51,6 +54,7 @@ Tex_stream::operator<<(String s) } continue; } + line_len_i_ ++; switch(*cp) { case '%': @@ -72,9 +76,14 @@ Tex_stream::operator<<(String s) /* 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; @@ -83,5 +92,12 @@ Tex_stream::operator<<(String s) return *this; } +void +Tex_stream::break_line() +{ + *os << "%\n"; + *os << String(' ', nest_level); + line_len_i_ = 0; +} /* *************************************************************** */ diff --git a/make/Rules.make b/make/Rules.make index 2f6d769044..36986881e5 100644 --- a/make/Rules.make +++ b/make/Rules.make @@ -37,6 +37,8 @@ $(outdir)/%.hh: %.y $(outdir)/%.cc: %.l $(FLEX) -Cfe -p -p -t $< > $@ +# could be faster: +# $(FLEX) -8 -Cf -t $< > $@ $(outdir)/%.text: $(outdir)/%.1 groff -man -Tascii $< > $@ diff --git a/make/lilypond.lsm b/make/lilypond.lsm index ad7b4d70e2..f3dea72647 100644 --- a/make/lilypond.lsm +++ b/make/lilypond.lsm @@ -2,8 +2,8 @@ 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 @@ -13,7 +13,7 @@ Author: hanwen@stack.nl (Han-Wen Nienhuys) 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++ diff --git a/make/lilypond.spec b/make/lilypond.spec index 0d27a4884c..fef4517805 100644 --- a/make/lilypond.spec +++ b/make/lilypond.spec @@ -1,9 +1,9 @@ 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 @@ -27,7 +27,7 @@ rm -rf $RPM_BUILD_ROOT 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 diff --git a/mi2mu/.version b/mi2mu/.version index af965a51c4..4e05deeab5 100644 --- a/mi2mu/.version +++ b/mi2mu/.version @@ -1,6 +1,6 @@ MAJOR_VERSION = 0 MINOR_VERSION = 0 -PATCH_LEVEL = 15 +PATCH_LEVEL = 16 # use to send patches, always empty for released version: MY_PATCH_LEVEL = # diff --git a/mi2mu/include/mi2mu.hh b/mi2mu/include/mi2mu.hh index 9d9bf8ecc0..5d381cedd0 100644 --- a/mi2mu/include/mi2mu.hh +++ b/mi2mu/include/mi2mu.hh @@ -26,6 +26,8 @@ #undef mtor #endif +#define MVOICE_LIST + #include "string.hh" #include "string-convert.hh" diff --git a/mi2mu/include/midi-score.hh b/mi2mu/include/midi-score.hh index 8c9d38bca7..990d4031ef 100644 --- a/mi2mu/include/midi-score.hh +++ b/mi2mu/include/midi-score.hh @@ -18,7 +18,7 @@ public: void process(); private: - IPointer_list midi_track_p_list_; + Pointer_list midi_track_p_list_; int format_i_; int tracks_i_; int tempo_i_; diff --git a/mi2mu/include/midi-track.hh b/mi2mu/include/midi-track.hh index 5e3394da35..61022327c3 100644 --- a/mi2mu/include/midi-track.hh +++ b/mi2mu/include/midi-track.hh @@ -31,17 +31,35 @@ public: int number_i_; private: - void add_begin_at( Pointer_list& open_voices_r, Moment mom ); +#ifdef MVOICE_LIST + void add_begin_at( Link_list& open_voices_r, Moment mom ); +#else + void add_begin_at( Array& 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& open_voices_r, Moment mom ); +#ifdef MVOICE_LIST + void remove_end_at( Link_list& open_voices_r, Moment mom ); +#else + void remove_end_at( Array& 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 tcol_p_list_; - IPointer_list midi_voice_p_list_; +#ifdef TCOL_LIST +#warning using track_column list + Pointer_list tcol_p_list_; +#else + Array tcol_p_array_; +#endif +#ifdef MVOICE_LIST +#warning using midi_voice list + Pointer_list midi_voice_p_list_; +#else + Array midi_voice_p_array_; +#endif }; #endif // MIDI_TRACK_HH diff --git a/mi2mu/include/midi-voice.hh b/mi2mu/include/midi-voice.hh index 6cadebfccb..8360af08e4 100644 --- a/mi2mu/include/midi-voice.hh +++ b/mi2mu/include/midi-voice.hh @@ -15,14 +15,18 @@ public: 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_p_list_; + int events_i_; + Moment end_mom_; + Moment begin_mom_; +#ifdef MEVENT_LIST +#error using list + Pointer_list midi_event_p_list_; +#else + Array midi_event_p_array_; +#endif }; #endif // MIDI_VOICE_HH diff --git a/mi2mu/include/track-column.hh b/mi2mu/include/track-column.hh index c1126437e6..6c0630883b 100644 --- a/mi2mu/include/track-column.hh +++ b/mi2mu/include/track-column.hh @@ -15,7 +15,12 @@ public: Moment mom(); //private: - IPointer_list midi_event_p_list_; +#ifdef MEVENT_LIST +#error using list + Pointer_list midi_event_p_list_; +#else + Array midi_event_p_array_; +#endif Moment mom_; }; diff --git a/mi2mu/main.cc b/mi2mu/main.cc index 06589c7891..200c96a606 100644 --- a/mi2mu/main.cc +++ b/mi2mu/main.cc @@ -90,7 +90,6 @@ main( int argc_i, char* argv_sz_a[] ) 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() ) @@ -102,6 +101,7 @@ main( int argc_i, char* argv_sz_a[] ) level_ver = DEBUG_ver; break; case 'h': + identify(); usage(); exit( 0 ); break; @@ -125,6 +125,7 @@ main( int argc_i, char* argv_sz_a[] ) case 's': { int i = String_convert::dec2_i( getopt_long.optarg ); if ( !i ) { + identify(); usage(); exit( 2 ); //usage } @@ -135,6 +136,7 @@ main( int argc_i, char* argv_sz_a[] ) level_ver = VERBOSE_ver; break; case 'w': + identify(); notice(); exit( 0 ); break; @@ -146,6 +148,9 @@ main( int argc_i, char* argv_sz_a[] ) 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 ); diff --git a/mi2mu/midi-lexer.l b/mi2mu/midi-lexer.l index 691955d574..1bc41ded0a 100644 --- a/mi2mu/midi-lexer.l +++ b/mi2mu/midi-lexer.l @@ -1,6 +1,17 @@ %{//-*-Fundamental-*- // midi-lexer.l +/* + backup rules + + after making a change to the lexer rules, run + flex -b + 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" @@ -27,13 +38,23 @@ 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] @@ -70,7 +91,7 @@ SSME [\0x7f][\x03] %% -{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 ); @@ -79,17 +100,32 @@ SSME [\0x7f][\x03] 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} { // really signed? tor( DEBUG_ver ) << "lex: int32" << endl; assert( YYLeng() == 4 ); @@ -98,14 +134,34 @@ SSME [\0x7f][\x03] yy_pop_state(); return INT32; } +{BACKUP_INT32_0} { + error( String( "int32: int32 expected: " ) + + String_convert::bin2hex_str( String( *( YYText() ) ) ) ); + exit( 1 ); +} +{BACKUP_INT32_1} { + error( String( "int32: int32 expected: " ) + + String_convert::bin2hex_str( String( *( YYText() ) ) ) ); + exit( 1 ); +} +{BACKUP_INT32_2} { + error( String( "int32: int32 expected: " ) + + String_convert::bin2hex_str( String( *( YYText() ) ) ) ); + exit( 1 ); +} {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; } +{BACKUP_INT16_0} { + error( String( "int16: int16 expected: " ) + + String_convert::bin2hex_str( String( *( YYText() ) ) ) ); + exit( 1 ); +} {I8} { tor( DEBUG_ver ) << "lex: i8" << endl; assert( YYLeng() == 1 ); @@ -137,6 +193,21 @@ SSME [\0x7f][\x03] + String_convert::bin2hex_str( String( *YYText() ) ) ); exit( 1 ); } +{BACKUP_VARINT_0}{U8} { + error( String( "track: varint expected: " ) + + String_convert::bin2hex_str( String( *( YYText() ) ) ) ); + exit( 1 ); +} +{BACKUP_VARINT_1}{U8} { + error( String( "track: varint expected: " ) + + String_convert::bin2hex_str( String( *( YYText() ) ) ) ); + exit( 1 ); +} +{BACKUP_VARINT_2}{U8} { + error( String( "track: varint expected: " ) + + String_convert::bin2hex_str( String( *( YYText() ) ) ) ); + exit( 1 ); +} {RUNNING_STATUS} { // yylval.byte = *(Byte*)YYText(); yylval.i = *(Byte*)YYText(); @@ -399,6 +470,21 @@ SSME [\0x7f][\x03] + String_convert::bin2hex_str( String( *YYText() ) ) ); exit( 1 ); } +{BACKUP_VARINT_0}{U8} { + error( String( "data: varint expected: " ) + + String_convert::bin2hex_str( String( *( YYText() ) ) ) ); + exit( 1 ); +} +{BACKUP_VARINT_1}{U8} { + error( String( "data: varint expected: " ) + + String_convert::bin2hex_str( String( *( YYText() ) ) ) ); + exit( 1 ); +} +{BACKUP_VARINT_2}{U8} { + error( String( "data: varint expected: " ) + + String_convert::bin2hex_str( String( *( YYText() ) ) ) ); + exit( 1 ); +} <> { // tor( NORMAL_ver ) << "<>"; diff --git a/mi2mu/midi-track.cc b/mi2mu/midi-track.cc index 07f57c0a67..03ac7fc130 100644 --- a/mi2mu/midi-track.cc +++ b/mi2mu/midi-track.cc @@ -13,7 +13,12 @@ Midi_track::Midi_track( int number_i, String copyright_str, String track_name_st 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() @@ -22,8 +27,9 @@ Midi_track::~Midi_track() delete midi_tempo_p_; } +#ifdef MVOICE_LIST void -Midi_track::add_begin_at( Pointer_list& open_voices_r, Moment mom ) +Midi_track::add_begin_at( Link_list& open_voices_r, Moment mom ) { for ( PCursor i( midi_voice_p_list_.top() ); i.ok(); i++ ) if ( i->begin_mom() == mom ) { @@ -31,6 +37,17 @@ Midi_track::add_begin_at( Pointer_list& open_voices_r, Moment mom ) open_voices_r.bottom().add( *i ); } } +#else +void +Midi_track::add_begin_at( Array& 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 ) @@ -69,22 +86,44 @@ Midi_track::end_mom() { // heu.. Moment mom = 0.0; +#ifdef MVOICE_LIST for ( PCursor 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 i( midi_voice_p_list_.top() ); i.ok(); i++ ) +#ifdef MVOICE_LIST + Real f = mom; + for ( PCursor 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 @@ -100,10 +139,17 @@ Midi_track::next_begin_mom( Moment now_mom ) { // Moment begin_mom = Midi_track::end_mom() + 1; Moment begin_mom = Midi_track::end_mom(); +#ifdef MVOICE_LIST for ( PCursor 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 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 begin_mom(); +#endif return begin_mom; } @@ -111,9 +157,16 @@ Moment Midi_track::next_end_mom( Moment now_mom ) { Moment end_mom = Midi_track::end_mom(); +#ifdef MVOICE_LIST for ( PCursor i( midi_voice_p_list_.top() ); i.ok(); i++ ) if ( i->end_mom() > now_mom ) end_mom = end_mom 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 end_mom(); +#endif return end_mom; } @@ -123,7 +176,9 @@ Midi_track::process() /* columns to voices */ - int bar_i = 1; +// int bar_i = 1; + int bar_i = 0; +#ifdef TCOL_LIST for ( PCursor i( tcol_p_list_.top() ); i.ok(); i++ ) { int begin_bar_i = check_begin_bar_i( i->mom(), bar_i ); if ( begin_bar_i ) @@ -132,11 +187,43 @@ Midi_track::process() 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 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; } @@ -151,9 +238,14 @@ Midi_track::output_mudela( Lily_stream& lily_stream_r ) lily_stream_r << "% instrument:" << instrument_str_; lily_stream_r.newline(); +// int bar_i = 1; int bar_i = 0; - Pointer_list open_voices; +#ifdef MVOICE_LIST + Link_list open_voices; +#else + Array open_voices; +#endif Moment now_mom = 0.0; Real now_f = now_mom; Real begin_f = 0; @@ -209,16 +301,26 @@ Midi_track::output_mudela( Lily_stream& lily_stream_r ) if ( start_of_track_bo ) { start_of_track_bo = false; String str; +#ifdef MVOICE_LIST for ( PCursor 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 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 ); } @@ -232,8 +334,8 @@ Midi_track::output_mudela( Lily_stream& lily_stream_r ) 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(); @@ -299,7 +401,8 @@ Midi_track::output_mudela_rest( Lily_stream& lily_stream_r, Moment begin_mom, Mo 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; } @@ -335,8 +438,10 @@ Midi_track::output_mudela_rest_remain( Lily_stream& lily_stream_r, Moment mom ) lily_stream_r << "r" << dur.str() << " "; } + +#ifdef MVOICE_LIST void -Midi_track::remove_end_at( Pointer_list& open_voices_r, Moment mom ) +Midi_track::remove_end_at( Link_list& open_voices_r, Moment mom ) { for ( PCursor i( open_voices_r.top() ); i.ok(); i++ ) // if ( i->end_mom() == mom ) { } @@ -347,6 +452,19 @@ Midi_track::remove_end_at( Pointer_list& open_voices_r, Moment mom break; } } +#else +void +Midi_track::remove_end_at( Array& 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 ) @@ -365,18 +483,55 @@ Midi_track::set_time( int num_i, int den_i, int clocks_i, int count_32_i ) Track_column* Midi_track::tcol_l( Moment mom ) { +#ifdef TCOL_LIST for ( PCursor 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 } diff --git a/mi2mu/midi-voice.cc b/mi2mu/midi-voice.cc index 21cac0482c..77a6526ef8 100644 --- a/mi2mu/midi-voice.cc +++ b/mi2mu/midi-voice.cc @@ -15,7 +15,11 @@ Midi_voice::Midi_voice( Moment begin_mom ) 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 @@ -27,6 +31,7 @@ Midi_voice::begin_mom() 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_; @@ -41,6 +46,20 @@ Midi_voice::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 @@ -48,12 +67,15 @@ Midi_voice::mudela_str( Moment from_mom, Moment to_mom, bool multiple_bo ) { 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 i( midi_event_p_list_.top() ); for ( ; i.ok() && now_mom < from_mom ; i++ ) now_mom += i->mom(); @@ -62,6 +84,16 @@ Midi_voice::mudela_str( Moment from_mom, Moment to_mom, bool multiple_bo ) 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 + "} "; diff --git a/mi2mu/my-midi-parser.cc b/mi2mu/my-midi-parser.cc index a8a2fb1e3b..e3a4c988cc 100644 --- a/mi2mu/my-midi-parser.cc +++ b/mi2mu/my-midi-parser.cc @@ -86,7 +86,16 @@ My_midi_parser::error( char const* sz_l ) 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 @@ -115,8 +124,15 @@ My_midi_parser::note_end_midi_event_p( int channel_i, int pitch_i, int dyn_i ) 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 ); } diff --git a/mi2mu/template.cc b/mi2mu/template.cc index 6024aa9f1d..24edd32cc4 100644 --- a/mi2mu/template.cc +++ b/mi2mu/template.cc @@ -17,9 +17,9 @@ class ostream; #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); diff --git a/mi2mu/track-column.cc b/mi2mu/track-column.cc index 57b072b3b9..a7faedf168 100644 --- a/mi2mu/track-column.cc +++ b/mi2mu/track-column.cc @@ -13,7 +13,11 @@ Track_column::Track_column( Moment mom ) 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 diff --git a/tex/lilyponddefs.tex b/tex/lilyponddefs.tex index d602bb3a14..a9db1f5fa2 100644 --- a/tex/lilyponddefs.tex +++ b/tex/lilyponddefs.tex @@ -6,6 +6,7 @@ % 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} @@ -14,7 +15,10 @@ \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 @@ -34,19 +38,23 @@ \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 @@ -90,6 +98,9 @@ \musixcalc } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% do derivative calcs + \def\musixcalc{ \interlinedist=\fontdimen5\musicfnt \smallspace=.3\interlinedist @@ -104,7 +115,8 @@ \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} @@ -120,13 +132,10 @@ \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} @@ -170,64 +179,6 @@ \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}} @@ -285,6 +236,63 @@ \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{% @@ -300,7 +308,24 @@ \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!}} -- 2.39.5