From d8895f67329930a00b556259ada0ef9a4c68f864 Mon Sep 17 00:00:00 2001 From: fred Date: Tue, 26 Mar 2002 21:46:47 +0000 Subject: [PATCH] lilypond-1.1.28 --- Documentation/tex/lilypond-overview.doc | 2 + Documentation/tex/refman.yo | 365 ++++++++++---- Documentation/tex/tutorial.yo | 68 ++- configure.in | 2 - flower/include/array.hh | 73 ++- flower/include/array.icc | 31 ++ flower/include/link.icc | 16 +- flower/include/parray.hh | 107 +++- input/bugs/time-grouping.ly | 16 + input/just-friends.ly | 58 +++ input/opus-130.ly | 6 - input/star-spangled-banner.ly | 7 - input/test/auto-beam-override.ly | 38 ++ input/test/auto-beam.ly | 95 ++-- input/test/chord-inversion.ly | 3 +- input/test/chord-table.ly | 2 +- input/test/coda-kludge.ly | 52 ++ input/test/ly2dvi-testpage.ly | 40 ++ input/test/rep.ly | 2 +- input/test/span-bars.ly | 23 + lib/duration-convert.cc | 6 +- lib/duration.cc | 4 +- lib/include/duration.hh | 2 +- lily/GNUmakefile | 3 + lily/abbrev.cc | 7 +- lily/abbreviation-beam.cc | 2 +- lily/atom.cc | 134 +++-- lily/auto-beam-engraver.cc | 103 +++- lily/bar-engraver.cc | 16 +- lily/bar-number-engraver.cc | 4 +- lily/bar-script-engraver.cc | 2 +- lily/bar.cc | 12 +- lily/base-span-bar-engraver.cc | 91 ++++ lily/beam-engraver.cc | 16 +- lily/beam.cc | 24 +- lily/bow.cc | 4 +- lily/boxes.cc | 7 + lily/break.cc | 5 +- lily/change-iterator.cc | 18 +- lily/chord-name-engraver.cc | 41 +- lily/chord.cc | 387 +++++++++----- lily/clef-item.cc | 7 +- lily/collision.cc | 3 +- lily/command-request.cc | 8 +- lily/crescendo.cc | 30 +- lily/dimension-cache.cc | 1 + lily/dots.cc | 8 +- lily/dynamic-engraver.cc | 4 +- lily/engraver-group.cc | 6 +- lily/engraver.cc | 3 +- lily/extender-spanner.cc | 9 +- lily/g-text-item.cc | 4 +- lily/general-script-def.cc | 18 +- lily/global-ctor.cc | 27 + lily/global-translator.cc | 2 +- lily/graphical-element.cc | 3 +- lily/heads-engraver.cc | 8 +- lily/include/atom.hh | 54 +- lily/include/bar.hh | 1 + lily/include/base-span-bar-engraver.hh | 44 ++ lily/include/beam-engraver.hh | 2 +- lily/include/box.hh | 1 + lily/include/change-iterator.hh | 1 - lily/include/chord-name-engraver.hh | 18 +- lily/include/chord.hh | 4 +- lily/include/colhpos.hh | 4 +- lily/include/command-request.hh | 2 +- lily/include/cons.cc | 10 + lily/include/cons.hh | 43 ++ lily/include/crescendo.hh | 2 +- lily/include/general-script-def.hh | 4 +- lily/include/global-ctor.hh | 32 ++ lily/include/global-translator.hh | 2 +- lily/include/includable-lexer.hh | 4 +- lily/include/killing-cons.tcc | 27 + lily/include/lily-proto.hh | 1 + lily/include/line-of-score.hh | 2 +- lily/include/lookup.hh | 53 +- lily/include/lyric-performer.hh | 2 +- lily/include/midi-def.hh | 2 +- lily/include/midi-item.hh | 2 +- lily/include/misc.hh | 2 +- lily/include/molecule.hh | 22 +- lily/include/music-list.hh | 4 +- lily/include/music-wrapper-iterator.hh | 1 - lily/include/music-wrapper.hh | 2 +- lily/include/music.hh | 2 +- lily/include/musical-request.hh | 20 +- lily/include/my-lily-lexer.hh | 2 +- lily/include/my-lily-parser.hh | 6 +- lily/include/paper-def.hh | 2 +- lily/include/paper-outputter.hh | 2 - lily/include/protected-scm.hh | 2 +- lily/include/repeat-engraver.hh | 1 + lily/include/repeated-music-iterator.hh | 3 - lily/include/repeated-music.hh | 2 +- lily/include/request-iterator.hh | 4 +- lily/include/rhythmic-grouping.hh | 60 +++ lily/include/score-element-info.hh | 4 +- lily/include/script-def.hh | 2 +- lily/include/script-engraver.hh | 4 +- lily/include/script.hh | 1 - lily/include/slur-engraver.hh | 8 +- lily/include/span-bar.hh | 29 +- lily/include/span-score-bar-engraver.hh | 6 +- lily/include/staff-side.hh | 1 - lily/include/stem.hh | 2 +- lily/include/text-def.hh | 5 +- lily/include/time-signature-engraver.hh | 8 +- lily/include/timing-translator.hh | 2 +- lily/include/translator.hh | 31 +- lily/item.cc | 6 +- lily/lexer.ll | 7 +- lily/line-of-score.cc | 30 +- lily/lookup.cc | 474 +++++++++--------- lily/main.cc | 7 + lily/midi-def.cc | 2 +- lily/midi-item.cc | 14 +- lily/midi-walker.cc | 2 +- lily/molecule.cc | 88 ++-- lily/multi-measure-rest-engraver.cc | 10 +- lily/multi-measure-rest.cc | 8 +- lily/music-list.cc | 8 +- lily/music-wrapper-iterator.cc | 8 +- lily/music-wrapper.cc | 4 +- lily/music.cc | 2 +- lily/musical-request.cc | 74 +-- lily/my-lily-parser.cc | 9 +- lily/note-column.cc | 24 +- lily/note-head.cc | 35 +- lily/p-col.cc | 6 +- lily/p-score.cc | 32 -- lily/paper-def.cc | 2 +- lily/paper-outputter.cc | 88 ++-- lily/parser.yy | 30 +- lily/protected-scm.cc | 7 +- lily/repeat-engraver.cc | 87 ++-- lily/repeated-music-iterator.cc | 48 +- lily/repeated-music.cc | 7 +- lily/request-iterator.cc | 10 +- lily/rest.cc | 4 +- lily/rhythmic-column-engraver.cc | 21 +- lily/rhythmic-grouping.cc | 383 ++++++++++++++ lily/score-element.cc | 11 +- lily/score-engraver.cc | 4 +- lily/score-performer.cc | 10 +- lily/score.cc | 2 +- lily/script-def.cc | 6 +- lily/script-engraver.cc | 3 +- lily/script.cc | 11 +- lily/sequential-music-iterator.cc | 2 +- lily/slur.cc | 2 + lily/span-bar-engraver.cc | 89 +--- lily/span-bar.cc | 42 +- lily/span-score-bar-engraver.cc | 44 +- lily/spring-spacer.cc | 14 +- lily/staff-margin-engraver.cc | 4 +- lily/staff-performer.cc | 4 +- lily/staff-side.cc | 12 +- lily/staff-sym.cc | 10 +- lily/stem-info.cc | 2 +- lily/stem.cc | 16 +- lily/template4.cc | 3 +- lily/text-def.cc | 23 +- lily/text-engraver.cc | 4 +- lily/text-spanner.cc | 6 +- lily/tie-engraver.cc | 6 +- lily/time-description.cc | 8 +- lily/time-signature.cc | 10 +- lily/timing-translator.cc | 6 +- lily/translator-ctors.cc | 21 - lily/translator-group.cc | 2 +- lily/translator.cc | 4 +- lily/tuplet-engraver.cc | 4 +- lily/tuplet-spanner.cc | 11 +- lily/volta-spanner.cc | 19 +- ly/auto-beam-settings.ly | 24 + ly/declarations.ly | 2 +- ly/dynamic.ly | 43 +- ly/params.ly | 2 + ly/property.ly | 3 + mf/GNUmakefile | 3 +- mf/feta-accordion.mf | 2 + mf/feta-bolletjes.mf | 34 +- mutopia/E.Satie/petite-ouverture-a-danser.ly | 2 - .../J.S.Bach/Petites-Preludes/preludes-1.ly | 7 - .../J.S.Bach/Petites-Preludes/preludes-2.ly | 7 - .../J.S.Bach/Petites-Preludes/preludes-4.ly | 7 - .../J.S.Bach/Petites-Preludes/preludes-5.ly | 7 - .../J.S.Bach/Petites-Preludes/preludes-6.ly | 8 - .../J.S.Bach/Solo-Cello-Suites/scs-paper.ly | 8 - mutopia/J.S.Bach/wtk1-fugue2.ly | 7 - ps/lily.ps | 3 +- scm/lily.scm | 201 ++++---- tex/lilyponddefs.tex | 40 -- 195 files changed, 3077 insertions(+), 1877 deletions(-) create mode 100644 input/bugs/time-grouping.ly create mode 100644 input/just-friends.ly create mode 100644 input/test/auto-beam-override.ly create mode 100644 input/test/coda-kludge.ly create mode 100644 input/test/ly2dvi-testpage.ly create mode 100644 input/test/span-bars.ly create mode 100644 lily/base-span-bar-engraver.cc create mode 100644 lily/global-ctor.cc create mode 100644 lily/include/base-span-bar-engraver.hh create mode 100644 lily/include/cons.cc create mode 100644 lily/include/cons.hh create mode 100644 lily/include/global-ctor.hh create mode 100644 lily/include/killing-cons.tcc create mode 100644 lily/include/rhythmic-grouping.hh create mode 100644 lily/rhythmic-grouping.cc create mode 100644 ly/auto-beam-settings.ly diff --git a/Documentation/tex/lilypond-overview.doc b/Documentation/tex/lilypond-overview.doc index 885faa6727..eae2c17b7c 100644 --- a/Documentation/tex/lilypond-overview.doc +++ b/Documentation/tex/lilypond-overview.doc @@ -12,6 +12,8 @@ \begin{document} \maketitle +[THIS IS WORK IN PROGRESS. THIS PAPER IS NOT FINISHED] + % -*-LaTeX-*- \section{Introduction} diff --git a/Documentation/tex/refman.yo b/Documentation/tex/refman.yo index f84468dc12..6cad45cc87 100644 --- a/Documentation/tex/refman.yo +++ b/Documentation/tex/refman.yo @@ -7,11 +7,11 @@ redef(var)(1)(whenlatex(latexcommand({\normalfont\scshape )ARG1+latexcommand(})) redef(code)(1)(tt(ARG1)) + COMMENT( TODO: the use of semicolons needs to be documented once it settles down - \times needs documentation with examples somewhere once it works (?) paper size? the explanation of how lyrics mode parses words seems ridiculous. Is there a simple way to explain this, or is the behavior @@ -22,15 +22,39 @@ TODO: accordion symbols extender* (see extender.ly) \repeat & \alternative -> probably should have an example + properties: + unfoldRepeats + voltaVisibility + property: stemLeftBeamCount stemRightBeamCount + interstaff beams (beam-interstaff.ly) + interstaff slurs (see preludes-1.ly) + boolean property barAuto + property: noteheadStyle + harmonics: test/harmonics.fly + autobeamer + properties: beamAutoEndx ??? rational string "1/2" + beamAutoBegin + beamAutoEnd + beamAuto + ScriptPadding + Direction + chordNameStyle (banter) + chordInversionPreserve + createInitdefaultClef + dynamicStyle + singleStaffBracket + numberOfStaffLines + + + {Mark,BarNumber,Margin}{Direction,ScriptPadding} + + ) -COMMENT( This document contains Mudela fragments. You need at least +COMMENT( +This document contains Mudela fragments. You need at least Yodl-1.30.18 to convert this to tex or html. - -TODO - -in stead <-> instead ) htmlbodyopt(bgcolor)(white) @@ -47,7 +71,7 @@ latexlayoutcmds( whentexinfo(notableofcontents()) -article(Mudela 1.0.7 / LilyPond 1.1.8 Reference Manual) +article(Mudela 1.0.14 / LilyPond 1.1.27 Reference Manual) (Adrian Mariano, Han-Wen Nienhuys and Jan Nieuwenhuizen) (nop()PIPETHROUGH(date "+%B %d, %Y")()()nop()) @@ -225,16 +249,16 @@ will only be able to refer to identifiers whose names begin with a letter and are entirely alphanumeric. It is also impossible to refer to an identifier whose name is the same as the name of a keyword. The following words are keywords: -verb(absdynamic grouping mm relative -accepts header musicalpitch remove -alternative in name repeat tempo -bar include notenames scm time -cadenza key notes scmfile times -clef keysignature paper score translator -cm lyrics partial script transpose -consists maininput penalty shape type -duration mark property skip version -font midi pt spandynamic) +verb(absdynamic duration mark property skip +accepts font midi pt spandynamic +alternative grouping mm relative tempo +bar header musicalpitch remove time +cadenza in name repeat times +chordmodifier include notenames scm translator +chords key notes scmfile transpose +clef keysignature paper score type +cm lyrics partial script version +consists maininput penalty shape) The right hand side of an identifier assignment is parsed completely when the assignment is made. It therefore must have any context @@ -318,6 +342,10 @@ notename of code(word). If no notename is found, then code(word) is treated as a string. If you mistype a notename, the parser will most likely complain that you should be in code(\lyrics) mode to do lyrics. +dit(Chord mode) Chord mode is instroduced by the keyword code(\chords). +Very similar to Note mode. +COMMENT(I'm not sure how it differs) + dit(Lyric mode) Lyrics mode is introduced by the keyword code(\lyrics). This mode is has rules that make it easy to include punctuation and diacritical marks in words. A word in Lyrics mode @@ -437,42 +465,66 @@ mudela(fragment,verbatim,center)( a'4. b'4. ) -In addition, the duration can be followed by a multiplier which is -introduced with the asterisk code(*) and can be an integer or a -fraction. The multiplier changes the duration that LilyPond uses -internally for the note, but for notes it -does not change the symbol that is printed. +Extra long notes can be obtained using the code(\breve) and +code(longa) durations: mudela(fragment,verbatim,center)( -c'4*2 c'4*2 d'8*2/3 d'8*2/3 +c'\breve gis'\longa +) + +In order to get triplets and other tuplets, you must use the +code(\times) keyword which multiplies the duration by a fraction. The +syntax is code(\times) var(fraction) var(music). The length of all of +the specified music will be multiplied by the fraction and the +fraction's denominator will be printed over the notes. The most +common tuplet is the triplet in which 3 notes have the length of 2, so +the notes are 2/3 their written length: +mudela(fragment,verbatim,center)( b'4 \times 2/3 {c'4 c' c'} d'4 d'4 ) +If you try to use code(\times) as the first thing in your music, you +may encounter the warning ``No one to print a tuplet start bracket''. +This happens because the Tuplet-engraver is in Voice and no Voice has +been created yet. You must explicitly specify the Voice context in +this situation +mudela(fragment,verbatim,center)( +\type Voice { \times 2/3 {c'4 d' e'}} ) + +A shorthand for code(\times) is to write code(*)var(fraction) after a +duration. This shorthand will not label triplets correctly, but +it is convenient for long rests. For long rests with durations equal to an integer number of whole notes, LilyPond produces output that indicates the duration of the rest. If you use code(r) then one rest symbol will be printed and several measures left blank. If you use code(R) then all of the measure will be filled with whole rests. +mudela(fragment,verbatim,center)( +r1 r1*3 R1*3 +) If you set the code(Score.SkipBars) property, then only one measure will be printed; with code(R), a number indicating the length of the rest will be displayed. mudela(fragment,verbatim,center)( -r1*3 R1*3 \property Score.SkipBars=1 -r1*3 R1*3) - -Extra long notes can be obtained using the code(\breve) and -code(longa) durations: +r1 r1*3 R1*3 +) +Even though the code(\times) command is not explicit, it is still +necessary to specify a code(Voice) context if the music begins with +rests lengthened using code(*). +Otherwise, the following will result: mudela(fragment,verbatim,center)( -c'\breve gis'\longa +R1*3 c'1 d' ) - -subsect(Note Spanners: Beams, Tuplets, Slurs and Ties) +subsect(Note Spanners: Beams, Slurs and Ties) A beam is specified by surrounding the beamed notes with brackets code([) and code(]). mudela(fragment,verbatim,center)( -[a'8 a'] [a'16 a' a' a'] +[a'8 a'] [a'16 a' a' a'] +) +Some more elaborate constructions: +mudela(fragment,verbatim,center)( +[a'16 c'' ] +\times 2/3 { [e'8 f' g'] } ) - -[EXPLAIN TUPLETS HERE] Another type of spanner is the slur. Slurs connects chords and try to avoid crossing stems. A slur is started with code(CHAR(40)) and stopped with @@ -492,6 +544,22 @@ mudela(fragment,verbatim,center)( e' ~ e' ~ ) +It is possible to create beams and slurs that cross staffs by switching the +context: +mudela(fragment,verbatim,center)( +< +\type Staff=one \notes\relative c'{ + \stemup + [c8 c \translator Staff=two \stemup c c] + \translator Staff=one + d4( \translator Staff=two )a4 + } +\type Staff=two \notes{ \clef bass;} +> +) + + +COMMENT(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) subsect(Note Ornaments) @@ -515,17 +583,17 @@ mudela()( c''-\open c''-\flageolet c''-\reverseturn c''-\trill c''-\prall c''-\mordent c''-\prallprall c''-\prallmordent - c''-\upprall c''-\downprall c''-\thumb} + c''-\upprall c''-\downprall c''-\thumb } \type Lyrics \lyrics{ accent marcato staccatissimo fermata stopped staccato tenuto upbow downbow lheel rheel ltoe rtoe turn open flageolet reverseturn trill prall - mordent prallprall prallmordent uprall downprall thumb}> - \paper{linewidth = 5.875\in; - indent = 0.0; - } -} + mordent prallprall prallmordent uprall downprall thumb } + > + \paper{ linewidth = 5.875\in; + indent = 0.0; } + } ) COMMENT( The following are defined in script.ly but do not work: @@ -572,6 +640,9 @@ mudela(fragment,verbatim,center)( c'' \< \! c'' d'' \decr e'' \rced < f''1 {s4 \< \! s4 \> \! s2 } >) + +COMMENT(Broken!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) + Tremolo marks can be printed by a note by adding code(:)[var(length)] after the note. The length must be at least 8. A var(length) value of 8 gives one line across the note stem. @@ -683,6 +754,101 @@ code(\transpose) first. Any code(\relative) keywords that are outside the code(\transpose) have no effect on notes that appear inside the code(\transpose). +sect(Chords) + +Chords can be entered either by name or by listing the notes in angle brackets. +Chords can be displayed either as notes or by name. To enter chords by name, +either place them inside the code(\chords) keyword, or use +code(\notes) and surround them with +code(@) characters. +Chord names have the form +var(tonic)[var(duration)][code(-)var(modifier)][code(^)var(subtractions)][code(/)var(inversion)] +The var(tonic) should be the tonic note of the chord, and the var(duration) is +the chord duration in the usual notation. There are two kinds of modifiers. +One type is chord additions, which are obtained by listing intervals separated +by dots. An interval is written by its number with an optional code(+) or +code(-) to indicate raising or lowering by half a step. A chord additions has +two effects: it adds the specified interval and all lower odd numbered +intervals to the chord, and it may lower or raise the specified interval. +Intervals can be separated by a dot (code(.)) if you need to list +several unmodified intervals. +Repeating a code(-) character will remove a half step from the preceeding +interval. +mudela(fragment,verbatim,center)( +\transpose c''{ +\chords{ + c1 c-3- c-7 c-8 c-9 + c-9-5+7+ c-3-5- c-4.6.8 +}}) +The second type of modifier that may appear after the code(-) is +a named modifier. +Named modifiers are listed in the file file(chord-modifiers.ly). The +available modifiers are code(m) and code(min) which lower +the 3rd half a step, code(aug) which raises the 5th, code(dim) which lowers +the 5th, code(maj) which adds a raised 7th, and code(sus) which replaces the +5th with a 4th. +mudela(fragment,verbatim,center)( +\transpose c''{ +\chords{ + c1-m c-min c-maj c-aug c-dim c-sus +}}) + +Chord subtractions are used to eliminate notes from a chord. The notes to be +subtracted are listed after a code(^) character, separated by dots. +mudela(fragment,verbatim,center)( +\transpose c''{ +\chords{ + c1^3 c-7^5.3 c-8^7 +}}) + +Chord inversions can be specified by appending code(/) and the name of a +single note to a chord. This has the effect of lowering the specified note by +an octave so it becomes the lowest note in the chord. If the +specified note is not in the chord then a warning will be printed. +mudela(fragment,verbatim,center)( +\transpose c'''{ + @c1@ @c/e@ @c/g@ @c-7/e@ +}) +Throughout these examples, chords have been shifted around the staff +using code(\transpose). The code(\relative) keyword has odd effects +when combined with named chords. + +For displaying printed chord names, use the code(ChordNames) context. +The chords may be entered either using the notation described above, +or directly using angle brackets. +mudela(fragment,verbatim)( +< + \type ChordNames { \chords{ a b c} \notes{ < d f g > < e g b > } } + \type Staff \notes{ a b c' d' e' } +> +) +Lilypond examines chords specified as lists of notes to determine a +name to give the chord. By default, LilyPond will not try to identify +chord inversions: +mudela(fragment,verbatim,center)( +< + \type ChordNames { + \notes{ < e' g' c'' > } } + \type Staff \notes{ c' } +>) +If you want inversions to be recognized, you must set the property +code(Score.chordInversion): +mudela(fragment,verbatim,center)( +< + \property Score.chordInversion = 1 + \type ChordNames { + \notes{ < e' g' c'' > } } + \type Staff \notes{ c' } +>) + +COMMENT( + Two other properties + chordInversionPreserve + and chordNameStyle = Banter + exist. What do these do? +) + + sect(Lyrics) Lyrics are entered like notes, with pitches replaced @@ -714,39 +880,29 @@ URG Why does this warrant an URG? ) +When one word is attached to many notes, you may +want a continuous line after the lyric to show this. To achieve +this effect, add a code(__) lyric after the lyric to be extended. +This will create +an extender, a line that extends over the entire duration of +the lyric. There must be a lyric after the code(__), so if you want +to extend the final lyric, you will have to end with a blank lyric. +mudela(verbatim,center)( +\score{ +< \notes \relative c''{ + a4()b()c()d c()d()b()a } + \type Lyrics \lyrics { + foo1 __ bar2. __ _ } +> }) + -COMMENT( - -sect(Chords and Voices) - -Here's a simple chord -mudela(fragment,verbatim,center)( - -) - -here are a few -mudela(fragment,verbatim,center)( -< - { c'()d'()c' } - { e'()f'()e' } - { g'()a'()g' } -> -) - -and similarly voices -mudela(fragment,verbatim)( -< - { \voiceone c'4 g' c' g' } - { \voicetwo c2 g2 } -> -) +COMMENT(Broken!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) -) sect(Time) LilyPond aligns all musical objects according to the amount of time -they occupy. All of these objects have a duration. When music is +they occupy. All musical objects have a duration. When music is written sequentially using braces the duration is the sum of the durations of the elements. When music is stacked into simultaneous music using angle @@ -843,6 +999,30 @@ verb( ) +sect(Repeats) + +In order to specify repeats, use the code(\repeat) keyword. By +default, repeats are printed with repeat symbols. +mudela(fragment,verbatim,center)( +c'1 +\repeat 2 { c'4 d' e' f' } +\repeat 2 { f' e' d' c' }) +In order to specify alternate endings, use the code(\alternative) +keyword. +mudela(fragment,verbatim,center)( +c'1 +\repeat 2 {c'4 d' e' f'} +\alternative { {d'2 d'} {f' f} }) +When the repeats involve partial measures, it will be necessary to use +code(\partial) keywords to indicate which measures are short. +mudela(fragment,verbatim)( +\type Staff { \relative c'{ + \repeat 2 { \partial 4; e | c2 d2 | e2 f2 | } + \alternative { { g4 g g } {\partial 2.; a a a a | b1 } } +}}) +Repeats can be unfolded by setting the unfoldRepeats + + sect(Keywords) Keywords sometimes appear alone, but usually they require arguments. @@ -907,7 +1087,7 @@ mudela(center)( mudela(center)( \score{ \notes{\cadenza 1; \clef alto; c'4_"\kern -10mm alto" - \clef scarlatti; c'4_"\kern -4mm scarlatti" + % \clef scarlatti; c'4_"\kern -4mm scarlatti" \clef mezzosoprano; c'4^"\kern -10mm mezzosoprano" \clef soprano; c'4_"\kern -10mm soprano" \clef treble; c'4^"\kern -6mm treble" @@ -973,7 +1153,7 @@ dit(code(\lyrics) var(lyriclist)) Parse var(lyriclist) in lyrics mode. dit(code(\maininput)) Internal command. This command is used for creating init files like file(init.fly) that read the user file into the middle of another -file. Using it in a user file will lead to an infinite loop. +file. It is illegal to use this command in a user file. dit(code(\mark) var(unsigned)code(;) or code(\mark) var(string)code(;)) Allowed in music only. Prints a mark over or under (depending on the @@ -1007,8 +1187,6 @@ code(\musicalpitch) keyword. dit(code(\notes) var(music)) Enter note mode and process the specified music. -dit(code(\)code(output) var(string)code(;)) Generate a parse error. - dit(code(\paper) var(statmentlist)) Appears in a score block to indicate that the music should be printed or to set output parameters. Can also appear at the top level to set @@ -1163,6 +1341,12 @@ dit(code(Voice)) Corresponds to a voice on a staff. This context handles the conversion of noteheads, dynamic signs, stems, beams, super- and subscripts, slurs, ties and rests. +dit(code(ChordNamesVoice)) A voice with chord names. Handles printing +of a line of chord names. + +dit(code(ChordNames)) Typesets chord names. Can contain +code(ChordNamesVoice) contexts. + dit(code(Lyrics)) Typesets lyrics. It can contain code(LyricVoice) contexts. dit(code(Staff)) Handles clefs, bar lines, keys, @@ -1177,6 +1361,10 @@ contexts. It adds a brace on the left side grouping the staffs together. The bar lines of the contained staffs are connected vertically. It can contain code(Staff) contexts. +dit(code(PianoStaff)) Just like code(GrandStaff) but with +code(minVerticalAlign) set equal to code(maxVerticalAlign) so that +interstaff beaming and slurring can be used. + dit(code(StaffGroup)) Contains code(Staff) or code(RhythmicStaff) contexsts. Adds a bracket on the left side, grouping the staffs together. The bar lines of the contained staffs are connected vertically. @@ -1262,7 +1450,7 @@ direction, set to code(\up) to force slurs up, set to code(\down) to force slurs down. The shorthands code(\slurup), code(\slurdown), and code(\slurboth) are available. -dit(code(tieYDirection)) Set to code(\free) for free choice of tie +dit(code(tieydirection)) Set to code(\free) for free choice of tie direction, set to code(\up) to force ties up, set to code(\down) to force ties down. @@ -1275,7 +1463,7 @@ horizontally if they collide with other notes. This is useful when typesetting many voices on one staff. The identifier code(\shift) is defined to enable this. -dit(code(dynamicdir)) Determines location of dynamic marks. Set to +dit(code(dynamicDir)) Determines location of dynamic marks. Set to code(\up) to print marks above the staff; set to code(\down) to print marks below the staff. @@ -1379,6 +1567,8 @@ mudela(fragment,center)( } ) +COMMENT(Broken!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) + ) @@ -1420,8 +1610,12 @@ beams with zero slope. The identifiers code(\beamslopeproportional), code(\beamslopedamped), and code(\beamslopezero) each set the corresponding value. +dit(code(chordInversion)) Determines whether LilyPond should look for +chord inversions when translating from notes to chord names. Set to 1 +to find inversions. The default is 0 which does not look for inversions. + ) - + COMMENT( @@ -1429,10 +1623,6 @@ Mystery properties: bar-number-engraver.cc: "barScriptPadding" vertical space for numbers span-bar-engraver.cc: "singleStaffBracket" do single staffs get a bracket? -bar-column-engraver.cc: "barColumnPriority" -bar-number-engraver.cc: "barNumberBreakPriority" Control horizontal ordering -mark-engraver.cc: "markBreakPriority" of bars, clefs, keysig -staff-margin-engraver.cc:"marginBreakPriority" etc. Slated for revision ) sect(Pre-defined Identifiers) @@ -1556,6 +1746,8 @@ at the top level, these assignments must be terminated by a semicolon. subsect(Paper variables) +Warning: this section is outdated and inaccurate. + There are a large number of paper variables that are used to control details of the layout. Usually you will not want to change these variables; they are set by default to vaules that depend on the font @@ -1601,17 +1793,10 @@ whether beams go up or down. It is real valued. If set to 2.0 then majority selection is used. If set to 3.0, then mean selection is used based on the mean center distance. If set to 4.0 then median selection is used, based on the median center distance. -dit(code(beam_ideal_stem1)) -dit(code(beam_ideal_stem2)) -dit(code(beam_minimum_stem1)) -dit(code(beam_minimum_stem2)) -dit(code(beam_multiple_break)) -dit(code(beam_slope_damp_correct_factor)) -dit(code(beam_thickness)) Specify the thickness of beams. dit(code(castingalgorithm)) dit(code(forced_stem_shorten)) Stems that have been forced to go the unnatural direction are shortened by this amount. Equal to -code(\interline) by default. +dit(code(forced_stem_shorten0)) dit(code(gourlay_energybound)) dit(code(gourlay_maxmeasures)) Maximum number of measures per line when using Gourlay method. @@ -1792,7 +1977,6 @@ The engravers for paper output are: description( dit(code(Abbreviation_beam_engraver)) -dit(code(Bar_column_engraver)) dit(code(Bar_engraver)) Engraves bar lines. Normally in code(Staff) and code(RhythmicStaff). dit(code(Bar_number_engraver)) Engrave bar numbers. These numbers @@ -1806,6 +1990,8 @@ with flags instead of beams. dit(code(Beam_req_swallow_translator)) Swallows beam requests. In code(LyricVoice). +dit(code(Chord_name_engraver)) Engraves chord names. Normally in +code(ChordNameVoice) dit(code(Clef_engraver)) Engraves the clef symbol. Normally in code(Staff). dit(code(Collision_engraver)) dit(code(Dot_column_engraver)) Engraves dots on dotted notes shifted to the @@ -1822,11 +2008,6 @@ dit(code(Piano_bar_engraver)) dit(code(Pitch_squash_engraver)) Treat all pitches as middle C. Used in code(RhythmicStaff). Note that the notes move, but the locations of accidentals stay the same. -dit(code(Plet_engraver)) Engraves brackets and the number over tuplets. In -code(Voice). -dit(code(Plet_swallow_engraver)) Swallows tuplet requests without any output. -In code(LyricVoice). -COMMENT( Should this be named Plet_req_swallow_translator? ) dit(code(Priority_horizontal_align_engraver)) dit(code(Repeat_engraver)) Handles repeats? In code(Staff) and code(RhythmicStaff). diff --git a/Documentation/tex/tutorial.yo b/Documentation/tex/tutorial.yo index 25f8d74ea6..b8c65bdf4f 100644 --- a/Documentation/tex/tutorial.yo +++ b/Documentation/tex/tutorial.yo @@ -98,16 +98,16 @@ mudela(verbatim)( \time 3/4; \repeat 2 { - d4 [g,8 a b c] d4 g, g | - e'4 [c8 d e fis] g4 g, g | - c4 [d8( )c b a( ] )b4 [c8 b a g] | - a4 [b8 a g fis] g2. | + d4 g,8 a b c d4 g, g | + e'4 c8 d e fis g4 g, g | + c4 d8( )c b a( )b4 c8 b a g | + a4 b8 a g fis g2. | } - b'4 [g8 a b g] - a4 [d,8 e fis d] | - g4 [e8 fis g d] cis4 [b8 cis] a4 | - [a8-. b-. cis-. d-. e-. fis-. ] + b'4 g8 a b g + a4 d,8 e fis d | + g4 e8 fis g d cis4 b8 cis a4 | + a8-. b-. cis-. d-. e-. fis-. g4 fis e | fis a, r8 cis8 d2.-\fermata @@ -223,16 +223,6 @@ verb( code(c''), the real pitch of this note is code(d''). The 4 designates the duration of the note (it is a quarter note). COMMENT( -)verb( - [g,8 -)COMMENT( - -)The open bracket starts a beam. Lily can set beams automatically, -but we want to specify them ourselves. This bracket is connected to the -following note, which is an eighth with pitch code(g') (remember -relative mode for pitches!) -COMMENT( - )verb( a b )COMMENT( @@ -242,16 +232,6 @@ duration is the same as the code(g), there is no need to enter the duration (It is not illegal to enter it anyway. You would then enter code(a8 b8)) COMMENT( -)verb( - c] -) COMMENT( - -) This ends the beam started four notes earlier, at the code(g). In -the output, you will notice a measure bar following this note. You do -not have to enter anything to make LilyPond create a bar. Instead -Lily will deduce where bars have to be by comparing durations of notes with -the current time signature. COMMENT( - )verb( d4 g, g | ) COMMENT( @@ -260,7 +240,7 @@ the current time signature. COMMENT( music, LilyPond will check that barchecks are found at the start of a bar. This can help you track down notes you forgot to enter. verb( - e'4 [c8 d e fis] + e'4 c8 d e fis ) COMMENT( ) So far, no notes were chromatically altered. Here is the first one @@ -269,17 +249,16 @@ that is: code(fis). Mudela by default uses Dutch note names, and sharp sign in the output. The program keeps track of key signatures, and will only print accidentals if they are needed. verb( - c4 [d8( )c b a( ] )b4 [c8 b a g] | + c4 d8( )c b a( )b4 c8 b a g | ) COMMENT( ) The next line shows something new: In mudela, one enters a slur by marking the beginning and ending note of the slur with an opening and closing parenthesis respectively. In the line shown above this is done for two slurs. Note that parentheses (slur markers) are between -the notes, and the brackets (beam markers) around the notes. As you -can see, the brackets and parentheses do not have to nest. +the notes. As you can see, parentheses do not have to nest. verb( - a4 [b8 a g fis] g2. | + a4 b8 a g fis g2. | ) COMMENT( ) A duration that is to be augmented with a duration dot, is notated @@ -291,14 +270,14 @@ verb( ) The end of the repeated music. LilyPond will typset a repeat bar. verb( - cis'4 [b8 cis] a4 | + cis'4 b8 cis a4 | ) COMMENT( ) This line shows that Lily will print an accidental if that is needed: the first C sharp will be printed with an accidental, the second one without. COMMENT( -)verb( [a8-. b-. cis-. d-. e-. fis-. ] % try some super and subscripts.)COMMENT( +)verb( a8-. b-. cis-. d-. e-. fis-. % try some super and subscripts.)COMMENT( )There is more to music than just pitches and rhythms. An important aspect is articulation. You can enter articulation signs either in an @@ -545,8 +524,8 @@ that is covered in bind(Section)ref(sec:polyphonic). subsect(Chords with names) -In the previous section we have been talking more about 'stacked notes' -rather than 'chords'. +In the previous section we have been talking more about `stacked notes' +rather than `chords'. If you need to enter a lot of chords that have proper names, you can use the code(\chords) mode as an alternative: COMMENT( @@ -1256,7 +1235,10 @@ perfor0mable: COMMENT( )mudela(fragment,verbatim)( < - \type Staff { c''8. c''16 bes'8. a'16 g'4 f'8 g'4. } + \type Staff { + \property Voice.beamAuto = "0" % no beams in melody + c''8. c''16 bes'8. a'16 g'4 f'8 g'4. + } \type Lyrics \lyrics { 'got8. me16 on8. my16 knees,4 Le-8 lie!4. } > ) COMMENT( @@ -1276,7 +1258,10 @@ urg )COMMENT( )mudela(fragment,verbatim)(< - \type Staff { c''8. c''16 bes'8. a'16 g'4 f'8 g'4. } + \type Staff { + \property Voice.beamAuto = "0" % no beams in melody + c''8. c''16 bes'8. a'16 g'4 f'8 g'4. + } \type Lyrics \lyrics { 'got8 me8 on8. m$\cal_Y$16 "3s,"4 Le-8 lie!4.} > )COMMENT( @@ -1684,9 +1669,14 @@ COMMENT( Of course, you can also use different ratios, and use beamed notes or rests: +COMMENT( BROKEN + +lilypond: score-element.cc:134: class Paper_def * Score_element::paper() const: Assertion `pscore_l_' failed. + mudela(fragment)( \type Voice \times 4/5 { [c''8 c''16 c''16] r8 [g'8 g'8] } ) +) If you make a tuplet of beamed notes, where the beam is as wide as the bracket, the bracket is omitted. diff --git a/configure.in b/configure.in index 4f251a61fe..854c957dd4 100644 --- a/configure.in +++ b/configure.in @@ -39,8 +39,6 @@ AC_STEPMAKE_TEXMF AC_STEPMAKE_YODL AC_STEPMAKE_GUILE -CXXFLAGS="$CXXFLAGS -fhandle-signatures" - dnl should check out -print dnl huh? dnl AC_CHECK_SEARCH_RESULT($FIND, find, Please use --enable-tex-dir) diff --git a/flower/include/array.hh b/flower/include/array.hh index cc489fdf10..c8fe30f16f 100644 --- a/flower/include/array.hh +++ b/flower/include/array.hh @@ -56,15 +56,12 @@ protected: public: /// check invariants - void OK() const - { - assert (max_ >= size_ && size_ >=0); - if (max_) assert (array_p_); - } + void OK() const ; /** report the size_. @see {setsize_} */ + int size() const { return size_; @@ -88,10 +85,10 @@ public: // ugh, get around gcc 2.8.1 ice; see bezier.cc Array (int i) - { - max_ = size_ = i; - array_p_ = new T[i]; - } + { + max_ = size_ = i; + array_p_ = new T[i]; + } /** set the size_ to #s#. @@ -107,17 +104,13 @@ public: { delete[] array_p_; } /// return a "new"ed copy of array - T* copy_array() const + T* copy_array() const { T* Tarray = new T[size_]; arrcpy (Tarray, array_p_, size_); return Tarray; } - // depracated - operator T*() const - { - return copy_array(); - } + void operator=(Array const & src) { set_size (src.size_); @@ -130,37 +123,36 @@ public: } /// tighten array size_. - void precompute() { - remax (size_); - } - - T * remove_array_p () { - T * p = array_p_; - size_ = 0; - max_ = 0; - array_p_ =0; - return p; + void precompute() { + remax (size_); } + + T * remove_array_p (); /// access element T &operator[] (int i) { - return elem (i); + return elem_ref (i); } /// access element - T const & operator[] (int i) const + T const & operator[] (int i) const { - return elem (i); + return elem_ref (i); } /// access element - T &elem (int i) const + T &elem_ref (int i) const { assert (i >=0&&i slice (int lower, int upper) - { - assert (lower >= 0 && lower <=upper&& upper <= size_); - Array r; - int s =upper-lower; - r.set_size (s); - arrcpy (r.array_p_, array_p_ + lower, s); - return r; - } + Array slice (int lower, int upper) ; void reverse(); }; diff --git a/flower/include/array.icc b/flower/include/array.icc index 0077a01d08..807382880e 100644 --- a/flower/include/array.icc +++ b/flower/include/array.icc @@ -64,3 +64,34 @@ Array::reverse () swap (i,j); } +template INLINE +void +Array::OK() const +{ + assert (max_ >= size_ && size_ >=0); + if (max_) assert (array_p_); +} + +template INLINE +T * +Array::remove_array_p () +{ + T * p = array_p_; + size_ = 0; + max_ = 0; + array_p_ =0; + return p; +} + +template INLINE +Array +Array::slice (int lower, int upper) +{ + assert (lower >= 0 && lower <=upper&& upper <= size_); + Array r; + int s =upper-lower; + r.set_size (s); + arrcpy (r.array_p_, array_p_ + lower, s); + return r; +} + diff --git a/flower/include/link.icc b/flower/include/link.icc index df560285f2..4b3c886aad 100644 --- a/flower/include/link.icc +++ b/flower/include/link.icc @@ -10,11 +10,11 @@ Link::OK() const #ifndef NDEBUG if (previous_) { - assert (previous_->next_ == this); + assert (previous_->next_ == this); } if (next_) { - assert (next_->previous_ == this); + assert (next_->previous_ == this); } #endif } @@ -60,7 +60,7 @@ Link::add (const T& thing) Link* l = new Link(this, next_, thing); if (next_) - next_->previous_ = l; + next_->previous_ = l; next_ = l; } @@ -72,7 +72,7 @@ Link::insert (const T& thing) // bugfix hwn 16/9/96 Link* l = new Link(previous_, this, thing); if (previous_) - previous_->next_ = l; + previous_->next_ = l; previous_ = l; } @@ -84,14 +84,14 @@ inline void Link::remove (List &l) { if (previous_) - previous_->next_ = next_; + previous_->next_ = next_; else - l.top_ = next_; + l.top_ = next_; if (next_) - next_->previous_ = previous_; + next_->previous_ = previous_; else - l.bottom_ = previous_; + l.bottom_ = previous_; } template diff --git a/flower/include/parray.hh b/flower/include/parray.hh index 77a69b519a..79ef5e6a7f 100644 --- a/flower/include/parray.hh +++ b/flower/include/parray.hh @@ -16,10 +16,10 @@ an array of pointers. TODO - should init to 0. Derive from Array? + should init to 0. */ template -class Link_array : public Array +class Link_array : private Array { static default_compare (T *const& p1, T *const&p2) { /* can't do p1 -p2, since T might be an incomplete type */ @@ -29,13 +29,64 @@ class Link_array : public Array return 1; return 0; } + Link_array (Array v) + :Array (v) + { + } public: + Link_array() + {} + Link_array (Link_array const &src) + : Array (src) + { + } + /// access element + T *elem (int i) const + { + return elem_ref (i); + } + T *&elem_ref (int i) const + { + return (T*&) Array::elem_ref (i); + } + + /// access element + T* &operator[] (int i) + { + return (T*&) Array::elem_ref (i); + } + /// access element + T *const operator[] (int i) const + { + return (T *const) Array::elem (i); + } + T *pop () + { + return (T*) Array::pop (); + } + void insert (T *t, int i) + { + Array::insert (t, i); + } + void push (T* t) + { + Array::push (t); + } + /// return last entry + T* top (int j=0) const + { + return (T*) Array::top (j); + } + T *& top (int i=0) + { + return (T*&) Array::top (i); + } void substitute (T *old, T*new_l) { int i; while ((i = find_i (old)) >=0) if (new_l) - elem (i) =new_l; + elem_ref (i) =new_l; else del (i); } @@ -44,7 +95,7 @@ public: int i; while ((i = find_i (old)) >=0) if (new_l) - elem (i) =new_l; + elem_ref (i) =new_l; else { unordered_del (i); } @@ -53,6 +104,10 @@ public: void default_sort() { sort (default_compare); } + // quicksort. + void sort (int (*compare)(T *const&,T *const&), + int lower = -1, int upper = -1); + void uniq() { Link_array l_arr; for (int i=0; i < size(); i++) @@ -60,7 +115,26 @@ public: l_arr.push (elem (i)); *this = l_arr; } - + Array::del; + Array::unordered_del; + Array::size; + Array::clear; + Array::set_size; + Array::empty; + Array::reverse; + T * get (int i) + { + return (T*) Array::get (i); + } + Link_array + slice(int l,int u) + { + return Array::slice (l,u); + } + void concat (Link_array const &a2) + { + Array::concat (a2); + } int find_i (T const * t) const { for (int i=0; i < size(); i++) if (elem (i) == t) @@ -75,6 +149,7 @@ public: else return 0; } + }; template @@ -88,5 +163,27 @@ typecast_array (Link_array const &a, T * /* dummy */ ) } + +template inline void +Link_array::sort (int (*compare)(T *const&,T *const&), + int lower = -1, int upper = -1) +{ + if (lower < 0) + { + lower = 0 ; + upper = size () - 1; + } + if (lower >= upper) + return; + swap (lower, (lower+upper)/2); + int last = lower; + for (int i= lower +1; i <= upper; i++) + if (compare (elem (i), elem(lower)) < 0) + swap (++last,i); + swap (lower, last); + sort (compare, lower, last-1); + sort (compare, last+1, upper); +} + #endif // PARRAY_HH diff --git a/input/bugs/time-grouping.ly b/input/bugs/time-grouping.ly new file mode 100644 index 0000000000..b0cc682d91 --- /dev/null +++ b/input/bugs/time-grouping.ly @@ -0,0 +1,16 @@ +%{ + wierd grouping bug +%} + +\score{ + \notes \relative c''{ + % be sure it's not related to auto-beamer + \property Voice.beamAuto = "0" + \time 1/2; + [ c8 c c c ] + \time 1/4; + [ c8 c ] + } + \paper{ + } +} diff --git a/input/just-friends.ly b/input/just-friends.ly new file mode 100644 index 0000000000..8082c7b83e --- /dev/null +++ b/input/just-friends.ly @@ -0,0 +1,58 @@ +\header { + filename = "just-friends.ly"; + title = "Just Friends"; + description = "Jazz chords example with bar lines"; + opus = ""; + source = "mutex@gmd.de"; + composer = ""; + enteredby = "jcn"; + copyright = "Public Domain"; +} + +%{ +In response to + +Message-Id: <19990206153950.A7474@gil.physik.rwth-aachen.de> +Date: Sat, 6 Feb 1999 15:39:50 +0100 +From: Christoph Kukulies +Subject: chord bars + +I was looking out for a FAQ on the www.gmd.de/Misc/Music page but didn't +find any so bear with me when asking a FAQ question: + +I want to generate some sheets that contain only the chords (changes) +of a certain tune (Jazz, Real Book, for example), like + + Just Friends + +[...] + +%} + +\score{ + \type ChordNames \chords{ + \property Score.chordInversion = 1 + \property Score.barAtLineStart = 1 + \repeat 2 { + f1-maj f-maj f-7 bes-7 + c-maj c-maj es es + d-7 g-7 b2-7/fis e-7 a1-7\break + d-7 d-7 d-7 g2-7 ges-7 + + f1-maj f1-maj f-7 bes-7 + c-maj c-maj es es + d-7 g-7 b2-7/fis e-7 a1-7\break + d-7 d2-7 g-7 c1-6 g2-7 c-7 + } + } + \paper{ + indent = 0.0\mm; + linewidth = 100.0\mm; + \translator{ + \ChordNameContext + barAuto = "1"; + \consists Bar_engraver; + \consists "Repeat_engraver"; + } + } +} diff --git a/input/opus-130.ly b/input/opus-130.ly index 0bb12e66c0..bd01cf52e2 100644 --- a/input/opus-130.ly +++ b/input/opus-130.ly @@ -63,12 +63,6 @@ cello = \notes\relative c'{ > \paper{ \translator { \OrchestralScoreContext } - \translator { - \VoiceContext - \consists Auto_beam_engraver; - beamAuto = 1.; - beamAutoEnd = "3/8"; - } } \midi{ \tempo 4 = 160; } } diff --git a/input/star-spangled-banner.ly b/input/star-spangled-banner.ly index d05c396cfa..f5b05d1e35 100644 --- a/input/star-spangled-banner.ly +++ b/input/star-spangled-banner.ly @@ -114,13 +114,6 @@ global = \notes { \translator { \BarNumberingStaffContext } - \translator{ - \VoiceContext - \consists Auto_beam_engraver; - beamAuto = 1.; - beamAutoEnd8 = "1/4"; - beamAutoEnd16 = "1/4"; - } } } diff --git a/input/test/auto-beam-override.ly b/input/test/auto-beam-override.ly new file mode 100644 index 0000000000..ad378a5837 --- /dev/null +++ b/input/test/auto-beam-override.ly @@ -0,0 +1,38 @@ +%{ + Currently (1.1.27.jcn3), the auto-beam engraver will only engrave + sensible beams, which means that it will end a beam when: + * a rest is encountered + * another beam (entered manually) is encountered + * there's a 'gap' in the beam note's durations + + The beam will be ended also when + + now / beamAutoEnd = 0 +%} + +\score{ + \notes \relative c''{ + \time 2/4; + % one beam per measure + c8 c c c + c16 c c c c c c c + % from here on consider ending beam every 1/4 note + \property Voice.beamAutoEnd = "1/4" + c8 c c c + % manually override autobeam with weird beaming + c8 [c c] c + c8 c c r + c8 c c4 + r8 c c c + % no autobeaming + \property Voice.beamAuto = "0" + c8 c c c + } + \paper{ + \translator{ + \VoiceContext + % consider ending beam at every 1/2 note + beamAutoEnd = "1/2"; + } + } +} diff --git a/input/test/auto-beam.ly b/input/test/auto-beam.ly index 02e7711dba..6839be6600 100644 --- a/input/test/auto-beam.ly +++ b/input/test/auto-beam.ly @@ -1,49 +1,62 @@ %{ - Currently (1.1.22.jcn5), the auto-beam engraver will only engrave - sensible beams (hopefully), which means that it will give up the - whole beam if: - * a rest is encountered - * another beam (entered manually) is encountered - * there's a 'gap' in the beam note's durations - - There's no smart algorithm, beginning a beam is considered when - - now / beamAutoBegin = 0 - - the beam will be ended when - - * now / beamAutoEnd = 0 + The auto-beam engraver has presets for common time signatures. %} - + \score{ \notes \relative c''{ - \time 2/4; - % one beam per measure - c8 c c c - c16 c c c c c c c - % from here on two beams per measure - \property Voice.beamAutoEnd = "1/4"; - c8 c c c - % manually override autobeam with weird beaming - c8 [c c] c - c8 c c r - c8 c c4 - r8 c c c - % no autobeaming - \property Voice.beamAuto = "0" - c8 c c c +%{ + % urg: something breaks in grouping ; see input/bugs/time-grouping.ly + \time 1/2; + c8 c c c + c16 c c c c c c c + c32 c c c c c c c c c c c c c c c + \time 1/4; + c8 c + c16 c c c + c32 c c c c c c c + \time 1/8; + c8 + c16 c + c32 c c c +%} + \time 2/2; + c8 c c c c c c c + c16 c c c c c c c c c c c c c c c + c32 c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c + \time 2/4; + c8 c c c + c16 c c c c c c c + c32 c c c c c c c c c c c c c c c + \time 2/8; + c8 c + c16 c c c + c32 c c c c c c c + \time 3/2; + c8 c c c c c c c c c c c + c16 c c c c c c c c c c c c c c c c c c c c c c c + \time 3/4; + c8 c c c c c + c16 c c c c c c c c c c c + c32 c c c c c c c c c c c c c c c c c c c c c c c + \time 3/8; + c8 c c + c16 c c c c c + c32 c c c c c c c c c c c + \time 4/4; + c8 c c c c c c c + c16 c c c c c c c c c c c c c c c + c32 c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c + \time 4/8; + c8 c c c + c16 c c c c c c c + c32 c c c c c c c c c c c c c c c + \time 6/8; + c8 c c c c c + c16 c c c c c c c c c c c + \time 9/8; + c8 c c c c c c c c + c16 c c c c c c c c c c c c c c c c c } \paper{ - \translator{ - \VoiceContext - % add experimental auto-beaming - \consists Auto_beam_engraver; - % switch it on (perhaps a bit double, but we want to be able - % to switch it off conveniently - beamAuto = 1.; - % consider starting beam at every 4 note - % beamAutoBegin = "1/4"; - beamAutoEnd = "1/2"; - } } } diff --git a/input/test/chord-inversion.ly b/input/test/chord-inversion.ly index 543502d4a0..2e06840c5e 100644 --- a/input/test/chord-inversion.ly +++ b/input/test/chord-inversion.ly @@ -9,9 +9,8 @@ inversions = \notes\transpose c''\chords{ c1 c-sus c-6 c/e c/g c/d % now try to find chords with inversions \property Score.chordInversion = 1 - \property Score.chordInversionPreserve = 1 c1 c-sus c-6 - c/e % c/e is not found because preserving doesn't work fully yet... + c/e c/g c/d % this triggers a warning: no 'd' in chord of c } diff --git a/input/test/chord-table.ly b/input/test/chord-table.ly index 14c758c52e..98174f1cf7 100644 --- a/input/test/chord-table.ly +++ b/input/test/chord-table.ly @@ -5,7 +5,7 @@ enteredby = "jcn"; } tab = \notes\transpose c'''\chords{ - c1 c-m c-4 c-m4 c-5+ c-5- c-m5- c-5.5+ c-6\break %c-m6\break + c1 c-m c-4 c-m4 c-5+ c-5- c-m5- c-5-.5+ c-6\break %c-m6\break } \score{ diff --git a/input/test/coda-kludge.ly b/input/test/coda-kludge.ly new file mode 100644 index 0000000000..982a815aa8 --- /dev/null +++ b/input/test/coda-kludge.ly @@ -0,0 +1,52 @@ +%{ +Hi, + I want to write some music that has the structure: + + Intro + \repeat 4 { Chorus [first-ending] verse } + fifth-ending final + + The obvious: + + \repeat 4 { Chorus \alternative{{first-ending}{}} verse} + \alternative{{}{fifth-ending}} + final + + doesn't work. + + And the (logically correct but ugly) + + \repeat 4 {Chorus} + \alternative {{first-ending verse}{fifth ending}} + final + + is very ugly, because the volta bracket keeps going for so + long. + + Peter C +%} + +\score{ + < + \type Staff \notes\relative c''{ + c c c c + % coda-klugde: let volta span only one bar + \property Staff.voltaSpannerDuration = "1" + \repeat 5 { d d d d } + \alternative { { e e e e f f f f } + { g g g g } } + } + \type Lyrics \lyrics{ + intro1 + \repeat 5 {} + \alternative < + { chorus1 one verse1 } + { chorus1 two verse1 } + { chorus1 three verse } + { chorus1 four verse } + > + five1 + } + > +} + diff --git a/input/test/ly2dvi-testpage.ly b/input/test/ly2dvi-testpage.ly new file mode 100644 index 0000000000..ba3e51f172 --- /dev/null +++ b/input/test/ly2dvi-testpage.ly @@ -0,0 +1,40 @@ + +%{ + Test ly2dvi features. +%} + +\header { +copyright = "copyright"; +title = "title"; +subtitle = "subtitle"; +composer = "composer"; +arranger = "arranger"; +instrument = "instrument"; +metre = "metre"; +opus = "opus"; +piece = "piece"; +poet = "poet"; +} + + +\score { + \notes { c1 c1 c1 c1 } +} + +\score { + \notes { c1 c1 c1 c1 } + + \header { + + title = "localtitle"; + subtitle = "localsubtitle"; + composer = "localcomposer"; + arranger = "localarranger"; + instrument = "localinstrument"; + metre = "localmetre"; + opus = "localopus"; + piece = "localpiece"; + poet = "localpoet"; + copyright = "localcopyright"; + } +} diff --git a/input/test/rep.ly b/input/test/rep.ly index 2b79795ecc..1275606bb0 100644 --- a/input/test/rep.ly +++ b/input/test/rep.ly @@ -2,7 +2,7 @@ < \type Staff \notes\relative c'{ c4 d e f - \repeat 2 { g a b c } + \repeat 3 { g a b c } % \alternative { { c b a g } { f e d c } } c c c c \alternative { { c b a g } { f e d c } { c d e f } } g g g g diff --git a/input/test/span-bars.ly b/input/test/span-bars.ly new file mode 100644 index 0000000000..5c7fb2c324 --- /dev/null +++ b/input/test/span-bars.ly @@ -0,0 +1,23 @@ + +\version "1.0.14"; +nt = \notes { c1 \break c1 c1 } +stuff = \notes \relative c'' < + \type Staff = stone { \nt } + \type Staff = sttwo { \nt } +> + +\score{ + \type StaffGroup \stuff +} + +\score{ + \type StaffGroup < \type GrandStaff \stuff + \type Staff = stthree \nt + > +} + +\score{ + \type ChoirStaff \stuff +} + + diff --git a/lib/duration-convert.cc b/lib/duration-convert.cc index c1240f3cdd..4f2e2a9015 100644 --- a/lib/duration-convert.cc +++ b/lib/duration-convert.cc @@ -105,14 +105,14 @@ Duration_convert::mom2_dur (Moment mom) Duration dur = mom2standardised_dur (mom); // if (!dur.mom () || (dur.mom () == mom)) - if (!dur.length () || (dur.length () == mom)) + if (!dur.length_mom () || (dur.length_mom () == mom)) return dur; assert (midi_as_plet_b_s); // dur.set_plet (type_mom, Duration::division_1_i_s / 4); // Moment as_plet_mom = mom / dur.mom (); - Moment as_plet_mom = mom / dur.length (); + Moment as_plet_mom = mom / dur.length_mom (); as_plet_mom *= dur.plet_.mom (); long num = as_plet_mom.num (); long den = as_plet_mom.den (); @@ -185,7 +185,7 @@ Duration_convert::ticks2_dur (int ticks_i) Duration dur = mom2standardised_dur (mom); - if (dur.length () == mom) + if (dur.length_mom () == mom) return dur; return mom2_dur (mom); diff --git a/lib/duration.cc b/lib/duration.cc index f65348ae6d..8e254ba0f2 100644 --- a/lib/duration.cc +++ b/lib/duration.cc @@ -45,10 +45,8 @@ Duration::compress (Moment m) plet_.type_i_ *= m.den_i (); } -// ugh, what's this? -// i should be called "mom ()", ... or at least "length_mom ()" Moment -Duration::length () const +Duration::length_mom () const { return Duration_convert::dur2_mom (*this); } diff --git a/lib/include/duration.hh b/lib/include/duration.hh index 509a6d69d9..1ece5771d8 100644 --- a/lib/include/duration.hh +++ b/lib/include/duration.hh @@ -31,7 +31,7 @@ struct Duration { static bool duration_type_b (int t); void set_ticks (int ticks_i ); - Moment length () const ; // zo naai mij + Moment length_mom () const ; static int division_1_i_s; /// Logarithm of the base duration. diff --git a/lily/GNUmakefile b/lily/GNUmakefile index c61ab3e81e..1de3dc99c2 100644 --- a/lily/GNUmakefile +++ b/lily/GNUmakefile @@ -8,6 +8,9 @@ SUBDIRS = include MODULE_LIBS=$(depth)/lib $(depth)/flower MODULE_INCLUDES=$(depth)/lib/include $(depth)/flower/include +MODULE_CXXFLAGS= + + STEPMAKE_TEMPLATES= c++ executable po diff --git a/lily/abbrev.cc b/lily/abbrev.cc index 04eb7dec72..af2849d91a 100644 --- a/lily/abbrev.cc +++ b/lily/abbrev.cc @@ -13,6 +13,7 @@ #include "paper-def.hh" #include "lookup.hh" #include "stem.hh" +#include "offset.hh" Abbreviation::Abbreviation () { @@ -44,15 +45,15 @@ Abbreviation::do_brew_molecule_p () const } Real sl = slope_f * internote_f; - Atom a (lookup_l ()->beam (sl, w, beam_f)); + Molecule a (lookup_l ()->beam (sl, w, beam_f)); a.translate (Offset (-w/2, w / 2 * slope_f)); Molecule *beams= new Molecule; for (int i = 0; i < abbrev_flags_i_; i++) { - Atom b (a); + Molecule b (a); b.translate_axis (interbeam_f * i, Y_AXIS); - beams->add_atom (b); + beams->add_molecule (b); } beams->translate_axis (-beams->extent ()[Y_AXIS].center (), Y_AXIS); diff --git a/lily/abbreviation-beam.cc b/lily/abbreviation-beam.cc index 94aa9f4d08..c2e2650da2 100644 --- a/lily/abbreviation-beam.cc +++ b/lily/abbreviation-beam.cc @@ -13,7 +13,7 @@ #include "abbreviation-beam.hh" #include "misc.hh" #include "debug.hh" -#include "atom.hh" + #include "molecule.hh" #include "leastsquares.hh" #include "stem.hh" diff --git a/lily/atom.cc b/lily/atom.cc index 0d71f4e240..119f2315ff 100644 --- a/lily/atom.cc +++ b/lily/atom.cc @@ -14,109 +14,101 @@ #include "dimensions.hh" #include "lookup.hh" #include "main.hh" +#include "global-ctor.hh" -inline bool -Atom::check_infinity_b ()const +Atom::Atom(SCM s) { - bool ridiculous = false; - -#ifndef NDEBUG - /* infinity checks. */ - for (int a = X_AXIS; a < NO_AXES; a++) - { - Axis ax = (Axis)a; - if (abs (off_[ax]) >= 100 CM) - { - warning (_f ("ridiculous dimension: %s, %s", axis_name_str (ax), - print_dimen (off_[ax]))); - - if (experimental_features_global_b) - assert (false); - - ( (Atom*)this)->off_[ax] = 0.0; - ridiculous = true; - } - } -#endif - return ridiculous; + func_ = s; } -void -Atom::print () const +#if 0 +int +Atom::smob_display (SCM smob, SCM port, scm_print_state*) { -#ifndef NPRINT - DOUT << "string: " << str_ << '\n'; - - DOUT << "dim:"; - for (Axis i=X_AXIS; i < NO_AXES; incr (i)) - DOUT << axis_name_str (i) << " = " << dim_[i].str (); + Atom* a =(Atom*) SCM_CDR(smob); + String i (a->off_.str ()); + + scm_puts ("#func_); + scm_puts (">", port); - DOUT << "\noffset: " << off_.str (); -#endif + /* non-zero means success */ + return 1; } -Box -Atom::extent () const + +scm_sizet +Atom::smob_free (SCM smob) { - Box b (dim_); - b.translate (off_); - return b; + Atom * a= (Atom*) SCM_CDR(smob); + delete a; + return sizeof (Atom); } -Interval -Atom::extent (Axis a) const +SCM +Atom::smob_mark (SCM smob) { - return dim_[a] + off_[a]; + Atom * a= (Atom*) SCM_CDR(smob); + scm_gc_mark (a->func_); + return a->font_; } +long Atom::smob_tag_; - -Atom::Atom () - : dim_ (Interval (0,0),Interval (0,0)) +void +Atom::init_smob () { - str_ = "unknown\n"; - origin_l_ = 0; -} + static scm_smobfuns type_rec; -Atom::Atom (String s, Box b) - : dim_ (b) -{ - str_ = s; - origin_l_ = 0; + type_rec.mark = smob_mark; + type_rec.free = smob_free; + type_rec.print = smob_display; + type_rec.equalp = 0; + + smob_tag_ = scm_newsmob (&type_rec); } -String -Atom::str () const +SCM +Atom::make_smob () const { - return String ("Atom (\'") + str_ + "\', (" + dim_.x ().str () + ", " - + dim_.y ().str () + "))"; + SCM smob; + SCM_NEWCELL (smob); + SCM_SETCAR (smob, smob_tag_); + SCM_SETCDR (smob, this); + return smob; } -Offset -Atom::offset () const +SCM +Atom::make_atom (SCM outputfunc) { - check_infinity_b (); - return off_; + Atom * a= new Atom(outputfunc); + return a->make_smob (); } -void -Atom::translate_axis (Real r, Axis a) +SCM +Atom::copy_self () const { - off_[a] += r; - check_infinity_b (); + return (new Atom (*this))->make_smob (); } -void -Atom::translate (Offset o) +bool +Atom::Atom_b (SCM obj) { - off_ += o; - check_infinity_b (); + return(SCM_NIMP(obj) && SCM_CAR(obj) == smob_tag_); } -bool -Atom::empty() const +Atom* +Atom::atom_l (SCM a) { - return (dim_.y().length() == 0); + assert (Atom_b (a)); + return (Atom*) SCM_CDR(a); } + + +ADD_GLOBAL_CTOR_WITHNAME(atomsmob, Atom::init_smob); +#endif + + diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 23698891e4..2ce8813b6d 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -11,7 +11,7 @@ #include "musical-request.hh" #include "bar.hh" #include "beam.hh" -#include "grouping.hh" +#include "rhythmic-grouping.hh" #include "rest.hh" #include "stem.hh" #include "debug.hh" @@ -22,6 +22,7 @@ ADD_THIS_TRANSLATOR (Auto_beam_engraver); Auto_beam_engraver::Auto_beam_engraver () { beam_p_ = 0; + mult_i_ = 0; finished_beam_p_ = 0; finished_grouping_p_ = 0; grouping_p_ = 0; @@ -37,22 +38,92 @@ void Auto_beam_engraver::consider_end_and_begin () { Time_description const *time = get_staff_info().time_C_; + int num = time->whole_per_measure_ / time->one_beat_; + int den = time->one_beat_.den_i (); + String time_str = String ("time") + to_str (num) + "_" + to_str (den); + int type = 1 << (mult_i_ + 2); + String type_str = to_str (type); + + /* + Determine end moment for auto beaming (and begin, mostly 0==anywhere) + In order of increasing priority: + + i. every beat + ii. time_beamAutoEnd + iii. time_beamAutoEnd + iv. beamAutoEnd + v. beamAutoEnd + + + Rationale: + + [to be defined in config file] + i. easy catch-all rule + ii. exceptions for time signature + iii. exceptions for time signature, for specific duration type - Scalar begin = get_property ("beamAutoBegin", 0); - Moment begin_mom = begin.to_rat (); + [user override] + iv. generic override + v. override for specific duration type + + The user overrides should be required for common cases. + */ - Scalar end = get_property ("beamAutoEnd", 0); - Moment end_mom = end.to_rat (); + /* + first guess: begin beam at any position + */ + Moment begin_mom (0); + /* + first guess: end beam at end of beat + */ + Moment end_mom = time->one_beat_; + + /* + second guess: property generic time exception + */ + Scalar begin = get_property (time_str + "beamAutoBegin", 0); + if (begin.length_i ()) + begin_mom = begin.to_rat (); + Scalar end = get_property (time_str + "beamAutoEnd", 0); + if (end.length_i ()) + end_mom = end.to_rat (); + + /* + third guess: property time exception, specific for duration type + */ + if (mult_i_) + { + Scalar end_mult = get_property (time_str + "beamAutoEnd" + type_str, 0); + if (end_mult.length_i ()) + end_mom = end_mult.to_rat (); + Scalar begin_mult = get_property (time_str + "beamAutoBegin" + type_str, 0); + if (begin_mult.length_i ()) + begin_mom = begin_mult.to_rat (); + } + + /* + fourth guess [user override]: property plain generic + */ + begin = get_property ("beamAutoBegin", 0); + if (begin.length_i ()) + begin_mom = begin.to_rat (); + + end = get_property ("beamAutoEnd", 0); + if (end.length_i ()) + end_mom = end.to_rat (); + + /* + fifth guess [user override]: property plain, specific for duration type + */ if (mult_i_) { - int type = 1 << (mult_i_ + 2); - Scalar end_mult = get_property (String ("beamAutoEnd") - + to_str (type), 0); + Scalar end_mult = get_property (String ("beamAutoEnd") + type_str, 0); if (end_mult.length_i ()) end_mom = end_mult.to_rat (); - else if (Moment (type, 4) / end_mom > Moment (4)) - end_mom /= Moment (type, 8); + Scalar begin_mult = get_property (String ("beamAutoBegin") + type_str, 0); + if (begin_mult.length_i ()) + begin_mom = begin_mult.to_rat (); } Real f; @@ -83,7 +154,7 @@ Auto_beam_engraver::consider_end_and_begin () void Auto_beam_engraver::begin_beam () { - DOUT << String ("starting autobeam at: ") + now_moment ().str () + "\n"; + DOUT << String ("starting autobeam at: ") + now_mom ().str () + "\n"; beam_p_ = new Beam; grouping_p_ = new Rhythmic_grouping; @@ -112,7 +183,7 @@ Auto_beam_engraver::begin_beam () void Auto_beam_engraver::end_beam () { - DOUT << String ("ending autobeam at: ") + now_moment ().str () + "\n"; + DOUT << String ("ending autobeam at: ") + now_mom ().str () + "\n"; if (beam_p_->stems_.size () < 2) { DOUT << "junking autombeam: less than two stems\n"; @@ -241,12 +312,12 @@ Auto_beam_engraver::acknowledge_element (Score_element_info info) consider_end_and_begin (); } mult_i_ = m; - grouping_p_->add_child (start, rhythmic_req->duration ()); + grouping_p_->add_child (start, rhythmic_req->length_mom ()); stem_l->flag_i_ = rhythmic_req->duration_.durlog_i_; beam_p_->add_stem (stem_l); - Moment now = now_moment (); + Moment now = now_mom (); last_add_mom_ = now; - extend_mom_ = extend_mom_ >? now + rhythmic_req->duration (); + extend_mom_ = extend_mom_ >? now + rhythmic_req->length_mom (); } } } @@ -276,7 +347,7 @@ Auto_beam_engraver::process_acknowledged () { if (beam_p_) { - Moment now = now_moment (); + Moment now = now_mom (); if ((extend_mom_ < now) || ((extend_mom_ == now) && (last_add_mom_ != now ))) { diff --git a/lily/bar-engraver.cc b/lily/bar-engraver.cc index 57436ae70f..5d3993f232 100644 --- a/lily/bar-engraver.cc +++ b/lily/bar-engraver.cc @@ -61,6 +61,11 @@ Bar_engraver::create_bar () { bar_p_->type_str_ = default_type; } + Scalar prop = get_property ("barAtLineStart", 0); + if (prop.to_bool ()) + { + bar_p_->at_line_start_b_ = true; + } announce_element (Score_element_info (bar_p_, bar_req_l_)); } } @@ -68,6 +73,13 @@ Bar_engraver::create_bar () void Bar_engraver::request_bar (String type_str) { + Scalar prop = get_property ("barAtLineStart", 0); + if (!now_mom ()) + { + Scalar prop = get_property ("barAtLineStart", 0); + if (!prop.to_bool ()) + return; + } create_bar (); if (((type_str == "|:") && (bar_p_->type_str_ == ":|")) || ((type_str == ":|") && (bar_p_->type_str_ == "|:"))) @@ -104,10 +116,10 @@ Bar_engraver::do_process_requests() create_bar (); bar_p_->type_str_ = bar_req_l_->type_str_; } - else if (!now_moment ()) + else if (!now_mom ()) { create_bar (); - bar_p_->type_str_ = ""; + bar_p_->type_str_ = "|"; } else { diff --git a/lily/bar-number-engraver.cc b/lily/bar-number-engraver.cc index 7adc8dcdea..433e82126e 100644 --- a/lily/bar-number-engraver.cc +++ b/lily/bar-number-engraver.cc @@ -18,7 +18,7 @@ Bar_number_engraver::Bar_number_engraver() axis_ = Y_AXIS; type_ = "barNumber"; visibility_lambda_ - = gh_eval_str ("(lambda (d) (if (= d 1) '(#f . #f) '(#t . #t)))"); + = gh_eval_str ("postbreak_only_visibility"); } void @@ -28,7 +28,7 @@ Bar_number_engraver::do_process_requests () Timing_translator *timer = dynamic_cast(tr); Time_description *time = &timer->time_; - if (!time->whole_in_measure_ && !time->cadenza_b_ && now_moment () > Moment (0)) + if (!time->whole_in_measure_ && !time->cadenza_b_ && now_mom () > Moment (0)) { create_items (0); diff --git a/lily/bar-script-engraver.cc b/lily/bar-script-engraver.cc index cf741641df..e197da6a9c 100644 --- a/lily/bar-script-engraver.cc +++ b/lily/bar-script-engraver.cc @@ -19,7 +19,7 @@ Bar_script_engraver::Bar_script_engraver () staff_side_p_ = 0; text_p_ =0; visibility_lambda_ - = gh_eval_str ("(lambda (d) (if (= d -1) '(#t . #t) '(#f . #f)))"); + = gh_eval_str ("non_postbreak_visibility"); } void diff --git a/lily/bar.cc b/lily/bar.cc index 824e2316a1..0bb7365076 100644 --- a/lily/bar.cc +++ b/lily/bar.cc @@ -18,6 +18,7 @@ Bar::Bar () { breakable_b_ = true; type_str_ = "|"; + at_line_start_b_ = false; } void @@ -50,6 +51,9 @@ static char const *bar_breaks[][3] ={ {":|", ":|", ""}, {"||", "||", ""}, {".|.", ".|.", ""}, + {"", "scorebar", "|"}, + {"", "{", "{"}, + {"", "[", "["}, {0,0,0} }; @@ -59,7 +63,13 @@ Bar::do_pre_processing () for (int i=0; bar_breaks[i][0]; i++) { if (bar_breaks[i][1] == type_str_) - type_str_ = bar_breaks[i][break_status_dir ()+1]; + { + type_str_ = bar_breaks[i][break_status_dir ()+1]; + if (at_line_start_b_ && (break_status_dir_ == 1) && (type_str_ == "")) + { + type_str_ = "|"; + } + } } /* diff --git a/lily/base-span-bar-engraver.cc b/lily/base-span-bar-engraver.cc new file mode 100644 index 0000000000..1f90617969 --- /dev/null +++ b/lily/base-span-bar-engraver.cc @@ -0,0 +1,91 @@ +/* + span-bar-grav.cc -- implement Base_span_bar_engraver + + source file of the GNU LilyPond music typesetter + + (c) 1997--1998 Han-Wen Nienhuys +*/ + +#include "span-bar.hh" +#include "base-span-bar-engraver.hh" +#include "vertical-align-spanner.hh" + +Base_span_bar_engraver::Base_span_bar_engraver() +{ + spanbar_p_ =0; + valign_l_ =0; + use_priority_b_ = true; + break_priority_i_ = 0; +} + +Span_bar* +Base_span_bar_engraver::get_span_bar_p() const +{ + return new Span_bar; +} + + +void +Base_span_bar_engraver::acknowledge_element (Score_element_info i) +{ + int depth = i.origin_grav_l_arr_.size(); + if (depth > 1 + && dynamic_cast (i.elem_l_)) + { + bar_l_arr_.push (dynamic_cast (i.elem_l_)); + + if (bar_l_arr_.size() >= 2 && !spanbar_p_) + /* + hmm, i do want a bracket with one staff some times, but not always + if (bar_l_arr_.size() >= 1 && !spanbar_p_) + + --jcn + */ + + /* + + use a property? get_property ("singleStaffBracket", 0) ? + + --hwn + */ + { + spanbar_p_ = get_span_bar_p(); + + if (use_priority_b_) + { + spanbar_p_->break_priority_i_ = break_priority_i_; + } + else + { + spanbar_p_->dim_cache_[X_AXIS].parent_l_ = &bar_l_arr_[0]->dim_cache_[X_AXIS]; + } + + announce_element (Score_element_info (spanbar_p_,0)); + if (spanbar_p_->type_str_.empty_b ()) + spanbar_p_-> type_str_ = bar_l_arr_[0]->type_str_; + } + } + else if (dynamic_cast (i.elem_l_) + && i.origin_grav_l_arr_.size() <= 2) + { + valign_l_ = dynamic_cast (i.elem_l_); + } +} + +void +Base_span_bar_engraver::do_pre_move_processing() +{ + if (spanbar_p_) + { + for (int i=0; i < bar_l_arr_.size() ; i++) + spanbar_p_->add_bar (bar_l_arr_[i]); + spanbar_p_->set_align (valign_l_); + typeset_element (spanbar_p_); + spanbar_p_ =0; + } + bar_l_arr_.set_size (0); +} + + + +ADD_THIS_TRANSLATOR(Base_span_bar_engraver); diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index ac7a02a26b..4bd2e9e591 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -10,7 +10,7 @@ #include "beam-engraver.hh" #include "musical-request.hh" #include "beam.hh" -#include "grouping.hh" +#include "rhythmic-grouping.hh" #include "stem.hh" #include "warn.hh" #include "time-description.hh" @@ -22,6 +22,7 @@ Beam_engraver::Beam_engraver () finished_grouping_p_ = 0; grouping_p_ =0; reqs_drul_[LEFT] = reqs_drul_[RIGHT] =0; + prev_start_req_ =0; } bool @@ -50,6 +51,7 @@ Beam_engraver::do_process_requests () { if (!beam_p_) reqs_drul_[STOP]->warning (_("No beam to end")); + prev_start_req_ =0; finished_beam_p_ = beam_p_; finished_grouping_p_ = grouping_p_; @@ -111,7 +113,11 @@ Beam_engraver::typeset_beam () void Beam_engraver::do_post_move_processing () { - reqs_drul_ [START] =0; + if (reqs_drul_[START]) + { + prev_start_req_ = reqs_drul_[START]; + reqs_drul_ [START] =0; + } } void @@ -126,7 +132,7 @@ Beam_engraver::do_removal_processing () typeset_beam (); if (beam_p_) { - warning (_ ("Unfinished beam")); + prev_start_req_->warning (_ ("Unfinished beam")); finished_beam_p_ = beam_p_; finished_grouping_p_ = grouping_p_; typeset_beam (); @@ -171,7 +177,7 @@ Beam_engraver::acknowledge_element (Score_element_info info) if (!grouping_p_->child_fit_b (start)) { String s (_ ("please fix me") + ": " - + _f ("stem at %s doesn't fit in beam", now_moment ().str ())); + + _f ("stem at %s doesn't fit in beam", now_mom ().str ())); if (info.req_l_) info.req_l_->warning(s); @@ -180,7 +186,7 @@ Beam_engraver::acknowledge_element (Score_element_info info) } else { - grouping_p_->add_child (start, rhythmic_req->duration ()); + grouping_p_->add_child (start, rhythmic_req->length_mom ()); stem_l->flag_i_ = rhythmic_req->duration_.durlog_i_; beam_p_->add_stem (stem_l); } diff --git a/lily/beam.cc b/lily/beam.cc index 90476e1e9f..094ca9f855 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -26,13 +26,13 @@ #include "abbreviation-beam.hh" #include "misc.hh" #include "debug.hh" -#include "atom.hh" + #include "molecule.hh" #include "leastsquares.hh" #include "stem.hh" #include "paper-def.hh" #include "lookup.hh" -#include "grouping.hh" +#include "rhythmic-grouping.hh" Beam::Beam () { @@ -629,15 +629,15 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const */ Real w = here->hpos_f () - prev->hpos_f (); w = w/2 beam (sl, w, beam_f); a.translate (Offset (-w, -w * sl)); for (int j = 0; j < lhalfs; j++) { - Atom b (a); + Molecule b (a); b.translate_axis (-dir_ * dy * (lwholebeams+j), Y_AXIS); - leftbeams.add_atom (b); + leftbeams.add_molecule (b); } } @@ -647,7 +647,7 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const int rwholebeams = here->beams_i_drul_[RIGHT] beams_i_drul_[LEFT]; Real w = next->hpos_f () - here->hpos_f (); - Atom a = lookup_l ()->beam (sl, w + stemdx, beam_f); + Molecule a = lookup_l ()->beam (sl, w + stemdx, beam_f); a.translate_axis( - stemdx/2, X_AXIS); int j = 0; Real gap_f = 0; @@ -656,9 +656,9 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const int nogap = rwholebeams - here->beam_gap_i_; for (; j < nogap; j++) { - Atom b (a); + Molecule b (a); b.translate_axis (-dir_ * dy * j, Y_AXIS); - rightbeams.add_atom (b); + rightbeams.add_molecule (b); } // TODO: notehead widths differ for different types gap_f = nw_f / 2; @@ -668,9 +668,9 @@ Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const for (; j < rwholebeams; j++) { - Atom b (a); + Molecule b (a); b.translate (Offset (gap_f, -dir_ * dy * j)); - rightbeams.add_atom (b); + rightbeams.add_molecule (b); } w = w/2 get_var ("slur_thickness"); Array c = get_controls (); Real dy = c[3].y () - c[0].y (); - Atom a; + Molecule a; if (!dash_i_) a = lookup_l ()->slur (c); @@ -56,7 +56,7 @@ Bow::do_brew_molecule_p () const a.translate (Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT])); Molecule* mol_p = new Molecule; - mol_p->add_atom (a); + mol_p->add_molecule (a); mol_p->translate_axis (-interstaff_f_, Y_AXIS); return mol_p; diff --git a/lily/boxes.cc b/lily/boxes.cc index 92c8fa6c5a..af9d230e0b 100644 --- a/lily/boxes.cc +++ b/lily/boxes.cc @@ -30,6 +30,13 @@ Box::Box() { } +void +Box::set_empty () +{ + interval_a_[X_AXIS].set_empty (); + interval_a_[Y_AXIS].set_empty (); +} + Box::Box (Interval ix, Interval iy) { x() = ix; diff --git a/lily/break.cc b/lily/break.cc index f6c374dce5..dd88023ec6 100644 --- a/lily/break.cc +++ b/lily/break.cc @@ -103,7 +103,8 @@ Break_algorithm::find_breaks () const Line_spacer* Break_algorithm::generate_spacing_problem (Line_of_cols curline, Interval line) const { - Spring_spacer * sp= (Spring_spacer*) (*get_line_spacer) (); // ugh + // ugh + Spring_spacer * sp= dynamic_cast ((*get_line_spacer) ()); sp->paper_l_ = pscore_l_->paper_l_; sp->add_column (curline[0], true, line[LEFT]); @@ -146,7 +147,7 @@ Break_algorithm::feasible (Line_of_cols curline) const for (int i=0; i < curline.size (); i++) { if (i && i < curline.size () -1 - && (((Score_column*)curline[i])->break_penalty_i () >= Break_req::FORCE)) + && ((dynamic_cast(curline[i]))->break_penalty_i () >= Break_req::FORCE)) return false; } return true; diff --git a/lily/change-iterator.cc b/lily/change-iterator.cc index 81352999e6..028d19f69f 100644 --- a/lily/change-iterator.cc +++ b/lily/change-iterator.cc @@ -15,8 +15,9 @@ void Change_iterator::error (String reason) { - String to_type = change_l ()->change_to_type_str_; - String to_id = change_l ()->change_to_id_str_; + Change_translator const * t = dynamic_cast (music_l_); + String to_type = t->change_to_type_str_; + String to_id = t->change_to_id_str_; String warn1 = _f ("can't change `%s\' to `%s\'", to_type, to_id) + ": " + reason; @@ -24,13 +25,7 @@ Change_iterator::error (String reason) + report_to_l ()->type_str_ + " = `" + report_to_l ()->id_str_ + "\': "; warning (warn2); - change_l ()->warning (warn1); -} - -Change_translator * -Change_iterator::change_l () -{ - return (Change_translator*) music_l_; + t->warning (warn1); } /* @@ -42,8 +37,9 @@ Change_iterator::do_process_and_next (Moment m) Translator_group * current = report_to_l (); Translator_group * last = 0; - String to_type = change_l ()->change_to_type_str_; - String to_id = change_l ()->change_to_id_str_; + Change_translator const * t = dynamic_cast (music_l_); + String to_type = t->change_to_type_str_; + String to_id = t->change_to_id_str_; /* find the type of translator that we're changing. diff --git a/lily/chord-name-engraver.cc b/lily/chord-name-engraver.cc index 336eacb3ed..95784a44bc 100644 --- a/lily/chord-name-engraver.cc +++ b/lily/chord-name-engraver.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1998 Jan Nieuwenhuizen + (c) 1998, 1999 Jan Nieuwenhuizen */ #include "chord-name-engraver.hh" @@ -20,6 +20,7 @@ ADD_THIS_TRANSLATOR (Chord_name_engraver); Chord_name_engraver::Chord_name_engraver () { + tonic_req_ = 0; } void @@ -37,6 +38,11 @@ Chord_name_engraver::do_try_music (Music* m) pitch_arr_.push (n->pitch_); return true; } + if (Tonic_req* t = dynamic_cast (m)) + { + tonic_req_ = t; + return true; + } return false; } @@ -48,37 +54,33 @@ Chord_name_engraver::do_process_requests () if (!pitch_arr_.size ()) return; - /* - Banter style chord names (almost). - TODO: - - move this stuff to new Item class Chord_name - - switch on property, add american (?) chordNameStyle - - Scalar chordNameStyle = get_property ("chordNameStyle", 0); - if (chordNameStyle == "Banter") - chord = pitches_to_banter (pitch_arr_)); - - */ - Chord chord (pitch_arr_); Musical_pitch* inversion = 0; Scalar chord_inversion = get_property ("chordInversion", 0); if (chord_inversion.to_bool ()) { - int tonic_i = chord.find_tonic_i (); + int tonic_i = tonic_req_ + ? chord.find_notename_i (tonic_req_->pitch_) : chord.find_tonic_i (); + if (tonic_i) { inversion = &pitch_arr_[0]; - Scalar preserve = get_property ("chordInversionPreserve", 0); - if (preserve.to_bool ()) - chord.rebuild_from_base (tonic_i); - else - chord.rebuild_insert_inversion (tonic_i); + chord.rebuild_insert_inversion (tonic_i); } } G_text_item* item_p = new G_text_item; + /* + TODO: + - switch on property, add american (?) chordNameStyle: + Chord::american_str (...) + + Scalar chordNameStyle = get_property ("chordNameStyle", 0); + if (chordNameStyle == "Banter") + item_p->text_str_ = chord.banter_str (inversion); + */ + item_p->text_str_ = chord.banter_str (inversion); Scalar style = get_property ("textstyle", 0); @@ -98,4 +100,5 @@ Chord_name_engraver::do_pre_move_processing () } text_p_arr_.clear (); pitch_arr_.clear (); + tonic_req_ = 0; } diff --git a/lily/chord.cc b/lily/chord.cc index 26ae4ce271..c85ea0610a 100644 --- a/lily/chord.cc +++ b/lily/chord.cc @@ -9,57 +9,71 @@ #include "chord.hh" #include "warn.hh" +// doesn't seem common, and we should know about this during purple hit +// #define INVERSION_ADDED_AS_BASE 1 + Chord::Chord (Array pitch_arr) { pitch_arr_ = pitch_arr; } -// construct from parser output -// urg: should split this up into understandable chunks -Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p) +static void +rebuild_transpose (Musical_pitch tonic, Array* pitch_arr_p) { - for (int i = 0; i < add_arr_p->size (); i++) + for (int i = 0; i < pitch_arr_p->size (); i++) { Musical_pitch p = tonic; - Musical_pitch q = (*add_arr_p)[i]; + Musical_pitch q = (*pitch_arr_p)[i]; // duh, c7 should mean if (q.notename_i_ == 6) q.accidental_i_--; p.transpose (q); - (*add_arr_p)[i] = p; + (*pitch_arr_p)[i] = p; } - add_arr_p->sort (Musical_pitch::compare); - for (int i = 0; i < sub_arr_p->size (); i++) + pitch_arr_p->sort (Musical_pitch::compare); +} + +static int +find_pitch_i (Array const* pitch_arr_p, Musical_pitch p) +{ + for (int i = 0; i < pitch_arr_p->size (); i++) + if (p == (*pitch_arr_p)[i]) + return i; + return -1; +} + +static int +find_notename_i (Array const* pitch_arr_p, Musical_pitch p) +{ + int i = find_pitch_i (pitch_arr_p, p); + if (i == -1) { - Musical_pitch p = tonic; - Musical_pitch q = (*sub_arr_p)[i]; - // duh, c7 should mean - if (q.notename_i_ == 6) - q.accidental_i_--; - p.transpose (q); - (*sub_arr_p)[i] = p; + for (int i = 0; i < pitch_arr_p->size (); i++) + { + p.octave_i_ = (*pitch_arr_p)[i].octave_i_; + if (p == (*pitch_arr_p)[i]) + return i; + } } - sub_arr_p->sort (Musical_pitch::compare); + return i; +} + +static int +trap_i (Musical_pitch tonic, Musical_pitch p) +{ + int i = p.notename_i_ - tonic.notename_i_ + + (p.octave_i_ - tonic.octave_i_) * 7; + while (i < 0) + i += 7; + i++; + return i; +} +static Array +missing_triads_pitch_arr (Arrayconst* pitch_arr_p) +{ Musical_pitch third (2); Musical_pitch mthird (2, -1); - Musical_pitch missing; - missing = tonic; - missing.transpose (third); - - Musical_pitch p; - p = tonic; - p.transpose (third); - p.transpose (mthird); - - /* - must have minimum at 5 (3 is added automatically as missing) - */ - if (!add_arr_p->size ()) - add_arr_p->push (p); - else if ((add_arr_p->top () < p) && (add_arr_p->top ().notename_i_ != p.notename_i_)) - add_arr_p->push (p); - add_arr_p->sort (Musical_pitch::compare); Array triads; triads.push (third); // c e @@ -70,49 +84,87 @@ Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Array missing_arr; + + for (int i = 0; i < pitch_arr_p->size ();) + { + Musical_pitch p = (*pitch_arr_p)[i]; + int trap = trap_i (tonic, p); + if (last.notename_i_ == p.notename_i_) + last.transpose (triads[(last.notename_i_ - tonic.notename_i_ + 7) % 7]); + if (trap > trap_i (tonic, last)) + { + while (trap > trap_i (tonic, last)) + { + if ((last.notename_i_ - tonic.notename_i_ + 7) % 7 == 6) + { + Musical_pitch special_seven = last; + Musical_pitch lower (0, -1); + special_seven.transpose (lower); + missing_arr.push (special_seven); + } + else + { + missing_arr.push (last); + } + last.transpose (triads[(last.notename_i_ - tonic.notename_i_ + 7) % 7]); + } + } + else + { + i++; + } + } + return missing_arr; +} + + +/* + construct from parser output +*/ +Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p) +{ + rebuild_transpose (tonic, add_arr_p); + rebuild_transpose (tonic, sub_arr_p); + + Musical_pitch fifth = tonic; + fifth.transpose (Musical_pitch (2)); + fifth.transpose (Musical_pitch (2, -1)); + + /* + default chord includes upto 5: <1, 3, 5> + */ + add_arr_p->insert (tonic, 0); + int highest_trap = trap_i (tonic, add_arr_p->top ()); + if (highest_trap < 5) + add_arr_p->push (fifth); + /* - if first addition is 4, assume sus4 and don't add third implicitely + find missing triads */ - Musical_pitch sus (3); - sus.transpose (tonic); - if (add_arr_p->size ()) - if ((*add_arr_p)[0] == sus) - missing.transpose (mthird); + Array missing_arr = missing_triads_pitch_arr (add_arr_p); /* - add missing triads + if additions include 4, assume sus4 and don't add third implicitely */ - for (int i = 0; i < add_arr_p->size ();) + Musical_pitch third = tonic; + third.transpose (Musical_pitch (2)); + Musical_pitch sus = tonic; + sus.transpose (Musical_pitch (3)); + if (::find_pitch_i (add_arr_p, sus) != -1) { - Musical_pitch p = (*add_arr_p)[i]; - if (p > missing) - while (p > missing) - { - if (p.notename_i_ != missing.notename_i_) - { - if ((missing.notename_i_ - tonic.notename_i_ + 7) % 7 == 6) - { - Musical_pitch special_seven = missing; - Musical_pitch lower (0, -1); - special_seven.transpose (lower); - add_arr_p->insert (special_seven, i++); - } - else - add_arr_p->insert (missing, i++); - } - missing.transpose (triads[(missing.notename_i_ - tonic.notename_i_ + 7) % 7]); - } - else if (p.notename_i_ == missing.notename_i_) - missing.transpose (triads[(missing.notename_i_ - tonic.notename_i_ + 7) % 7]); - else - i++; + int i = ::find_pitch_i (&missing_arr, third); + if (i != -1) + missing_arr.get (i); } - + /* - add tonic + complete the list of triads to be added */ - if (!add_arr_p->size () || ((*add_arr_p)[0] != tonic)) - add_arr_p->insert (tonic, 0); + add_arr_p->concat (missing_arr); + add_arr_p->sort (Musical_pitch::compare); /* add all that aren't subtracted @@ -132,6 +184,8 @@ Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Arraysize (); i++) warning (_f ("invalid subtraction: not part of chord: %s", (*sub_arr_p)[i].str ())); @@ -140,42 +194,90 @@ Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Arraynotename_i_) - && (pitch_arr_[i].accidental_i_ == inversion_p->accidental_i_)) - break; + { + if ((pitch_arr_[i].notename_i_ == inversion_p->notename_i_) + && (pitch_arr_[i].accidental_i_ == inversion_p->accidental_i_)) + break; + } if (i == pitch_arr_.size ()) - warning (_f ("invalid inversion pitch: not part of chord: %s", - inversion_p->str ())); + { + warning (_f ("invalid inversion pitch: not part of chord: %s", + inversion_p->str ())); + } else - { - /* - urg - should be run-time switchable "chordInversionPreserve", howto? - - there are two ways commonly used to rearrange a chord with - an inversion: - - 1. rebuild pitch list, taking inversion as base - */ -#if 0 - rebuild_from_base (i); + { +#if INVERSION_ADDED_AS_BASE + pitch_arr_.insert (pitch_arr_[i], 0); + rebuild_with_bass (0); #else - /* - or - 2. insert inversion as lowest (at first position) - */ rebuild_with_bass (i); #endif + } delete inversion_p; } } +void +Chord::find_additions_and_subtractions(Array* add_arr_p, Array* sub_arr_p) +{ + Musical_pitch tonic = pitch_arr_[0]; + /* + all the triads that should be there + */ + Array all_arr; + all_arr.push (tonic); + all_arr.push (pitch_arr_.top ()); + all_arr.concat (missing_triads_pitch_arr (&all_arr)); + all_arr.sort (Musical_pitch::compare); + + int i = 0; + int j = 0; + while ((i < all_arr.size ()) || (j < pitch_arr_.size ())) + { + i = i push (p); + j++; + } + else + { + sub_arr_p->push (a); + i++; + } + } + + /* + add highest addition, because it names chord + */ + if (trap_i (tonic, pitch_arr_.top () > 5)) + add_arr_p->push (pitch_arr_.top ()); +} + String Chord::banter_str (Musical_pitch* inversion) const { Musical_pitch tonic = pitch_arr_[0]; + //urg, should do translation in scheme. + char const *acc[] = {"\\textflat\\textflat ", "\\textflat ", "", "\\textsharp " , "\\textsharp\\textsharp "}; + String tonic_str = tonic.str (); + tonic_str = tonic_str.left_str (1).upper_str () + + acc[tonic.accidental_i_ + 2]; + + Array add_arr; + Array sub_arr; + find_additions_and_subtractions (&add_arr, &sub_arr); + Array scale; scale.push (Musical_pitch (0)); // c scale.push (Musical_pitch (1)); // d @@ -183,79 +285,81 @@ Chord::banter_str (Musical_pitch* inversion) const scale.push (Musical_pitch (3)); // f scale.push (Musical_pitch (4)); // g scale.push (Musical_pitch (5)); // a + scale.push (Musical_pitch (6)); // b // 7 always means 7-... - scale.push (Musical_pitch (6, -1)); // b - + // scale.push (Musical_pitch (6, -1)); // b - for (int i = 0; i < scale.size (); i++) - scale[i].transpose (tonic); - - //urg, should do translation in scheme. - char const *acc[] = {"\\textflat\\textflat ", "\\textflat ", "", "\\textsharp " , "\\textsharp\\textsharp "}; - String tonic_str = tonic.str (); - tonic_str = tonic_str.left_str (1).upper_str () - + acc[tonic.accidental_i_ + 2]; - - String add_str; - String sub_str; + rebuild_transpose (tonic, &scale); + + bool has3m_b = false; + bool has4_b = false; + String str; String sep_str; - String sub_sep_str; - int last_trap = 1; - for (int i=1; i < pitch_arr_.size (); i++) + for (int i = 0; i < add_arr.size (); i++) { - Musical_pitch p = pitch_arr_[i]; - int trap = p.notename_i_ - tonic.notename_i_ - + (p.octave_i_ - tonic.octave_i_) * 7; - while (trap < 0) - trap += 7; - trap++; - while (trap - last_trap > 2) - { - last_trap += 2; - sub_str += sub_sep_str + "no" + to_str (last_trap); - sub_sep_str = "/"; - } - last_trap = trap; + Musical_pitch p = add_arr[i]; + int trap = trap_i (tonic, p); + if (trap == 4) + has4_b = true; int accidental = p.accidental_i_ - scale[(trap - 1) % 7].accidental_i_; if ((trap == 3) && (accidental == -1)) - tonic_str += "m"; // hmm - else if (accidental || (!(trap % 2) || ((i + 1 == pitch_arr_.size ()) && (trap > 5)))) + { + tonic_str += "m"; + has3m_b = true; + } + else if (accidental + || (!(trap % 2) || ((i + 1 == add_arr.size ()) && (trap > 5)))) { - add_str += sep_str; + str += sep_str; if ((trap == 7) && (accidental == 1)) - add_str += "maj7"; + str += "maj7"; else { - add_str += to_str (trap); + str += to_str (trap); if (accidental) - add_str += accidental < 0 ? "-" : "+"; - // catch "C4/no3"; remove "no3" - if (trap == 4) - { - int i = sub_str.index_i ("no3"); - if (i != -1) - sub_str = sub_str.nomid_str (i, 3); - if (!sub_str.length_i ()) - sub_sep_str = ""; - } + str += accidental < 0 ? "-" : "+"; } sep_str = "/"; } } + for (int i = 0; i < sub_arr.size (); i++) + { + Musical_pitch p = sub_arr[i]; + int trap = trap_i (tonic, p); + /* + if chord has 3-, assume minor and don't display 'no3' + if additions include 4, assume sus4 and don't display 'no3' + */ + if (!((trap == 3) && (has3m_b || has4_b))) + { + str += sep_str + "no" + to_str (trap); + sep_str = "/"; + } + } + String inversion_str; if (inversion) { inversion_str = inversion->str (); inversion_str = "/" + inversion_str.left_str (1).upper_str () - + acc[tonic.accidental_i_ + 2]; + + acc[inversion->accidental_i_ + 2]; } - if (sub_str.length_i ()) - sub_str = sep_str + sub_str; - String str = tonic_str + "$^{" + add_str + sub_str + "}$" + inversion_str; - return str; + return tonic_str + "$^{" + str + "}$" + inversion_str; +} + +int +Chord::find_notename_i (Musical_pitch p) const +{ + return ::find_notename_i (&pitch_arr_, p); +} + +int +Chord::find_pitch_i (Musical_pitch p) const +{ + return ::find_pitch_i (&pitch_arr_, p); } int @@ -318,6 +422,7 @@ Chord::find_tonic_i () const void Chord::rebuild_from_base (int base_i) { + assert (base_i >= 0); Musical_pitch last (0, 0, -5); Array new_arr; for (int i = 0; i < pitch_arr_.size (); i++) @@ -338,6 +443,12 @@ Chord::rebuild_from_base (int base_i) void Chord::rebuild_insert_inversion (int tonic_i) { + assert (tonic_i > 0); +#if INVERSION_ADDED_AS_BASE + // inversion was added; don't insert + Musical_pitch inversion = pitch_arr_.get (0); + (void)inversion; +#else Musical_pitch inversion = pitch_arr_.get (0); rebuild_from_base (tonic_i - 1); if (pitch_arr_.size ()) @@ -352,11 +463,13 @@ Chord::rebuild_insert_inversion (int tonic_i) pitch_arr_.insert (inversion, i); break; } +#endif } void Chord::rebuild_with_bass (int bass_i) { + assert (bass_i >= 0); Musical_pitch inversion = pitch_arr_.get (bass_i); // is lowering fine, or should others be raised? if (pitch_arr_.size ()) diff --git a/lily/clef-item.cc b/lily/clef-item.cc index 5e5fee9cbf..3f76f6f0c3 100644 --- a/lily/clef-item.cc +++ b/lily/clef-item.cc @@ -12,7 +12,6 @@ #include "molecule.hh" #include "paper-def.hh" #include "lookup.hh" -#include "clef-engraver.hh" #include "g-text-item.hh" #include "p-score.hh" @@ -78,10 +77,8 @@ Clef_item::do_brew_molecule_p() const String t = symbol_; if (change_b_) t += "_change"; - // Atom s = lookup_l ()-> text ("roman", to_str (break_status_dir ())); - - Atom s = lookup_l ()->clef (t); - Molecule*output = new Molecule (Atom (s)); + + Molecule*output = new Molecule (lookup_l ()->clef (t)); return output; } diff --git a/lily/collision.cc b/lily/collision.cc index 149e39fc23..db99d7b4c7 100644 --- a/lily/collision.cc +++ b/lily/collision.cc @@ -155,7 +155,8 @@ Collision::do_pre_processing() (shaddup) */ Offset o (x_off[j] * wid_f, y_off[j] * inter_f); - ((Score_element*)col_l_a[j])->translate (o); + col_l_a[j]->translate (o); + // ((Score_element*)col_l_a[j])->translate (o); } } } diff --git a/lily/command-request.cc b/lily/command-request.cc index 1ab0353bc5..aa5b3877d7 100644 --- a/lily/command-request.cc +++ b/lily/command-request.cc @@ -74,7 +74,7 @@ Bar_req::Bar_req (String s) Partial_measure_req::Partial_measure_req (Moment m) { - duration_ =m; + length_mom_ =m; } bool @@ -82,7 +82,7 @@ Partial_measure_req::do_equal_b (Request* r) const { Partial_measure_req *p = dynamic_cast (r); - return p&& p->duration_ == duration_; + return p&& p->length_mom_ == length_mom_; } @@ -133,7 +133,7 @@ Clef_change_req::Clef_change_req (String s) void Partial_measure_req::do_print() const { - DOUT << duration_; + DOUT << length_mom_; } @@ -181,7 +181,7 @@ Tempo_req::do_equal_b (Request *r) const { Tempo_req *t = dynamic_cast (r); - return t&& t->dur_.length()== dur_.length () && metronome_i_ == t->metronome_i_; + return t&& t->dur_.length_mom ()== dur_.length_mom () && metronome_i_ == t->metronome_i_; } diff --git a/lily/crescendo.cc b/lily/crescendo.cc index 47eff97b90..024a697c17 100644 --- a/lily/crescendo.cc +++ b/lily/crescendo.cc @@ -14,7 +14,7 @@ #include "debug.hh" #include "score-column.hh" -Crescendo::Crescendo() +Crescendo::Crescendo () { grow_dir_ =0; dir_ = DOWN; @@ -22,17 +22,17 @@ Crescendo::Crescendo() } Interval -Crescendo::symbol_height() const +Crescendo::symbol_height () const { - return get_symbol().dim_[Y_AXIS]; + return get_symbol ().dim_[Y_AXIS]; } static Real absdyn_dim = 10 PT; // ugh -Atom -Crescendo::get_symbol() const +Molecule +Crescendo::get_symbol () const { - Real w_dim = extent(X_AXIS).length (); + Real w_dim = extent (X_AXIS).length (); if (dyn_b_drul_[LEFT]) { w_dim -= absdyn_dim; @@ -44,24 +44,24 @@ Crescendo::get_symbol() const if (w_dim < 0) { - warning (_ ("crescendo") + " " + _("too small")); + warning (_ ("crescendo") + " " + _ ("too small")); w_dim = 0; } Drul_array broken; Direction d = LEFT; do { - Score_column* s = (Score_column* )spanned_drul_[d] ; // UGH - broken[d] = (!s->musical_b()); - } while (flip(&d) != LEFT); + Score_column* s = dynamic_cast(spanned_drul_[d]); // UGH + broken[d] = (!s->musical_b ()); + } while (flip (&d) != LEFT); - bool continued = broken[(Direction)-grow_dir_]; - return Atom (lookup_l ()->hairpin (w_dim, grow_dir_ < 0, continued)); + bool continued = broken[Direction (-grow_dir_)]; + return Molecule (lookup_l ()->hairpin (w_dim, grow_dir_ < 0, continued)); } Molecule* -Crescendo::do_brew_molecule_p() const +Crescendo::do_brew_molecule_p () const { Molecule* m_p =0; Real x_off_dim=0.0; @@ -69,8 +69,8 @@ Crescendo::do_brew_molecule_p() const x_off_dim += absdyn_dim; m_p = new Molecule; - Atom s (get_symbol()); - m_p->add_atom (s); + Molecule s (get_symbol ()); + m_p->add_molecule (s); m_p->translate (Offset (x_off_dim, coordinate_offset_f_)); return m_p; } diff --git a/lily/dimension-cache.cc b/lily/dimension-cache.cc index 8746337cca..6713e82b19 100644 --- a/lily/dimension-cache.cc +++ b/lily/dimension-cache.cc @@ -13,6 +13,7 @@ Dimension_cache::Dimension_cache (Dimension_cache const &d) { init(); empty_b_ = d.empty_b_; + offset_ = d.offset_; //let's hope others will copy the refpoint appropriately. } Dimension_cache::Dimension_cache () diff --git a/lily/dots.cc b/lily/dots.cc index 1a40a51570..ea37e88f11 100644 --- a/lily/dots.cc +++ b/lily/dots.cc @@ -33,18 +33,18 @@ Molecule* Dots::do_brew_molecule_p () const { Molecule *out = new Molecule; - Atom fill = lookup_l ()->fill (Box (Interval (0,0), + Molecule fill = lookup_l ()->fill (Box (Interval (0,0), Interval (0,0))); - out->add_atom (fill); + out->add_molecule (fill); - Atom d = lookup_l ()->dots (); + Molecule d = lookup_l ()->dots (); Real dw = d.dim_[X_AXIS].length (); d.translate_axis (-dw, X_AXIS); for (int i=no_dots_i_; i--; ) { d.translate_axis (2*dw,X_AXIS); - out->add_atom (d); + out->add_molecule (d); } Real inter_f = paper ()->internote_f (); out->translate_axis (inter_f * position_i_, Y_AXIS); diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index d36eeb250a..bf7a654295 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -92,10 +92,10 @@ Dynamic_engraver::do_process_requests() continue; } - String loud = absd->loudness_str (); + String loud = absd->loudness_str_; text_p_ = new G_text_item; - text_p_->text_str_ = "dyn" + loud; // ugh + text_p_->text_str_ = loud; // ugh Scalar prop = get_property ("dynamicStyle", 0); text_p_->style_str_ = prop.length_i () ? prop : "dynamic"; diff --git a/lily/engraver-group.cc b/lily/engraver-group.cc index a255c4c5cd..ab01127f61 100644 --- a/lily/engraver-group.cc +++ b/lily/engraver-group.cc @@ -30,11 +30,9 @@ Engraver_group_engraver::do_announces() Link_array groups = group_l_arr (); for (int i=0; i < groups.size(); i++) { - Engraver * eng = dynamic_cast (groups[i]); - if (eng) + Engraver_group_engraver * group = dynamic_cast (groups[i]); + if (group) { - Engraver_group_engraver * group = - (Engraver_group_engraver*) eng; group->do_announces(); } } diff --git a/lily/engraver.cc b/lily/engraver.cc index 762d800ed4..947209376b 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -11,6 +11,7 @@ #include "engraver.hh" #include "engraver-group.hh" #include "debug.hh" +#include "paper-def.hh" void Engraver::fill_staff_info (Staff_info&) @@ -36,7 +37,7 @@ Engraver::typeset_element (Score_element*p) Paper_def* Engraver::paper() const { - return (Paper_def*)output_def_l_; + return dynamic_cast(output_def_l_); } diff --git a/lily/extender-spanner.cc b/lily/extender-spanner.cc index 7c727b128c..9be7106bef 100644 --- a/lily/extender-spanner.cc +++ b/lily/extender-spanner.cc @@ -6,7 +6,7 @@ (c) 1998 Jan Nieuwenhuizen */ -#include "atom.hh" + #include "box.hh" #include "debug.hh" #include "lookup.hh" @@ -52,12 +52,11 @@ Extender_spanner::do_brew_molecule_p () const Real w = extent (X_AXIS).length (); w += (dx_f_drul_[RIGHT] - dx_f_drul_[LEFT]); - - Atom a = lookup_l ()->extender (w); - + Real h = paper ()->get_realvar (ly_symbol ("extender_height")); + Molecule a = lookup_l ()->filledbox ( Box (Interval (0,w), Interval (0,h))); a.translate (Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT])); - mol_p->add_atom (a); + mol_p->add_molecule (a); return mol_p; } diff --git a/lily/g-text-item.cc b/lily/g-text-item.cc index 26751aecb9..8d9d9cf152 100644 --- a/lily/g-text-item.cc +++ b/lily/g-text-item.cc @@ -8,7 +8,7 @@ */ #include "g-text-item.hh" -#include "atom.hh" + #include "molecule.hh" #include "paper-def.hh" #include "lookup.hh" @@ -16,7 +16,7 @@ Molecule* G_text_item::do_brew_molecule_p () const { - Atom a= paper ()->lookup_l(0)->text (style_str_,text_str_); + Molecule a= paper ()->lookup_l(0)->text (style_str_,text_str_); return new Molecule (a); } diff --git a/lily/general-script-def.cc b/lily/general-script-def.cc index 3ce45fbf5c..360a0123f0 100644 --- a/lily/general-script-def.cc +++ b/lily/general-script-def.cc @@ -6,10 +6,10 @@ (c) 1997--1998 Han-Wen Nienhuys */ - +#include "molecule.hh" #include "general-script-def.hh" #include "debug.hh" -#include "atom.hh" + Direction General_script_def::staff_dir() const @@ -60,19 +60,13 @@ General_script_def::do_print() const { } -Atom -General_script_def::get_atom (Paper_def*, Direction) const +Molecule +General_script_def::get_molecule (Paper_def*, Direction) const { - Atom s; - return Atom (s); + Molecule s; + return Molecule (s); } -Interval -General_script_def::width (Paper_def*) const -{ - Interval t; - return t; -} diff --git a/lily/global-ctor.cc b/lily/global-ctor.cc new file mode 100644 index 0000000000..562bd6131f --- /dev/null +++ b/lily/global-ctor.cc @@ -0,0 +1,27 @@ +/* + global-ctor.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ +#include "global-ctor.hh" +#include "array.hh" + +static Array *ctor_global_static_arr_p_; + +void +add_constructor (Global_ctor c) +{ + if (!ctor_global_static_arr_p_) + ctor_global_static_arr_p_ = new Array; + ctor_global_static_arr_p_->push (c); +} + +void +call_constructors () +{ + for (int i=0; i < ctor_global_static_arr_p_->size (); i++) + (ctor_global_static_arr_p_->elem (i)) (); +} diff --git a/lily/global-translator.cc b/lily/global-translator.cc index d6785e6d05..b92a7a992a 100644 --- a/lily/global-translator.cc +++ b/lily/global-translator.cc @@ -47,7 +47,7 @@ Global_translator::prepare (Moment m) } Moment -Global_translator::now_moment () const +Global_translator::now_mom () const { return now_mom_; } diff --git a/lily/graphical-element.cc b/lily/graphical-element.cc index 921608e9ae..940a972025 100644 --- a/lily/graphical-element.cc +++ b/lily/graphical-element.cc @@ -84,8 +84,7 @@ Graphical_element::set_empty (bool b) Interval Graphical_element::extent (Axis a) const { - Dimension_cache const * d = //(Dimension_cache*) - &dim_cache_[a]; + Dimension_cache const * d = &dim_cache_[a]; if (d->empty_b ()) return Interval (); diff --git a/lily/heads-engraver.cc b/lily/heads-engraver.cc index 4e894ba438..cd1719260d 100644 --- a/lily/heads-engraver.cc +++ b/lily/heads-engraver.cc @@ -16,13 +16,17 @@ Note_heads_engraver::Note_heads_engraver() } bool -Note_heads_engraver::do_try_music (Music *req_l) +Note_heads_engraver::do_try_music (Music *m) { - if (Note_req * n =dynamic_cast (req_l)) + if (Note_req * n =dynamic_cast (m)) { note_req_l_arr_.push (n); return true; } + if (Tonic_req* t = dynamic_cast (m)) + { + return true; + } return false; } diff --git a/lily/include/atom.hh b/lily/include/atom.hh index 22c5d15a0c..b4f656094a 100644 --- a/lily/include/atom.hh +++ b/lily/include/atom.hh @@ -13,32 +13,46 @@ #include "string.hh" #include "box.hh" #include "lily-proto.hh" +#include "lily-guile.hh" +#if 0 /// a symbol which can be translated, and freely copied class Atom { + static long smob_tag_; + + static SCM smob_mark (SCM); + static scm_sizet smob_free (SCM); + static int smob_display (SCM, SCM, scm_print_state*); + Atom (SCM s); + SCM make_smob () const; +public: Offset off_; + static SCM make_atom (SCM outputfunc); + SCM copy_self () const; + static Atom *atom_l (SCM); + + /// Is #obj# a Foo? + static bool Atom_b(SCM obj); + static void init_smob (); + SCM func_; + SCM font_; +}; + +#else + +class Atom { public: - Protected_scm lambda_; - Score_element * origin_l_; - - // urg, only used as a temp buffer - String str_; - String font_; - Box dim_; - - Offset offset () const; - String str() const; // for printing. - Atom (String, Box); - Atom (); - void translate (Offset o); - void translate_axis (Real r,Axis a); - /// how big is #this#? - Box extent() const; - Interval extent (Axis)const; - void print() const; - bool check_infinity_b () const; - bool empty() const; + Atom (SCM s); + Offset off_; + /* + SCM expression that (when evaluated) gives a TeX string +representing a musical notation symbol. */ + Protected_scm func_; + Protected_scm font_; }; + +#endif + #endif diff --git a/lily/include/bar.hh b/lily/include/bar.hh index 1bd1d6d8e6..c315e2137a 100644 --- a/lily/include/bar.hh +++ b/lily/include/bar.hh @@ -15,6 +15,7 @@ class Bar:public Item { public: String type_str_; + bool at_line_start_b_; VIRTUAL_COPY_CONS(Score_element); diff --git a/lily/include/base-span-bar-engraver.hh b/lily/include/base-span-bar-engraver.hh new file mode 100644 index 0000000000..6d8ddf71ed --- /dev/null +++ b/lily/include/base-span-bar-engraver.hh @@ -0,0 +1,44 @@ +/* + base-span-bar-engraver.hh -- declare Span_bar_engraver + + source file of the GNU LilyPond music typesetter + + (c) 1997--1998 Han-Wen Nienhuys +*/ + + +#ifndef SPAN_BAR_GRAV_HH +#define SPAN_BAR_GRAV_HH + +#include "engraver.hh" + +/** + + Make bars that span multiple "staffs". Catch bars, and span a + Span_bar over them if we find more than 2 bars + + */ +class Base_span_bar_engraver : public Engraver +{ + Span_bar * spanbar_p_; + Array bar_l_arr_; + Vertical_align_spanner * valign_l_; +public: + VIRTUAL_COPY_CONS(Translator); + + + Base_span_bar_engraver(); +protected: + /** + Do we use break priorities? If true, use break_priority_i_ as + horizontal alignment priority, otherwise, hang the spanbar on the + acknowledged bar. */ + bool use_priority_b_; + int break_priority_i_; + + virtual void acknowledge_element (Score_element_info); + virtual void do_pre_move_processing(); + virtual Span_bar* get_span_bar_p() const; +}; + +#endif // SPAN_BAR_GRAV_HH diff --git a/lily/include/beam-engraver.hh b/lily/include/beam-engraver.hh index 898e8b048d..5bd35d4b94 100644 --- a/lily/include/beam-engraver.hh +++ b/lily/include/beam-engraver.hh @@ -18,7 +18,7 @@ class Beam_engraver : public Engraver { Beam *finished_beam_p_; Beam *beam_p_; - + Beam_req * prev_start_req_; Rhythmic_grouping*grouping_p_; Rhythmic_grouping*finished_grouping_p_; diff --git a/lily/include/box.hh b/lily/include/box.hh index b26c6e3695..c53543d058 100644 --- a/lily/include/box.hh +++ b/lily/include/box.hh @@ -24,6 +24,7 @@ struct Box { void translate (Offset o); /// smallest box enclosing #b# + void set_empty (); void unite (Box b); Box(); Box (Interval ix, Interval iy); diff --git a/lily/include/change-iterator.hh b/lily/include/change-iterator.hh index 9dec9ba80c..6a703ac313 100644 --- a/lily/include/change-iterator.hh +++ b/lily/include/change-iterator.hh @@ -15,7 +15,6 @@ class Change_iterator : public Music_iterator { - Change_translator *change_l (); void error (String); protected: diff --git a/lily/include/chord-name-engraver.hh b/lily/include/chord-name-engraver.hh index 233714f017..4e13194916 100644 --- a/lily/include/chord-name-engraver.hh +++ b/lily/include/chord-name-engraver.hh @@ -12,33 +12,25 @@ #include "engraver.hh" #include "array.hh" #include "musical-pitch.hh" - #include "lily-proto.hh" -Array rebuild_from_base_pitch_arr (Array pitch_arr, int base_i); -Array rebuild_insert_inversion_pitch_arr (Array pitch_arr, int tonic_i); -Array rebuild_with_bass_pitch_arr (Array pitch_arr, int bass_i); - - class Chord_name_engraver : public Engraver { +public: + Chord_name_engraver (); + VIRTUAL_COPY_CONS (Translator); + protected: virtual void do_pre_move_processing (); virtual void acknowledge_element (Score_element_info i); virtual void do_process_requests (); virtual bool do_try_music (Music* m); -public: - Chord_name_engraver (); - VIRTUAL_COPY_CONS (Translator); - private: Array pitch_arr_; Link_array text_p_arr_; - - String banter_str (Array pitch_arr, Musical_pitch* inversion) const; - int find_tonic_i () const; Array rebuild_pitch_arr (int tonic_i) const; + Tonic_req* tonic_req_; }; #endif // CHORD_NAME_ENGRAVER_HH diff --git a/lily/include/chord.hh b/lily/include/chord.hh index 0fc7601aeb..a863e76572 100644 --- a/lily/include/chord.hh +++ b/lily/include/chord.hh @@ -25,9 +25,11 @@ public: String banter_str (Musical_pitch* inversion) const; int find_tonic_i () const; + int find_pitch_i (Musical_pitch p) const; + int find_notename_i (Musical_pitch p) const; + void find_additions_and_subtractions(Array* add_arr_p, Array* sub_arr_p); Array pitch_arr_; - int tonic_i_; }; #endif // CHORD_HH diff --git a/lily/include/colhpos.hh b/lily/include/colhpos.hh index 964933e2df..ee770c3b3d 100644 --- a/lily/include/colhpos.hh +++ b/lily/include/colhpos.hh @@ -7,10 +7,10 @@ #ifndef COLHPOS_HH #define COLHPOS_HH -#include "array.hh" +#include "parray.hh" #include "lily-proto.hh" -typedef Array Line_of_cols; +typedef Link_array Line_of_cols; struct Column_x_positions { Line_spacer * spacer_l_; diff --git a/lily/include/command-request.hh b/lily/include/command-request.hh index 7d539fb666..cf3c897efc 100644 --- a/lily/include/command-request.hh +++ b/lily/include/command-request.hh @@ -69,7 +69,7 @@ public: class Partial_measure_req : public Timing_req { public: - Moment duration_; + Moment length_mom_; Partial_measure_req (Moment); REQUESTMETHODS(Partial_measure_req); diff --git a/lily/include/cons.cc b/lily/include/cons.cc new file mode 100644 index 0000000000..39ed3095f6 --- /dev/null +++ b/lily/include/cons.cc @@ -0,0 +1,10 @@ +/* + cons.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#include "cons.hh" diff --git a/lily/include/cons.hh b/lily/include/cons.hh new file mode 100644 index 0000000000..4b4de47e55 --- /dev/null +++ b/lily/include/cons.hh @@ -0,0 +1,43 @@ +/* + cons.hh -- declare + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#ifndef CONS_HH +#define CONS_HH + +template +class Cons +{ +public: + T * car_; + Cons * next_; + virtual ~Cons (); + Cons () { + car_=0; + next_ =0; + } + Cons (T*t, Cons*c) + { + car_ = t; + next_ = c; + } +}; + +template +class Killing_cons : public Cons +{ +public: + Killing_cons (T *t, Cons *p) + : Cons( t,p) + { + } + virtual ~Killing_cons (); +}; + +#endif /* CONS_HH */ + diff --git a/lily/include/crescendo.hh b/lily/include/crescendo.hh index f39f1dbaf7..dec066bef9 100644 --- a/lily/include/crescendo.hh +++ b/lily/include/crescendo.hh @@ -30,7 +30,7 @@ protected: private: - Atom get_symbol() const; + Molecule get_symbol() const; }; #endif // CRESCENDO_HH diff --git a/lily/include/general-script-def.hh b/lily/include/general-script-def.hh index 2cd36becb6..dde24d58c8 100644 --- a/lily/include/general-script-def.hh +++ b/lily/include/general-script-def.hh @@ -27,11 +27,9 @@ public: virtual Direction rel_stem_dir() const; virtual int priority_i() const; virtual bool inside_b() const; - virtual Atom get_atom (Paper_def* p, Direction dir_) const; + virtual Molecule get_molecule (Paper_def* p, Direction dir_) const; bool equal_b (General_script_def const&) const; virtual ~General_script_def() {} - - virtual Interval width (Paper_def *) const; protected: virtual bool do_equal_b (General_script_def const *) const; virtual void do_print() const; diff --git a/lily/include/global-ctor.hh b/lily/include/global-ctor.hh new file mode 100644 index 0000000000..53d25a4477 --- /dev/null +++ b/lily/include/global-ctor.hh @@ -0,0 +1,32 @@ +/* + global-ctor.hh -- declare Global construction stuff. + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#ifndef GLOBAL_CTOR_HH +#define GLOBAL_CTOR_HH + + +#define ADD_GLOBAL_CTOR_WITHNAME(y,x)\ +class Global_ctor_ ## y \ +{\ +public: \ + Global_ctor_ ## y () { \ + add_constructor (x); \ + } \ +} _ ## y ## _ctor_init; \ + + +#define ADD_GLOBAL_CTOR(x) ADD_GLOBAL_CTOR_WITHNAME(x,x); + + +typedef void (* Global_ctor ) (); +void add_constructor (Global_ctor ctor); +void call_constructors (); + +#endif /* GLOBAL_CTOR_HH */ + diff --git a/lily/include/global-translator.hh b/lily/include/global-translator.hh index 0e12f150fd..7028dbc92f 100644 --- a/lily/include/global-translator.hh +++ b/lily/include/global-translator.hh @@ -34,7 +34,7 @@ public: protected: - virtual Moment now_moment () const; + virtual Moment now_mom () const; virtual Global_translator *global_l() { return this; } }; diff --git a/lily/include/includable-lexer.hh b/lily/include/includable-lexer.hh index 51aa0937ad..23b9724394 100644 --- a/lily/include/includable-lexer.hh +++ b/lily/include/includable-lexer.hh @@ -13,7 +13,7 @@ #include #include "string.hh" -#include "array.hh" +#include "parray.hh" #include "fproto.hh" #include "proto.hh" @@ -29,7 +29,7 @@ class Includable_lexer : public yyFlexLexer protected: bool close_input (); - Array include_stack_; + Link_array include_stack_; Array char_count_stack_; public: diff --git a/lily/include/killing-cons.tcc b/lily/include/killing-cons.tcc new file mode 100644 index 0000000000..3c9a9710e7 --- /dev/null +++ b/lily/include/killing-cons.tcc @@ -0,0 +1,27 @@ +/* + killing-cons.tcc -- declare Killing_cons + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#ifndef KILLING_CONS_TCC +#define KILLING_CONS_TCC + +template +Cons::~Cons () +{ +} + +template +Killing_cons::~Killing_cons () +{ + delete car_; + delete next_; +} + + +#endif /* KILLING_CONS_TCC */ + diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index 0c600002f8..bf37e62189 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -251,6 +251,7 @@ struct Time_signature; struct Time_signature_change_req; struct Time_signature_engraver; struct Time_signature_performer; +struct Tonic_req; struct Translator; struct Translator_group; struct Timing_req; diff --git a/lily/include/line-of-score.hh b/lily/include/line-of-score.hh index ab91f4d1f8..b3183efc97 100644 --- a/lily/include/line-of-score.hh +++ b/lily/include/line-of-score.hh @@ -15,7 +15,7 @@ class Line_of_score : public Spanner , public Super_element { public: - Link_array cols; + Link_array cols_; bool error_mark_b_; diff --git a/lily/include/lookup.hh b/lily/include/lookup.hh index 955ce1e87d..d61766a1f1 100644 --- a/lily/include/lookup.hh +++ b/lily/include/lookup.hh @@ -10,10 +10,8 @@ #ifndef LOOKUP_HH #define LOOKUP_HH -#include "atom.hh" #include "molecule.hh" #include "fproto.hh" -#include "scalar.hh" #include "direction.hh" #include "box.hh" @@ -27,33 +25,34 @@ public: - Atom special_ball (int, String) const; - Atom simple_bar (String s, Real w) const; + Molecule special_ball (int, String) const; + Molecule simple_bar (String s, Real w) const; Molecule accidental (int, bool cautionary) const; - Atom afm_find (String, bool warn=true) const; - Atom ball (int) const; + Molecule afm_find (String, bool warn=true) const; + Molecule ball (int) const; Molecule bar (String, Real height) const; - Atom beam (Real, Real, Real) const; - Atom clef (String) const; - Atom dashed_slur (Array controls, Real thick, Real dash) const; - Atom dots () const; - Atom extender (Real) const; - Atom fill (Box b) const; - Atom flag (int, Direction) const; - Atom hairpin (Real width, bool decresc, bool continued) const; - Atom plet (Real dy, Real dx, Direction dir) const; - Atom rest (int, bool outside) const; - Atom rule_symbol (Real height, Real width) const; - Atom script (String idx) const; - Atom stem (Real y1_pos, Real y2_pos) const; - Atom slur (Array controls) const; - Atom streepje (int type) const; - Atom text (String style, String text) const; - Atom vbrace (Real &dy) const; - Atom vbracket (Real &dy) const; - Atom volta (Real w, bool last_b) const; - Atom special_time_signature (String, Array) const; - Atom time_signature (Array) const; + Molecule beam (Real, Real, Real) const; + Molecule clef (String) const; + Molecule dashed_slur (Array controls, Real thick, Real dash) const; + Molecule dots () const; + Molecule ledger_line (Interval) const; + Molecule fill (Box b) const; + Molecule filledbox (Box b) const; + Molecule flag (int, Direction) const; + Molecule hairpin (Real width, bool decresc, bool continued) const; + Molecule plet (Real dy, Real dx, Direction dir) const; + Molecule rest (int, bool outside) const; + Molecule rule_symbol (Real height, Real width) const; + Molecule script (String idx) const; + Molecule stem (Real y1_pos, Real y2_pos) const; + Molecule slur (Array controls) const; + Molecule streepje (int type) const; + Molecule text (String style, String text) const; + Molecule staff_brace (Real dy) const; + Molecule staff_bracket (Real dy) const; + Molecule volta (Real w, bool last_b) const; + Molecule special_time_signature (String, int,int) const; + Molecule time_signature (int n,int d) const; Paper_def * paper_l_; diff --git a/lily/include/lyric-performer.hh b/lily/include/lyric-performer.hh index 4f83376ad4..baf31a47a9 100644 --- a/lily/include/lyric-performer.hh +++ b/lily/include/lyric-performer.hh @@ -25,7 +25,7 @@ protected: virtual void do_process_requests(); private: - Array lreq_arr_; + Link_array lreq_arr_; }; #endif // LYRIC_PERFOMER_HH diff --git a/lily/include/midi-def.hh b/lily/include/midi-def.hh index ef0029b418..85975ee8dd 100644 --- a/lily/include/midi-def.hh +++ b/lily/include/midi-def.hh @@ -31,7 +31,7 @@ public: Midi_def(); ~Midi_def(); - Real duration_to_seconds_f (Moment); + Real length_mom_to_seconds_f (Moment); int get_tempo_i (Moment moment); void print() const; void set_tempo (Moment moment, int count_per_minute_i); diff --git a/lily/include/midi-item.hh b/lily/include/midi-item.hh index 5b3eaf6a1a..2b251c4286 100644 --- a/lily/include/midi-item.hh +++ b/lily/include/midi-item.hh @@ -112,7 +112,7 @@ struct Midi_note : public Midi_item { Midi_note (Audio_item* audio_item_l); - Moment duration () const; + Moment length_mom () const; int pitch_i () const; virtual String str () const; diff --git a/lily/include/misc.hh b/lily/include/misc.hh index e659602e99..d45eabe840 100644 --- a/lily/include/misc.hh +++ b/lily/include/misc.hh @@ -27,7 +27,7 @@ sign (int i) { #ifndef STANDALONE #include "lily-proto.hh" -Interval itemlist_width (const Array &its); +Interval itemlist_width (const Link_array &its); #endif void set_frobnify (void*, size_t); diff --git a/lily/include/molecule.hh b/lily/include/molecule.hh index 757a26ac34..53da1c511a 100644 --- a/lily/include/molecule.hh +++ b/lily/include/molecule.hh @@ -13,29 +13,35 @@ #include "box.hh" #include "axes.hh" #include "direction.hh" +#include "protected-scm.hh" +#include "cons.hh" /** a group of individually translated symbols. You can add molecules to the top, to the right, etc. */ -struct Molecule { - Pointer_list atoms_; // change to List? +class Molecule { + // Protected_scm atom_list_; // change to List? + Killing_cons *atom_list_; + friend class Paper_outputter; +public: + Box dim_; - - Molecule() { } - Molecule (Atom const &a); + Molecule(); + ~Molecule(); void add_at_edge (Axis a, Direction d, const Molecule &m, Real padding); void add_molecule (Molecule const &m); void translate (Offset); + void do_center (Axis); void translate_axis (Real,Axis); - void add_atom (Atom const & a) ; + + void add_atom (Atom const *a); /// how big is #this#? Box extent() const; Interval extent (Axis) const; Molecule (const Molecule&s); void print() const; -private: - void operator=(const Molecule&); + void operator=(const Molecule&); }; #endif diff --git a/lily/include/music-list.hh b/lily/include/music-list.hh index 7cbbffee49..9665ff9df4 100644 --- a/lily/include/music-list.hh +++ b/lily/include/music-list.hh @@ -55,7 +55,7 @@ public: Simultaneous_music(Music_list *); virtual Musical_pitch to_relative_octave (Musical_pitch); - virtual Moment duration () const; + virtual Moment length_mom () const; }; @@ -84,6 +84,6 @@ public: virtual Musical_pitch to_relative_octave (Musical_pitch); Sequential_music(Music_list*); - virtual Moment duration () const; + virtual Moment length_mom () const; }; #endif // Music_sequence_HH diff --git a/lily/include/music-wrapper-iterator.hh b/lily/include/music-wrapper-iterator.hh index 50d9bbea27..fc149876c8 100644 --- a/lily/include/music-wrapper-iterator.hh +++ b/lily/include/music-wrapper-iterator.hh @@ -29,7 +29,6 @@ public: virtual bool ok () const; protected: - Music_wrapper *music_wrapper_l () const; virtual void do_print () const; virtual void do_process_and_next (Moment) ; diff --git a/lily/include/music-wrapper.hh b/lily/include/music-wrapper.hh index 26fea0ec7b..adbd869790 100644 --- a/lily/include/music-wrapper.hh +++ b/lily/include/music-wrapper.hh @@ -30,7 +30,7 @@ public: VIRTUAL_COPY_CONS(Music); Music_wrapper (Music_wrapper const&); - virtual Moment duration () const; + virtual Moment length_mom () const; virtual ~Music_wrapper (); virtual Musical_pitch to_relative_octave (Musical_pitch); diff --git a/lily/include/music.hh b/lily/include/music.hh index 8f30e44698..15ee2f7074 100644 --- a/lily/include/music.hh +++ b/lily/include/music.hh @@ -44,7 +44,7 @@ public: virtual Musical_pitch to_relative_octave (Musical_pitch); /// The duration of this piece of music - virtual Moment duration () const; + virtual Moment length_mom () const; virtual ~Music(){} void print() const; diff --git a/lily/include/musical-request.hh b/lily/include/musical-request.hh index cdc293a5f6..a25dd1d243 100644 --- a/lily/include/musical-request.hh +++ b/lily/include/musical-request.hh @@ -37,7 +37,7 @@ public: bool do_equal_b (Request*) const; void compress (Moment); - virtual Moment duration() const; + virtual Moment length_mom () const; static int compare (Rhythmic_req const&,Rhythmic_req const&); REQUESTMETHODS(Rhythmic_req); }; @@ -88,6 +88,13 @@ struct Melodic_req :virtual Musical_req REQUESTMETHODS(Melodic_req); }; +/// specify tonic of a chord +struct Tonic_req : public Melodic_req +{ + Tonic_req (); + REQUESTMETHODS(Tonic_req); +}; + /// Put a note of specified type, height, and with accidental on the staff. class Note_req : public Rhythmic_req, virtual public Melodic_req { public: @@ -163,21 +170,12 @@ public: class Dynamic_req : public virtual Musical_req { public: - /** - for absolute dynamics - - This sux. We'd want increasing numbers for FFF till PPP, but not - for FP, SF, SFZ (FP is *not* louder than FFF) - */ - enum Loudness { - FFFFFF, FFFFF, FFFF, FFF, FF, F, MF, MP, P, PP, PPP, PPPP, PPPPP, PPPPPP, FP, SF, SFF, SFZ, SP, SPP, RFZ }; - static String loudness_static_str (Loudness); REQUESTMETHODS(Dynamic_req); }; class Absolute_dynamic_req : public Dynamic_req { public: - Loudness loudness_; + String loudness_str_; virtual bool do_equal_b (Request*) const; String loudness_str () const; Absolute_dynamic_req(); diff --git a/lily/include/my-lily-lexer.hh b/lily/include/my-lily-lexer.hh index 91e51c635b..c303c258e9 100644 --- a/lily/include/my-lily-lexer.hh +++ b/lily/include/my-lily-lexer.hh @@ -36,7 +36,7 @@ public: Notename_table *chordmodifier_tab_p_; Notename_table *note_tab_p_; - Array scope_l_arr_; + Link_array scope_l_arr_; Keyword_table * keytable_p_; int errorlevel_i_; diff --git a/lily/include/my-lily-parser.hh b/lily/include/my-lily-parser.hh index 889ccf1bb7..fe5f4480be 100644 --- a/lily/include/my-lily-parser.hh +++ b/lily/include/my-lily-parser.hh @@ -11,7 +11,7 @@ #define MY_LILY_PARSER_HH #include "lily-proto.hh" #include "string.hh" -#include "array.hh" +#include "parray.hh" #include "lily-proto.hh" #include "lily-proto.hh" #include "duration.hh" @@ -36,7 +36,7 @@ public: bool first_b_; - Array pre_reqs, post_reqs; + Link_array pre_reqs, post_reqs; int fatal_error_i_; Sources * source_l_; int error_level_i_; @@ -52,7 +52,7 @@ public: void do_yyparse(); void parser_error (String); - Array* get_parens_request (int t); + Link_array* get_parens_request (int t); void set_debug(); void set_yydebug (bool); diff --git a/lily/include/paper-def.hh b/lily/include/paper-def.hh index df73bea785..4364350592 100644 --- a/lily/include/paper-def.hh +++ b/lily/include/paper-def.hh @@ -86,7 +86,7 @@ public: /** convert a duration to an idealspacing influence using the geometric_ and paratime_signatures. */ - Real duration_to_dist (Moment, Real) const; + Real length_mom_to_dist (Moment, Real) const; Real geometric_spacing (Moment) const; Real arithmetic_constant (Moment minimal_mom) const; Real arithmetic_spacing (Moment mom,Real constant) const; diff --git a/lily/include/paper-outputter.hh b/lily/include/paper-outputter.hh index 42c580768e..6348379e17 100644 --- a/lily/include/paper-outputter.hh +++ b/lily/include/paper-outputter.hh @@ -39,8 +39,6 @@ public: void stop_line (); void switch_to_font (String fontname); - Array font_arr_; - String current_font_; Paper_stream* outstream_l_; }; diff --git a/lily/include/protected-scm.hh b/lily/include/protected-scm.hh index f02ced787b..eafcc54c9c 100644 --- a/lily/include/protected-scm.hh +++ b/lily/include/protected-scm.hh @@ -24,7 +24,7 @@ public: Protected_scm (Protected_scm const &); ~Protected_scm (); Protected_scm &operator = (Protected_scm const &); - operator SCM (); + operator SCM () const; SCM to_SCM () const; }; diff --git a/lily/include/repeat-engraver.hh b/lily/include/repeat-engraver.hh index cef330a718..ba5ac43066 100644 --- a/lily/include/repeat-engraver.hh +++ b/lily/include/repeat-engraver.hh @@ -37,6 +37,7 @@ private: Array stop_mom_arr_; Array alternative_start_mom_arr_; Array alternative_stop_mom_arr_; + Array alternative_str_arr_; }; #endif // REPEAT_ENGRAVER_HH diff --git a/lily/include/repeated-music-iterator.hh b/lily/include/repeated-music-iterator.hh index 1e8c48a2d4..9f8b720132 100644 --- a/lily/include/repeated-music-iterator.hh +++ b/lily/include/repeated-music-iterator.hh @@ -23,11 +23,8 @@ public: virtual bool ok () const; protected: - virtual Repeated_music* repeated_music_l () const; - virtual void do_print () const; virtual void do_process_and_next (Moment); - private: void start_next_element (); diff --git a/lily/include/repeated-music.hh b/lily/include/repeated-music.hh index 6175d45864..5e2e2b28c7 100644 --- a/lily/include/repeated-music.hh +++ b/lily/include/repeated-music.hh @@ -29,7 +29,7 @@ public: virtual void do_print () const; virtual void transpose (Musical_pitch p); - virtual Moment duration () const; + virtual Moment length_mom () const; virtual Musical_pitch to_relative_octave (Musical_pitch p); VIRTUAL_COPY_CONS(Music); }; diff --git a/lily/include/request-iterator.hh b/lily/include/request-iterator.hh index d374d5929f..4d078dca46 100644 --- a/lily/include/request-iterator.hh +++ b/lily/include/request-iterator.hh @@ -18,9 +18,9 @@ class Request_chord_iterator : public Music_iterator { Request_chord * elt_l () const; /** - cache elt_l ()->duration (). + cache elt_l ()->length_mom (). */ - Moment elt_duration_; + Moment elt_length_mom_; bool last_b_; public: diff --git a/lily/include/rhythmic-grouping.hh b/lily/include/rhythmic-grouping.hh new file mode 100644 index 0000000000..edccad7baf --- /dev/null +++ b/lily/include/rhythmic-grouping.hh @@ -0,0 +1,60 @@ +/* + rhythmic-grouping.hh -- part of GNU LilyPond + + (c) 1996--1998 Han-Wen Nienhuys +*/ + +#ifndef RHYTHMIC_GROUPING_HH +#define RHYTHMIC_GROUPING_HH + +#include "minterval.hh" +#include "parray.hh" + +/** data structure which represents rhythmic units this is a tree. It groupes notes according to rules + + TODO Documentation. Unhairing + */ +struct Rhythmic_grouping { + Link_array children; + MInterval *interval_; + + + Array intervals(); + MInterval interval() const; + Moment length_mom () const; + void intersect (MInterval); + + void operator=(Rhythmic_grouping const&); + Rhythmic_grouping (Rhythmic_grouping const&); + Rhythmic_grouping (MInterval, int n=1); + Rhythmic_grouping(); + Rhythmic_grouping (Link_array); + ~Rhythmic_grouping(); + + void add_child (Moment start, Moment len); + bool child_fit_b (Moment start); + void split (Rhythmic_grouping r); + void split (Array); + void split (int n); + + void print() const; + void OK() const; + + Array generate_beams (Array, int&); + + /** multiply self to span #i#. + In implementation, this isn't really const, but conceptually it is. + */ + void extend (MInterval i) const; + void translate (Moment); +private: + void init(); + void junk(); + void copy (Rhythmic_grouping const&); +}; + + +Rhythmic_grouping parse_grouping (Array beat_i_arr, Array elt_length_arr); + + +#endif // RHYTHMIC_GROUPING_HH diff --git a/lily/include/score-element-info.hh b/lily/include/score-element-info.hh index 19586ede51..594e811452 100644 --- a/lily/include/score-element-info.hh +++ b/lily/include/score-element-info.hh @@ -12,7 +12,7 @@ #include "scalar.hh" #include "lily-proto.hh" -#include "array.hh" +#include "parray.hh" /** Data container for broadcasts @@ -20,7 +20,7 @@ struct Score_element_info { Score_element * elem_l_; Music *req_l_; - Array origin_grav_l_arr_; + Link_array origin_grav_l_arr_; Score_element_info (Score_element*, Music*); Score_element_info(); diff --git a/lily/include/script-def.hh b/lily/include/script-def.hh index 1bf61fd493..e7f7697a49 100644 --- a/lily/include/script-def.hh +++ b/lily/include/script-def.hh @@ -34,7 +34,7 @@ public: virtual Direction rel_stem_dir() const; virtual int priority_i() const; virtual bool inside_b() const; - virtual Atom get_atom (Paper_def* p, Direction dir_) const; + virtual Molecule get_molecule (Paper_def* p, Direction dir_) const; virtual bool do_equal_b (General_script_def const *) const; diff --git a/lily/include/script-engraver.hh b/lily/include/script-engraver.hh index afef25c8b7..5e009bbfa3 100644 --- a/lily/include/script-engraver.hh +++ b/lily/include/script-engraver.hh @@ -12,8 +12,8 @@ class Script_engraver : public Engraver { - Array