From a5ad2625e3efe81539bbad78c5f44b61bd1f5b69 Mon Sep 17 00:00:00 2001 From: Carl Sorensen Date: Sat, 18 Feb 2012 09:49:56 -0700 Subject: [PATCH] Set context properties to allow half-measure beaming in 3/4 (Issue 2246) Introduce beamWholeMeasure, which allows beaming of a whole measure of eighth notes in 3/4 time (but not beaming of a half measure, since it appears to be a 6/8 beaming). By default, set to #t. Introduce beamHalfMeasure, which allows beaming of a half measure of eighth notes in 3/4 time. By default, set to #f. A non-empty beamExceptions entry will override beamHalfMeasure and beamWholeMeasure, since user-specified rules should override defaults. Includes updated documentation in English docs, and a new regtest. No changes to translated docs. --- Documentation/notation/rhythms.itely | 30 ++++++++---- input/regression/autobeam-3-4-rules.ly | 24 ++++++++++ .../regression/multiple-time-sig-settings.ly | 4 +- ly/engraver-init.ly | 3 ++ scm/auto-beam.scm | 48 ++++++++++++++----- scm/define-context-properties.scm | 4 ++ scm/time-signature-settings.scm | 17 +++---- 7 files changed, 101 insertions(+), 29 deletions(-) create mode 100644 input/regression/autobeam-3-4-rules.ly diff --git a/Documentation/notation/rhythms.itely b/Documentation/notation/rhythms.itely index a3707bf42a..b5c60a1980 100644 --- a/Documentation/notation/rhythms.itely +++ b/Documentation/notation/rhythms.itely @@ -2147,17 +2147,31 @@ if @code{beamExceptions} is not reset. \repeat unfold 8 {c8} @end lilypond -In a similar fashion, eighth notes in 3/4 time are beamed as a full -measure by default. To beam eighth notes in 3/4 time on the beat, -reset @code{beamExceptions}. +In traditional engraving, eighth notes can have special beaming rules. +A measure consisting of only eighth notes can be beamed in one. This rule is +controlled by the context property @code{beamWholeMeasure}: @lilypond[quote,verbatim,relative=2] \time 3/4 -% by default we beam in (3) due to beamExceptions -\repeat unfold 6 {a8} | -% This will beam (1 1 1) due to beatLength -\set Timing.beamExceptions = #'() -\repeat unfold 6 {a8} +% By default we beam in one +\repeat unfold 6 { a8 } +% We can avoid beaming in one +\set Timing.beamWholeMeasure = ##f +\repeat unfold 6 { a8 } +@end lilypond + +In some engraving from the Romantic and Classical periods, +a half-measure of eighth notes can be beamed +together even though this violates the general rule (see Gould, p. 153). +This behavior is controlled by the context property @code{beamHalfMeasure}: + +@lilypond[quote,verbatim,relative=2] +\time 3/4 +% By default we avoid half-measure beams +r4. a8 a a | +% We can allow half-measure beams +\set Timing.beamHalfMeasure = ##t +r4. a8 a a | @end lilypond @i{@strong{How automatic beaming works}} diff --git a/input/regression/autobeam-3-4-rules.ly b/input/regression/autobeam-3-4-rules.ly new file mode 100644 index 0000000000..5730b6c424 --- /dev/null +++ b/input/regression/autobeam-3-4-rules.ly @@ -0,0 +1,24 @@ +\version "2.15.31" + +\header { + + doctitle = "Special beaming rules for 3/4 time" + + texinfo = " +Whole-measure and half-measure beaming in 3/4 time can be controlled. +The first measure should be beamed in one. The second measure should +be beamed in three. The third and fourth measures should be beamed +at 3/8. + " + +} + +\relative c' { + \time 3/4 + c8^\markup "Beam in one" c c c c c + \set Timing.beamWholeMeasure = ##f + c8^\markup "Beam in three" c c c c c + \set Timing.beamHalfMeasure = ##t + r4.^\markup "Beam in Two" c8 c c + c8 c c r4. +} diff --git a/input/regression/multiple-time-sig-settings.ly b/input/regression/multiple-time-sig-settings.ly index 2caad79c8e..ab95af5498 100644 --- a/input/regression/multiple-time-sig-settings.ly +++ b/input/regression/multiple-time-sig-settings.ly @@ -10,7 +10,7 @@ by the markups. \new Staff{ \relative c' { - \overrideTimeSignatureSettings + \overrideTimeSignatureSettings #'(4 . 4) % time signature fraction #'(1 . 4) % base moment fraction #'(1 1 1 1) % beatStructure @@ -19,7 +19,7 @@ by the markups. #'(3 . 4) % time signature fraction #'(1 . 4) % base moment fraction #'(1 1 1) % beatStructure - #'() % beamExceptions + #'((end . (((1 . 8) . (2 2 2))))) % set exceptions to beam by 1/4 \time 4/4 c8^\markup {"Beam by 1/4"} c c c c c c c | \time 3/4 diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 6335ab65b1..da8f398cf2 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -614,6 +614,9 @@ automatically when an output definition (a @code{\score} or beatStructure = #'(1 1 1 1) beamExceptions = #'((end . (((1 . 8) . (4 4)) ((1 . 12) . (3 3 3 3))))) + beamWholeMeasure = ##t + beamHalfMeasure = ##f + autoBeaming = ##t autoBeamCheck = #default-auto-beam-check diff --git a/scm/auto-beam.scm b/scm/auto-beam.scm index 3cb350867b..85ff3c65a1 100644 --- a/scm/auto-beam.scm +++ b/scm/auto-beam.scm @@ -16,9 +16,9 @@ ;;;; along with LilyPond. If not, see . ;; Determine whether an auto beam should be extended to the right -;; of the current stem. We start anywhere except on the last note -;; of a beat. We end according to the follwing rules, in order -;; of decreasing priority: +;; of the current stem. In general, we start anywhere except on +;; the last note of a beat. We end according to the follwing rules, +;; in order of decreasing priority: ;; ;; 1. end ;; 2. end @@ -61,6 +61,12 @@ (define (beat-end? moment beat-structure) (pair? (member moment beat-structure))) ;; member returns a list if found, not #t + (define (use-special-3-4-rules? fraction base-moment exceptions) + "Should we use special 3/4 time signature beaming rules?" + (and (equal? fraction '(3 . 4)) + (equal? base-moment (ly:make-moment 1 4)) + (null? (assoc-get '(1 . 8) exceptions '())))) + ;; Start of actual auto-beam test routine ;; ;; @@ -79,6 +85,8 @@ '()) beamingfraction test-beam)) (non-grace (ly:make-moment (ly:moment-main-numerator measure-pos) @@ -106,17 +114,35 @@ exception-grouping 0 grouping-moment))) (if (= dir START) - ;; Start rules - (or (not (equal? time-signature-fraction '(3 . 4))) ;; start anywhere if not 3/4 + ;; Start rules -- start anywhere unless 3/4 with default rules + ;; #t if beam is to start + (or (not (use-special-3-4-rules? + time-signature-fraction + base-moment + exceptions)) ;; start anywhere if not default 3/4 (= (ly:moment-main-numerator pos) 0) ;; start at beginning of measure - (not (null? exception-grouping)) ;; don't use special rules if exception - (beat-end? pos beat-endings) ;; are we at start of beat? + (and beam-half-measure + (equal? type '(1 . 8)) + (equal? pos (ly:make-moment 3 8))) ;; start at mid-measure if 1/8 note beam + (beat-end? pos beat-endings) ;; start if at start of beat (and (not (equal? test-beam base-moment)) ;; is beat split? (not (beat-end? (ly:moment-add pos test-beam) beat-endings)))) ;; will this note end the beat - ;; End rules + ;; End rules -- #t if beam is to end (or (= (ly:moment-main-numerator pos) 0) ;; end at measure beginning - (if (null? exception-grouping) - (beat-end? pos beat-endings) ;; no exception, so check beat ending - (member pos exception-moments))))))) ;; check exception rule + (if (use-special-3-4-rules? + time-signature-fraction + base-moment + exceptions) + ;; special rule for default 3/4 beaming + (if (and (equal? type '(1 . 8)) + (or beam-whole-measure + (and beam-half-measure + (not (equal? pos (ly:make-moment 3 8)))))) + #f + (beat-end? pos beat-endings)) + ;; rules for all other cases -- check for applicable exception + (if (null? exception-grouping) + (beat-end? pos beat-endings) ;; no exception, so check beat ending + (member pos exception-moments)))))))) ;; check exception rule diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index 43079859c6..e0da636c51 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -141,6 +141,10 @@ apply for the down staff of @code{PianoStaff}. Used by @code{\\autochange}.") (beamExceptions ,list? "An alist of exceptions to autobeam rules that normally end on beats.") + (beamHalfMeasure ,boolean? "Allow a half measure of eighth notes to +be beamed together in 3/4 time?") + (beamWholeMeasure ,boolean? "Allow a whole measure of eighth notes +to be beamed together in 3/4 time?") (beatStructure ,list? "List of @code{baseMoment}s that are combined to make beats.") diff --git a/scm/time-signature-settings.scm b/scm/time-signature-settings.scm index bdabac8873..898eee600a 100644 --- a/scm/time-signature-settings.scm +++ b/scm/time-signature-settings.scm @@ -64,6 +64,7 @@ ;;; NOTE: numerator is kept in beam-type because of ;;; tuplets, e.g. (2 . 24) = (2 . 3) * (1 . 8) ;;; for eighth-note triplets. +;;; (define-public default-time-signature-settings '( @@ -82,14 +83,15 @@ ((beamExceptions . ((end . (((1 . 32) . (8 8 8 8 8 8)))))))) ;; in 3 4 time: - ;; use defaults, but combine all beats into a unit if possible + ;; use defaults -- no entries necessary ;; - ;; set all beams to end on beats, but 1 8 to beam entire measure - ;; in order to avoid beaming every beam type for the entire measure, we set - ;; triplets back to every beat. + ;; Whole measure beaming is controlled by context property + ;; beamWholeMeasure + ;; Half measure beaming is controlled by context property + ;; beamHalfMeasure + ((3 . 4) . - ((beamExceptions . ((end . (((1 . 8) . (6)) ;1/8 note whole measure - ((1 . 12) . (3 3 3)))))))) ;Anything shorter by beat + ((beamExceptions . ()))) ;; in 3 8 time: ;; beam entire measure together @@ -232,7 +234,6 @@ for @var{time-signature} from @var{time-signature-settings}." "Like the C++ code that executes \\override, but without type checking." (begin - (revert-property-setting context property setting) (ly:context-set-property! context property @@ -263,7 +264,7 @@ a fresh copy of the list-head is made." ;; body of revert-property-setting (let ((current-value (ly:context-property context property))) - (if (> (entry-count current-value setting) 1) + (if (> (entry-count current-value setting) 0) (ly:context-set-property! context property -- 2.39.2