From: Jan Nieuwenhuizen Date: Thu, 21 Apr 2005 14:28:31 +0000 (+0000) Subject: * scm/auto-beam.scm (revert-property-setting): Bugfixes: add X-Git-Tag: release/2.5.21~19 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=a98b4affe11787c3e30b1e23dd363de64b940a80;p=lilypond.git * scm/auto-beam.scm (revert-property-setting): Bugfixes: add missing parameter, actualy cdr through list. Actually return a list with ENTRY removed (was '()). * scripts/convert-ly.py: Update. Print warning if file cannot be opened. (do_conversion): Fix printing of continuation comma. * Documentation/user/advanced-notation.itely (Beam formatting): Remove refbugs about compound time and mixed duration. * scm/auto-beam.scm (default-auto-beam-settings): Write out all modulo moments explicitely. * lily/moment.cc (operator %): New function. * lily/moment-scheme.cc (ly:mod-moment): Wrap it. * lily/translator-scheme.cc (ly:translator-now, ly:translator-property): New function. * scm/auto-beam.scm (default-auto-beam-check): New function. * lily/auto-beam-engraver.cc (test_moment): Use it. * flower/rational.cc (operator %): Bugfix. --- diff --git a/ChangeLog b/ChangeLog index c6b24027b5..d5fbe3e4c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2005-04-21 Jan Nieuwenhuizen + + * scm/auto-beam.scm (revert-property-setting): Bugfixes: add + missing parameter, actualy cdr through list. Actually return a + list with ENTRY removed (was '()). + + * scripts/convert-ly.py: Update. Print warning if file cannot be + opened. + (do_conversion): Fix printing of continuation comma. + + * Documentation/user/advanced-notation.itely (Beam formatting): + Remove refbugs about compound time and mixed duration. + + * scm/auto-beam.scm (default-auto-beam-settings): Write out all + modulo moments explicitely. + + * lily/moment.cc (operator %): New function. + + * lily/moment-scheme.cc (ly:mod-moment): Wrap it. + + * lily/translator-scheme.cc (ly:translator-now, + ly:translator-property): New function. + + * scm/auto-beam.scm (default-auto-beam-check): New function. + + * lily/auto-beam-engraver.cc (test_moment): Use it. + + * flower/rational.cc (operator %): Bugfix. + 2005-04-21 Erik Sandberg * scripts/abc2ly: Bugfix @@ -22,6 +51,11 @@ 2005-04-20 Jan Nieuwenhuizen + * SConstruct (test_lib): Bump mftrace requirement to 1.1.9. + + * lily/auto-beam-engraver.cc (test_moment): Test exact measure + position (was: use modulo measure length). + * configure.in (no gui_b): Remove optional gtk+ requirement. 2005-04-20 Han-Wen Nienhuys diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index 3563854786..ba7b855b6e 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -57,12 +57,17 @@ markup texts. There is a music function @code{\musicDisplay}, which will display a music expression as indented Scheme code. +@item +Automatic beaming is now specified explicitly for each moment +throughout a measure, which enables automatic beaming in compound +measures, as demonstrated in the following item. + @item A plus sign was added to the number font. This enables printing of compound time signatures @lilypondfile[]{compound-time.ly} - + @item A new @code{\circle} markup command allows for all kinds of circled texts diff --git a/Documentation/user/advanced-notation.itely b/Documentation/user/advanced-notation.itely index 172fe997dd..524a02e675 100644 --- a/Documentation/user/advanced-notation.itely +++ b/Documentation/user/advanced-notation.itely @@ -1909,7 +1909,7 @@ also possible to adjust settings at higher contexts, by adding a equal to @code{override-auto-beam-setting} with the argument @var{context} set to @code{'Score}. -For example, if automatic beams should end on every quarter note, use +For example, if automatic beams should end on the first quarter note, use the following @example #(override-auto-beam-setting '(end * * * *) 1 4 'Staff) @@ -1917,10 +1917,22 @@ the following Since the duration of a quarter note is 1/4 of a whole note, it is entered as @code{(ly:make-moment 1 4)}. +If automatic beams should end on every quarter in 5/4 time, specify +all endings +@example +#(override-auto-beam-setting '(end * * * *) 1 4 'Staff) +#(override-auto-beam-setting '(end * * * *) 1 2 'Staff) +#(override-auto-beam-setting '(end * * * *) 3 4 'Staff) +#(override-auto-beam-setting '(end * * * *) 5 4 'Staff) +@dots{} +@end example + The same syntax can be used to specify beam starting points. In this example, automatic beams can only end on a dotted quarter note @example #(override-auto-beam-setting '(end * * * *) 3 8) +#(override-auto-beam-setting '(end * * * *) 1 2) +#(override-auto-beam-setting '(end * * * *) 7 8) @end example In 4/4 time signature, this means that automatic beams could end only on 3/8 and on the fourth beat of the measure (after 3/4, that is 2 times @@ -1965,26 +1977,6 @@ same holds polyphonic voices, entered with @code{<< @dots{} \\ @dots{} >>}. If a polyphonic voice ends while an automatic beam is still accepting notes, it is not typeset. -The rules for ending a beam depend on the shortest note in a beam. -So, while it is possible to have different ending rules for eight -beams and sixteenth beams, a beam that contains both eight and -sixteenth notes will use the rules for the sixteenth beam. - -In the example below, the autobeamer makes eighth beams and sixteenth -end at three eighths. The third beam can only be corrected by -specifying manual beaming. - -@lilypond[quote,raggedright,fragment,relative=1] -#(override-auto-beam-setting '(end * * * *) 3 8) -% rather show case where it goes wrong -%\time 12/8 c'8 c c c16 c c c c c c[ c c c] c8[ c] c4 -\time 12/8 c'8 c c c16 c c c c c c c c c c8 c c4 -@end lilypond -It is not possible to specify beaming parameters that act differently in -different parts of a measure. This means that it is not possible to use -automatic beaming in irregular meters such as @code{5/8}. - - @node Beam formatting @subsection Beam formatting diff --git a/SConstruct b/SConstruct index 0095768056..d4c847f046 100644 --- a/SConstruct +++ b/SConstruct @@ -339,7 +339,7 @@ def configure (target, source, env): test_program (required, 'guile-config', '1.6', 'GUILE development', 'libguile-dev or guile-devel') test_program (required, 'mf', '0.0', 'Metafont', 'tetex-bin') - test_program (required, 'mftrace', '1.1.6', + test_program (required, 'mftrace', '1.1.9', 'mftrace (http://xs4all.nl/~hanwen/mftrace)', 'mftrace') test_program (required, 'potrace', '0.0', 'Potrace', 'potrace') test_program (required, 'python', '2.1', 'Python (www.python.org)', diff --git a/flower/rational.cc b/flower/rational.cc index c5634402b1..ec39ad307c 100644 --- a/flower/rational.cc +++ b/flower/rational.cc @@ -140,10 +140,7 @@ Rational::compare (Rational const &r, Rational const &s) return 0; else if (r.sign_ == 0) return 0; - else - { - return r.sign_ * ::sign (int (r.num_ * s.den_) - int (s.num_ * r.den_)); - } + return r.sign_ * ::sign (int (r.num_ * s.den_) - int (s.num_ * r.den_)); } int @@ -155,7 +152,7 @@ compare (Rational const &r, Rational const &s) Rational & Rational::operator %= (Rational r) { - *this = r.mod_rat (r); + *this = mod_rat (r); return *this; } @@ -165,9 +162,7 @@ Rational::operator += (Rational r) if (is_infinity ()) ; else if (r.is_infinity ()) - { - *this = r; - } + *this = r; else { int n = sign_ * num_ * r.den_ + r.sign_ * den_ * r.num_; diff --git a/input/mutopia/E.Satie/petite-ouverture-a-danser.ly b/input/mutopia/E.Satie/petite-ouverture-a-danser.ly index 28fd54b8c7..f02ac54c6c 100644 --- a/input/mutopia/E.Satie/petite-ouverture-a-danser.ly +++ b/input/mutopia/E.Satie/petite-ouverture-a-danser.ly @@ -149,8 +149,6 @@ lower = \context Staff \relative c{ \clef bass \lower >> - #(override-auto-beam-setting '(end 1 8 * *) 1 4) - #(override-auto-beam-setting '(end 1 16 * *) 1 4) >> \layout { \context { diff --git a/input/regression/beam-auto.ly b/input/regression/beam-auto.ly index 96fea7e641..5f9932c038 100644 --- a/input/regression/beam-auto.ly +++ b/input/regression/beam-auto.ly @@ -1,64 +1,61 @@ \version "2.4.0" \header{ - texidoc = "@cindex Beaming Presets + texidoc = "@cindex Beaming Presets There are presets for the @code{auto-beam} engraver in the case of common time signatures. " } -\score{ - \relative c''{ - \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 +\relative 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 - } - \layout{ - } + \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 } diff --git a/input/test/beam-auto-4-8.ly b/input/test/beam-auto-4-8.ly index 43d66eeef2..4544c29c4d 100644 --- a/input/test/beam-auto-4-8.ly +++ b/input/test/beam-auto-4-8.ly @@ -1,15 +1,17 @@ -\version "2.4.0" -% keep for now, although merging into beam-auto-override is a possibility. +%% \version "2.5.21" + +%% keep for now, although merging into beam-auto-override is a possibility. \header { texidoc = "@cindex Auto Beaming 4/8 You can override the automatic beaming settings. " } -\score{ - \relative c''{ - \time 4/8 +\layout{raggedright = ##t} + +\relative c''{ + \time 4/8 %{ the default for 4/8 (see scm/auto-beam.scm) @@ -17,8 +19,7 @@ You can override the automatic beaming settings. | | | |--| x| x| x| x| x| %} - c8 c c c16 c - + c8 c c c16 c %{ user override @@ -26,11 +27,13 @@ You can override the automatic beaming settings. | | | |--| x| x| x| x| x| %} - #(override-auto-beam-setting '(end * * * *) 2 4) - c8 c c c16 c - - } -\layout{raggedright = ##t} + %% This has now (2.5.21) changed, (end * * * *) no longer + %% masks the default config entry ('(end * * 4 8) 1 4)) + %% rather than masking by override: + %% #(override-auto-beam-setting '(end * * * *) 2 4) + %% revert the config file setting. + #(revert-auto-beam-setting '(end * * 4 8) 1 4) + c8 c c c16 c } diff --git a/input/test/beam-auto-override.ly b/input/test/beam-auto-override.ly index a674cd1cf0..3c816cf01b 100644 --- a/input/test/beam-auto-override.ly +++ b/input/test/beam-auto-override.ly @@ -1,5 +1,7 @@ -\version "2.4.0" +%% ugh +%% \version "2.5.21" + \header { texidoc = "@cindex Auto Beaming Override @@ -7,7 +9,7 @@ The auto-beamer, which can be overridden, will only engrave beams that end before encountering of @itemize @bullet -@item a rest, +@item a rest, @item an other, manually entered beam, or @item @@ -22,27 +24,32 @@ The @code{autoBeaming} can also be turned off. %% TODO: check doc string. -hw -\score{ - \relative c''{ - #(override-auto-beam-setting '(end * * * *) 1 2) - \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 - #(override-auto-beam-setting '(end * * * *) 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 - \set autoBeaming = ##f - c8 c c c - } - \layout{raggedright = ##t} +\layout{raggedright = ##t} +\relative c''{ + %% This has now (2.5.21) changed, (end * * * *) no longer + %% masks the default config entry ('(end * * 2 4) 1 4)) + %% rather than masking by override: + %% #(override-auto-beam-setting '(end * * * *) 1 2) + %% revert the config file setting. + #(revert-auto-beam-setting '(end * * 2 4) 1 4) + \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 + #(override-auto-beam-setting '(end * * * *) 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 + \set autoBeaming = ##f + c8 c c c } diff --git a/input/test/beam-count.ly b/input/test/beam-count.ly index 816f9c174e..024464c588 100644 --- a/input/test/beam-count.ly +++ b/input/test/beam-count.ly @@ -1,5 +1,5 @@ -\version "2.4.0" +%%\version "2.5.21" \header{ texidoc="@cindex Beam Count @@ -11,7 +11,13 @@ two sets of four 32nds are joined, as if they were 8th notes. \layout { raggedright = ##t} \relative { - #(override-auto-beam-setting '(end * * * *) 1 4) + %% This has now (2.5.21) changed, (end * * * *) no longer + %% masks the default config entry ('(end * * 2 4) 1 4)) + %% rather than masking by override: + %% #(override-auto-beam-setting '(end * * * *) 1 4) + %% revert the config file settings. + #(revert-auto-beam-setting '(end 1 32 4 4) 1 8) + #(revert-auto-beam-setting '(end 1 32 4 4) 3 8) f32 g a b b a g f f32 g a diff --git a/input/test/compound-time.ly b/input/test/compound-time.ly index 43366dc6b0..0bf588441a 100644 --- a/input/test/compound-time.ly +++ b/input/test/compound-time.ly @@ -4,7 +4,8 @@ texidoc = "@cindex compound time @cindex plus -Compound time signatures can be printed. +Compound time signatures can be printed. Automatic beaming works in +compound time. " } @@ -19,20 +20,13 @@ Compound time signatures can be printed. (font-family . number))) (markup #:line ( #:column (one num) #:lower 1 "+" #:column (two num))))) -% ;; #:line ( #:column (one num) #:lower 1 "+" #:column (two num))))) \relative { %% compound time signature hack \time 5/8 \override Staff.TimeSignature #'print-function = #(lambda (grob) (compound-time grob "2" "3" "8")) - - %% manual beaming, auto beam engraver cannot handle compound time, - %% it extends 2/8 pattern to 4/8, which does not work. - - %% Hmm, why don't we just junk the modulo functionality, and - %% write-out all endings explicitely, we get compound time handling - %% for free? - - c4 c8[ c c] + #(override-auto-beam-setting '(end 1 8 5 8) 1 4) + c8 c c8 c c } + diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 670d77d496..1a79419ad9 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -108,141 +108,16 @@ Auto_beam_engraver::try_music (Music *m) return false; } -/* - Determine end moment for auto beaming (or begin moment, but mostly - 0== anywhere) In order of increasing priority: - - i. begin anywhere, end at every beat - ii. end * - iii. end - - iv. end * * * - v. end * * - - - 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 - - [user override] - iv. generic override - v. override for specific duration type -*/ bool -Auto_beam_engraver::test_moment (Direction dir, Moment test_mom) +Auto_beam_engraver::test_moment (Direction dir, Moment test) { - Moment now = now_mom (); - if (dir == START - && now.grace_part_) - { - return false; - } - - SCM wild = scm_list_n (ly_symbol2scm ("*"), ly_symbol2scm ("*"), SCM_UNDEFINED); - SCM function; - if (dir == START) - function = scm_list_n (ly_symbol2scm ("begin"), SCM_UNDEFINED); - else - function = scm_list_n (ly_symbol2scm ("end"), SCM_UNDEFINED); - - Moment beat_length (1, 4); - if (Moment *m = unsmob_moment (get_property ("beatLength"))) - { - beat_length = *m; - } - Moment measure_length (1, 1); - int num = 4; - if (Moment *m = unsmob_moment (get_property ("measureLength"))) - { - num = int ((*m / beat_length).main_part_); - } - - int den = beat_length.den (); - SCM time = scm_list_n (scm_int2num (num), scm_int2num (den), SCM_UNDEFINED); - - SCM type = scm_list_n (scm_int2num (test_mom.num ()), - scm_int2num (test_mom.den ()), SCM_UNDEFINED); - - /* - UGH UGH. - settings aren't grob-properties. - */ - SCM settings = get_property ("autoBeamSettings"); - - /* first guess */ - - /* begin beam at any position - (and fallback for end) */ - Moment moment (0); - - /* end beam at end of beat */ - if (dir == STOP) - { - moment = robust_scm2moment (get_property ("beatLength"), moment); - } - - /* second guess: property generic time exception */ - SCM m = scm_assoc (ly_append3 (function, wild, time), settings); - - if (m != SCM_BOOL_F && unsmob_moment (scm_cdr (m))) - moment = *unsmob_moment (scm_cdr (m)); - - /* third guess: property time exception, specific for duration type */ - m = scm_assoc (ly_append3 (function, type, time), settings); - if (m != SCM_BOOL_F && unsmob_moment (scm_cdr (m))) - moment = *unsmob_moment (scm_cdr (m)); - - /* fourth guess [user override]: property plain generic */ - m = scm_assoc (ly_append3 (function, wild, wild), settings); - if (m != SCM_BOOL_F && unsmob_moment (scm_cdr (m))) - moment = *unsmob_moment (scm_cdr (m)); - - /* fifth guess [user override]: property plain, specific for duration type */ - m = scm_assoc (ly_append3 (function, type, wild), settings); - if (m != SCM_BOOL_F && unsmob_moment (scm_cdr (m))) - moment = *unsmob_moment (scm_cdr (m)); - - Rational r; - if (moment.to_bool ()) - { - /* Ugh? measurePosition can be negative, when \partial - We may have to fix this elsewhere (timing translator) - r = unsmob_moment (get_property ("measurePosition"))->mod_rat (moment); - */ - Moment pos (0); - if (Moment *m = unsmob_moment (get_property ("measurePosition"))) - { - pos = *m; - } - - if (pos < Moment (0)) - { - Moment length (1); - - if (Moment *m = unsmob_moment (get_property ("measureLength"))) - { - length = *m; - } - pos = length - pos; - } - r = pos.main_part_.mod_rat (moment.main_part_); - } - else - { - if (dir == START) - /* if undefined, starting is ok */ - r = 0; - else - /* but ending is not */ - r = 1; - } - - return !r; + return scm_call_3 (get_property ("autoBeamCheck"), + self_scm (), + scm_from_int (dir), + test.smobbed_copy ()) + != SCM_BOOL_F; } - + void Auto_beam_engraver::consider_begin (Moment test_mom) { diff --git a/lily/include/moment.hh b/lily/include/moment.hh index 2192680b89..ba8164f031 100644 --- a/lily/include/moment.hh +++ b/lily/include/moment.hh @@ -33,6 +33,7 @@ public: void operator *= (Moment const &m); void operator /= (Moment const &m); + void operator %= (Moment const &m); Rational main_part_; Rational grace_part_; @@ -53,6 +54,7 @@ IMPLEMENT_ARITHMETIC_OPERATOR (Moment, +); IMPLEMENT_ARITHMETIC_OPERATOR (Moment, -); IMPLEMENT_ARITHMETIC_OPERATOR (Moment, /); IMPLEMENT_ARITHMETIC_OPERATOR (Moment, *); +IMPLEMENT_ARITHMETIC_OPERATOR (Moment, %); DECLARE_UNSMOB (Moment, moment); int compare (Moment const &, Moment const &); diff --git a/lily/moment-scheme.cc b/lily/moment-scheme.cc index 9c924a90cf..831ace9215 100644 --- a/lily/moment-scheme.cc +++ b/lily/moment-scheme.cc @@ -75,6 +75,17 @@ LY_DEFINE (ly_div_moment, "ly:div-moment", return (*ma / * mb).smobbed_copy (); } +LY_DEFINE (ly_mod_moment, "ly:mod-moment", + 2, 0, 0, (SCM a, SCM b), + "Modulo of two moments.") +{ + Moment *ma = unsmob_moment (a); + Moment *mb = unsmob_moment (b); + SCM_ASSERT_TYPE (ma, a, SCM_ARG1, __FUNCTION__, "moment"); + SCM_ASSERT_TYPE (mb, b, SCM_ARG2, __FUNCTION__, "moment"); + return (*ma % * mb).smobbed_copy (); +} + LY_DEFINE (ly_moment_grace_numerator, "ly:moment-grace-numerator", 1, 0, 0, (SCM mom), diff --git a/lily/moment.cc b/lily/moment.cc index a50ce3cbd1..8b866922a8 100644 --- a/lily/moment.cc +++ b/lily/moment.cc @@ -96,6 +96,7 @@ Moment::operator += (Moment const &src) main_part_ += src.main_part_; grace_part_ += src.grace_part_; } + void Moment::operator -= (Moment const &src) { @@ -103,9 +104,7 @@ Moment::operator -= (Moment const &src) grace_part_ -= src.grace_part_; } -/* - only take the main part of SRC for multiplication. -*/ +/* Only take the main part of SRC for multiplication. */ void Moment::operator *= (Moment const &src) { @@ -113,9 +112,7 @@ Moment::operator *= (Moment const &src) grace_part_ *= src.main_part_; } -/* - only take the main part of SRC for multiplication. -*/ +/* Only take the main part of SRC for division. */ void Moment::operator /= (Moment const &src) { @@ -123,6 +120,14 @@ Moment::operator /= (Moment const &src) grace_part_ /= src.main_part_; } +/* Only take the main part of SRC for division. */ +void +Moment::operator %= (Moment const &src) +{ + main_part_ %= src.main_part_; + grace_part_ %= src.main_part_; +} + int Moment::den () const { diff --git a/lily/translator-scheme.cc b/lily/translator-scheme.cc index cec56a0a76..fa4774bc6a 100644 --- a/lily/translator-scheme.cc +++ b/lily/translator-scheme.cc @@ -8,6 +8,7 @@ #include "context-def.hh" #include "translator-group.hh" +#include "moment.hh" LY_DEFINE (ly_translator_name, "ly:translator-name", 1, 0, 0, (SCM trans), @@ -20,6 +21,15 @@ LY_DEFINE (ly_translator_name, "ly:translator-name", return ly_symbol2scm (nm); } +LY_DEFINE (ly_translator_now, "ly:translator-now", + 1, 0, 0, (SCM trans), + "Return now-moment of translater TRANS") +{ + Translator *tr = unsmob_translator (trans); + SCM_ASSERT_TYPE (tr, trans, SCM_ARG1, __FUNCTION__, "Translator"); + return tr->now_mom ().smobbed_copy (); +} + LY_DEFINE (ly_translator_description, "ly:translator-description", 1, 0, 0, (SCM me), "Return an alist of properties of translator @var{me}.") @@ -29,6 +39,20 @@ LY_DEFINE (ly_translator_description, "ly:translator-description", return tr->translator_description (); } +LY_DEFINE (ly_translator_property, "ly:translator-property", + 2, 0, 0, (SCM translator, SCM sym), + "Return the value of a value in translator @var{g} of property @var{sym}. " + "It will return @code{' ()} (end-of-list) " + "if @var{sym} is undefined in @var{g}." + "\n\n") +{ + Translator *sc = unsmob_translator (translator); + SCM_ASSERT_TYPE (sc, translator, SCM_ARG1, __FUNCTION__, "translator"); + SCM_ASSERT_TYPE (scm_is_symbol (sym), sym, SCM_ARG2, __FUNCTION__, "symbol"); + + return sc->internal_get_property (sym); +} + int Translator::print_smob (SCM s, SCM port, scm_print_state *) { diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 7fd0abefd4..4091ec98fd 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -467,6 +467,7 @@ AncientRemoveEmptyStaffContext = \context { explicitKeySignatureVisibility = #all-visible autoBeamSettings = #default-auto-beam-settings autoBeaming = ##t + autoBeamCheck = #default-auto-beam-check scriptDefinitions = #default-script-alist verticalAlignmentChildCallback = #Align_interface::alignment_callback diff --git a/scm/auto-beam.scm b/scm/auto-beam.scm index fe867dff82..806287d171 100644 --- a/scm/auto-beam.scm +++ b/scm/auto-beam.scm @@ -21,91 +21,124 @@ ;;; maybe do: '(end shortest-1 16 time-3 4) ? -;;; in 3 2 time: -;;; end beams each 1 2 note -;;; end beams with 16th notes each 1 4 note -;;; end beams with 32th notes each 1 8 note - (define-public default-auto-beam-settings - `( - ((end * * 3 2) . ,(ly:make-moment 1 2)) - ((end 1 16 3 2) . ,(ly:make-moment 1 4)) - ((end 1 32 3 2) . ,(ly:make-moment 1 8)) - - ((begin 1 8 3 4) . ,(ly:make-moment 1 4)) - - ((end * * 3 4) . ,(ly:make-moment 3 4)) - ((begin 1 16 3 4) . ,(ly:make-moment 1 16)) - ((end 1 16 3 4) . ,(ly:make-moment 1 4)) - ;;((begin 1 32 3 4) . ,(ly:make-moment 1 8)) - ((end 1 32 3 4) . ,(ly:make-moment 1 8)) - - ((begin 1 16 3 8) . ,(ly:make-moment 1 8)) - ((end * * 3 8) . ,(ly:make-moment 3 8)) - - ;; in common time: - ;; end beams each 1 2 note - ;; end beams with 32th notes each 1 8 note - ;; end beams with 1 8 triplets each 1 4 note - - ((end * * 4 4) . ,(ly:make-moment 1 2)) - ((end 1 12 4 4) . ,(ly:make-moment 1 4)) - ((end 1 16 4 4) . ,(ly:make-moment 1 4)) - ((end 1 32 4 4) . ,(ly:make-moment 1 8)) - - ((end * * 2 4) . ,(ly:make-moment 1 4)) - ((end 1 12 2 4) . ,(ly:make-moment 1 4)) - ((end 1 16 2 4) . ,(ly:make-moment 1 4)) - ((end 1 32 2 4) . ,(ly:make-moment 1 8)) - - ;; It seems that, because of a bug in the previous auto-beamer, - ;; we had the effect of this setting x - ;; ((end * * 2 8) . ,(ly:make-moment 2 8)) - - ((end * * 4 8) . ,(ly:make-moment 1 4)) - ((end 1 16 4 8) . ,(ly:make-moment 1 4)) - ((end 1 32 4 8) . ,(ly:make-moment 1 8)) - - ((end * * 4 16) . ,(ly:make-moment 1 8)) - - ((end * * 6 8) . ,(ly:make-moment 3 8)) - ((end 1 16 6 8) . ,(ly:make-moment 3 8)) - ((end 1 32 6 8) . ,(ly:make-moment 1 8)) - - ((end * * 9 8) . ,(ly:make-moment 3 8)) - ((end 1 16 9 8) . ,(ly:make-moment 3 8)) - ((end 1 32 9 8) . ,(ly:make-moment 1 8)) - - ((end * * 12 8) . ,(ly:make-moment 3 8)) - ((end 1 16 12 8) . ,(ly:make-moment 3 8)) - ((end 1 32 12 8) . ,(ly:make-moment 1 8)) - )) - - -(define (override-property-setting context context-prop setting value) + `( + ;; in 3 2 time: + ;; end beams each 1 2 note + ;; end beams with 16th notes each 1 4 note + ;; end beams with 32th notes each 1 8 note + + ((end * * 3 2) . ,(ly:make-moment 1 2)) + ((end * * 3 2) . ,(ly:make-moment 2 2)) + + ((end 1 16 3 2) . ,(ly:make-moment 1 4)) + ((end 1 16 3 2) . ,(ly:make-moment 1 2)) + ((end 1 16 3 2) . ,(ly:make-moment 3 4)) + ((end 1 16 3 2) . ,(ly:make-moment 5 4)) + + ((end 1 32 3 2) . ,(ly:make-moment 1 8)) + ((end 1 32 3 2) . ,(ly:make-moment 1 4)) + ((end 1 32 3 2) . ,(ly:make-moment 3 8)) + ((end 1 32 3 2) . ,(ly:make-moment 1 2)) + ((end 1 32 3 2) . ,(ly:make-moment 5 8)) + ((end 1 32 3 2) . ,(ly:make-moment 3 4)) + ((end 1 32 3 2) . ,(ly:make-moment 9 8)) + ((end 1 32 3 2) . ,(ly:make-moment 5 4)) + ((end 1 32 3 2) . ,(ly:make-moment 11 8)) + + ((end * * 3 4) . ,(ly:make-moment 3 4)) + + ((end 1 16 3 4) . ,(ly:make-moment 1 4)) + ((end 1 16 3 4) . ,(ly:make-moment 1 2)) + + ((end 1 32 3 4) . ,(ly:make-moment 1 8)) + ((end 1 32 3 4) . ,(ly:make-moment 1 4)) + ((end 1 32 3 4) . ,(ly:make-moment 3 8)) + ((end 1 32 3 4) . ,(ly:make-moment 1 2)) + ((end 1 32 3 4) . ,(ly:make-moment 5 8)) + + ((end * * 3 8) . ,(ly:make-moment 3 8)) + + ;; in common time: + ;; end beams each 1 2 note + ;; end beams with 32th notes each 1 8 note + ;; end beams with 1 8 triplets each 1 4 note + + ((end * * 4 4) . ,(ly:make-moment 1 2)) + ((end 1 12 4 4) . ,(ly:make-moment 1 4)) + ((end 1 12 4 4) . ,(ly:make-moment 3 4)) + + ((end 1 16 4 4) . ,(ly:make-moment 1 4)) + ((end 1 16 4 4) . ,(ly:make-moment 3 4)) + + ((end 1 32 4 4) . ,(ly:make-moment 1 8)) + ((end 1 32 4 4) . ,(ly:make-moment 1 4)) + ((end 1 32 4 4) . ,(ly:make-moment 3 8)) + ((end 1 32 4 4) . ,(ly:make-moment 5 8)) + ((end 1 32 4 4) . ,(ly:make-moment 3 4)) + ((end 1 32 4 4) . ,(ly:make-moment 7 8)) + + ((end * * 2 4) . #f) ;; switch-off at-any-beat feature + ((end * * 2 4) . ,(ly:make-moment 1 4)) + ((end 1 32 2 4) . ,(ly:make-moment 1 8)) + ((end 1 32 2 4) . ,(ly:make-moment 3 8)) + + ((end * * 4 8) . #f) ;; switch-off at-any-beat feature + ((end * * 4 8) . ,(ly:make-moment 1 4)) + ((end 1 32 4 8) . ,(ly:make-moment 1 8)) + ((end 1 32 4 8) . ,(ly:make-moment 3 8)) + + ((end * * 4 16) . #f) ;; switch-off at-any-beat feature + ((end * * 4 16) . ,(ly:make-moment 1 8)) + + ((end * * 6 8) . #f) ;; switch-off at-any-beat feature + ((end * * 6 8) . ,(ly:make-moment 3 8)) + ((end 1 32 6 8) . ,(ly:make-moment 1 8)) + ((end 1 32 6 8) . ,(ly:make-moment 1 4)) + ((end 1 32 6 8) . ,(ly:make-moment 1 2)) + ((end 1 32 6 8) . ,(ly:make-moment 5 8)) + + ((end * * 9 8) . #f) ;; switch-off at-any-beat feature + ((end * * 9 8) . ,(ly:make-moment 3 8)) + ((end * * 9 8) . ,(ly:make-moment 3 4)) + ((end 1 32 9 8) . ,(ly:make-moment 1 8)) + ((end 1 32 9 8) . ,(ly:make-moment 1 4)) + ((end 1 32 9 8) . ,(ly:make-moment 1 2)) + ((end 1 32 9 8) . ,(ly:make-moment 5 8)) + ((end 1 32 9 8) . ,(ly:make-moment 7 8)) + ((end 1 32 9 8) . ,(ly:make-moment 1 1)) + ((end 1 32 9 8) . ,(ly:make-moment 9 8)) + + ((end * * 12 8) . #f) ;; switch-off at-every-beat + ((end * * 12 8) . ,(ly:make-moment 3 8)) + ((end * * 12 8) . ,(ly:make-moment 3 4)) + ((end * * 12 8) . ,(ly:make-moment 9 8)) + ((end * * 12 8) . ,(ly:make-moment 2 1)) + ((end 1 32 12 8) . ,(ly:make-moment 1 8)) + )) + +(define (override-property-setting context property setting value) "Like the C++ code that executes \\override, but without type checking. " + (ly:context-set-property! + context property + (cons (cons setting value) (ly:context-property context property)))) - (ly:context-set-property! context context-prop - (cons (cons setting value) - (ly:context-property context context-prop)))) - -(define (revert-property-setting context setting) +(define (revert-property-setting context property setting) "Like the C++ code that executes \revert, but without type checking. " - (define (revert-assoc alist key) - "Return ALIST, with KEY removed. ALIST is not modified, instead -a fresh copy of the list-head is made." + (define (revert-member alist entry new) + "Return ALIST, with ENTRY removed. ALIST is not modified, instead +a fresh copy of the list-head is made." (cond - ((null? alist) '()) - ((equal? (caar alist) key) (cdr alist)) - (else (cons (car alist) (revert-assoc alist key))))) + ((null? alist) new) + ((equal? (car alist) entry) (revert-member (cdr alist) entry new)) + (else (revert-member (cdr alist) entry (cons (car alist) new))))) - (ly:context-set-property! - context context-prop - (revert-assoc (ly:context-property context context-prop) - setting))) + (ly:context-set-property! + context property + (revert-member (ly:context-property context property) setting '()))) (define-public (override-auto-beam-setting setting num den . rest) (ly:export @@ -121,13 +154,79 @@ a fresh copy of the list-head is made." (define-public (score-override-auto-beam-setting setting num den) (override-auto-beam-setting setting num den 'Score)) -(define-public (revert-auto-beam-setting setting . rest) +(define-public (revert-auto-beam-setting setting num den . rest) (ly:export (context-spec-music (make-apply-context (lambda (c) (revert-property-setting c 'autoBeamSettings - setting))) + (cons setting (ly:make-moment num den))))) (if (and (pair? rest) (symbol? (car rest))) (car rest) 'Voice)))) + +;; Determine end moment for auto beaming (or begin moment, but mostly +;; 0== anywhere). In order of decreasing priority: +;; +;; 1. end * * +;; 2. end * * * +;; 3. end +;; 4. end * +;; 5. if 1-4 not specified: begin anywhere, end at every beat +;; +;; Rationale: +;; +;; [user override] +;; 1. override for specific duration type +;; 2. generic override +;; +;; [to be defined in config file] +;; 3. exceptions for specific time signature, for specific duration type +;; 4. exceptions for specific time signature +;; 5. easy catch-all rule for non-specified measure types + +(define-public (default-auto-beam-check translator dir test) + (define (get name default) + (let ((value (ly:translator-property translator name))) + (if (not (null? value)) value default))) + + (if (!= (ly:moment-grace-numerator (ly:translator-now translator)) 0) + ;; No auto beaming for grace notes + #f + (let* ((beat-length (get 'beatLength (ly:make-moment 1 1))) + (measure-length (get 'measureLength (ly:make-moment 1 1))) + (measure-pos (get 'measurePosition (ly:make-moment 0 1))) + (settings (get 'autoBeamSettings '())) + (function (list (if (= dir START) 'begin 'end))) + (num-mom (ly:div-moment measure-length beat-length)) + (num (inexact->exact + (round (/ (ly:moment-main-numerator num-mom) + (ly:moment-main-denominator num-mom))))) + (den (ly:moment-main-denominator beat-length)) + (time (list num den)) + (type (list (ly:moment-main-numerator test) + (ly:moment-main-denominator test))) + (pos (if (>= (ly:moment-main-numerator measure-pos) 0) + measure-pos + (ly:add-moment measure-length measure-pos))) + (lst (list + ;; Hmm, should junk user-override feature, + ;; or split this in user-override and config section? + (append function type '(* *)) + (append function '(* * * *)) + (append function type time) + (append function '(* *) time)))) + (if (or + ;; always begin or end beams at beginning/ending of measure + (= (ly:moment-main-numerator pos) 0) + (first-member (map (lambda (x) (cons x pos)) lst) settings)) + #t + (if (= dir START) + ;; if no entry matches our function + time or type, + ;; start anywhere + (not (first-assoc lst settings)) + ;; if no entry matches our function + time or type, + ;; end at any beat + (and (not (first-assoc lst settings)) + (= (ly:moment-main-denominator + (ly:div-moment pos beat-length)) 1))))))) diff --git a/scm/lily-library.scm b/scm/lily-library.scm index 2d25a3991f..cd8b72cafb 100644 --- a/scm/lily-library.scm +++ b/scm/lily-library.scm @@ -119,7 +119,21 @@ found." '() (cons (cons (func (caar list)) (cdar list)) (map-alist-keys func (cdr list))))) - + +(define-public (first-member members lst) + "Return first successful MEMBER of member from MEMBERS in LST." + (if (null? members) + #f + (let ((m (member (car members) lst))) + (if m m (first-member (cdr members) lst))))) + +(define-public (first-assoc keys lst) + "Return first successful ASSOC of key from KEYS in LST." + (if (null? keys) + #f + (let ((k (assoc (car keys) lst))) + (if k k (first-assoc (cdr keys) lst))))) + ;;;;;;;;;;;;;;;; ;; vector (define-public (vector-for-each proc vec) diff --git a/scm/lily.scm b/scm/lily.scm index c86308c41d..3defc3e3ad 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -305,12 +305,14 @@ The syntax is the same as `define*-public'." "Entry point for LilyPond." (let* ((failed '()) (handler (lambda (key failed-file) - (set! failed (append (list failed-file) failed))))) + (set! failed (append (list failed-file) failed))))) + ;;(handler (lambda (key . arg) (set! failed (append arg failed))))) (for-each (lambda (f) (catch 'ly-file-failed (lambda () (ly:parse-file f)) (lambda (x . args) (handler x f))) + ;;(lambda (x) (handler x f))) (if #f (dump-gc-protects))) files) diff --git a/scripts/convert-ly.py b/scripts/convert-ly.py index 8a99c282c0..a0078ce4f2 100644 --- a/scripts/convert-ly.py +++ b/scripts/convert-ly.py @@ -123,6 +123,7 @@ if 1: if re.search ('\\\\multi', str): sys.stderr.write ('\n') sys.stderr.write (NOT_SMART % "\\multi") + sys.stderr.write ('\n') return str conversions.append (((0,1,9), conv, '\\header { key = concat + with + operator }')) @@ -192,6 +193,7 @@ if 1: if re.search ('\\\\header', str): sys.stderr.write ('\n') sys.stderr.write (NOT_SMART % "new \\header format") + sys.stderr.write ('\n') return str conversions.append (((1,0,2), conv, '\\header { key = concat + with + operator }')) @@ -225,6 +227,7 @@ if 1: if re.search ('[a-zA-Z]+ = *\\translator',str): sys.stderr.write ('\n') sys.stderr.write (NOT_SMART % "\\translator syntax") + sys.stderr.write ('\n') # raise FatalConversionError () return str @@ -296,6 +299,7 @@ if 1: if re.search ('\\\\repeat',str): sys.stderr.write ('\n') sys.stderr.write (NOT_SMART % "\\repeat") + sys.stderr.write ('\n') # raise FatalConversionError () return str @@ -445,6 +449,7 @@ if 1: if re.search ('\\\\repetitions',str): sys.stderr.write ('\n') sys.stderr.write (NOT_SMART % "\\repetitions") + sys.stderr.write ('\n') # raise FatalConversionError () return str @@ -473,6 +478,7 @@ if 1: if re.search ('\\\\notenames',str): sys.stderr.write ('\n') sys.stderr.write (NOT_SMART % "new \\notenames format") + sys.stderr.write ('\n') return str conversions.append (((1,3,38), conv, '\musicalpitch { a b c } -> #\'(a b c)')) @@ -492,6 +498,7 @@ if 1: if re.search ('\\[:',str): sys.stderr.write ('\n') sys.stderr.write (NOT_SMART % "new tremolo format") + sys.stderr.write ('\n') return str conversions.append (((1,3,41), conv, @@ -518,6 +525,7 @@ if 1: if re.search ('\\\\keysignature', str): sys.stderr.write ('\n') sys.stderr.write (NOT_SMART % "new tremolo format") + sys.stderr.write ('\n') return str @@ -630,6 +638,7 @@ if 1: if re.search ('\\\\textscript "[^"]* *"[^"]*"', str): sys.stderr.write ('\n') sys.stderr.write (NOT_SMART % "new \\textscript markup text") + sys.stderr.write ('\n') str = re.sub ('\\textscript +("[^"]*")', '\\textscript #\\1', str) @@ -945,6 +954,7 @@ if 1: and re.search ('automaticMelismata', str) == None: sys.stderr.write ('\n') sys.stderr.write (NOT_SMART % "automaticMelismata; turned on by default since 1.5.67.") + sys.stderr.write ('\n') raise FatalConversionError () return str @@ -1592,6 +1602,7 @@ def conv (str): sys.stderr.write (NOT_SMART % "\\pitch") sys.stderr.write ('\n') sys.stderr.write ("Use Scheme code to construct arbitrary note events.") + sys.stderr.write ('\n') raise FatalConversionError () @@ -1988,6 +1999,7 @@ def conv (str): sys.stderr.write (NOT_SMART % "ly:paper-get-variable") sys.stderr.write ('\n') sys.stderr.write ('use (ly:paper-lookup (ly:grob-paper ))') + sys.stderr.write ('\n') raise FatalConversionError () str = re.sub (r'\\defaultAccidentals', "#(set-accidental-style 'default)", str) @@ -2482,6 +2494,24 @@ def conv (str): conversions.append (((2, 5, 18), conv, 'ly:warn -> ly:warning')) +def conv (str): + if re.search ("(override-|revert-)auto-beam-setting", str)\ + or re.search ("autoBeamSettings"): + sys.stderr.write ('\n') + sys.stderr.write (NOT_SMART % "auto beam settings") + sys.stderr.write ('\n') + sys.stderr.write (''' +Auto beam settings must now specify each interesting moment in a measure +explicitely; 1/4 is no not multiplied to cover moments 1/2 and 3/4 too. +''') + sys.stderr.write (UPDATE_MANUALLY) + sys.stderr.write ('\n') + raise FatalConversionError () + return str + +conversions.append (((2, 5, 21), + conv, + 'warn about auto beam settings')) ################################ # END OF CONVERSIONS @@ -2505,10 +2535,10 @@ def do_conversion (infile, from_version, outfile, to_version): try: for x in conv_list: sys.stderr.write (tup_to_str (x[0])) - str = x[1] (str) - last_conversion = x[0] if x != conv_list[-1]: sys.stderr.write (', ') + str = x[1] (str) + last_conversion = x[0] except FatalConversionError: sys.stderr.write (_ ("%s: error while converting") \ @@ -2558,7 +2588,7 @@ def do_one_file (infile_name): if infile_name: - infile = open (infile_name,'r') + infile = open (infile_name, 'r') else: infile = sys.stdin @@ -2637,6 +2667,11 @@ for f in files: if f == '-': f = '' elif not os.path.isfile (f): + sys.stderr.write ('\n') + sys.stderr.write (_ ("can't open file: `%s'") % f) + sys.stderr.write ('\n') + if len (files) == 1: + sys.exit (1) continue try: do_one_file (f)