]> git.donarmstrong.com Git - lilypond.git/commitdiff
Patch for auto-beam; Fix issue 511
authorCarl Sorensen <c_sorensen@byu.edu>
Fri, 22 Aug 2008 17:09:06 +0000 (11:09 -0600)
committerCarl Sorensen <c_sorensen@byu.edu>
Wed, 27 Aug 2008 05:28:05 +0000 (23:28 -0600)
Use timeSignatureFraction to determine time instead of
 calculating from measureLength and beatLength

Use beatGrouping to determine beam stop points if
  it is valid

Add  regression test for autobeaming and beatGrouping

Signed-off-by: Carl Sorensen <c_sorensen@byu.edu>
input/regression/beatGrouping.ly [new file with mode: 0644]
scm/auto-beam.scm

diff --git a/input/regression/beatGrouping.ly b/input/regression/beatGrouping.ly
new file mode 100644 (file)
index 0000000..136f947
--- /dev/null
@@ -0,0 +1,30 @@
+\version "2.11.57"
+\header {
+
+  texidoc = "Autobeaming will break beams according to beatGrouping
+if the total length of the beat groups is equal to measureLength.
+Otherwise, it will break beams according to beatLength."
+}
+
+{
+  \time 12/16
+
+  % default beatLength is 1/16; beatGrouping for this time is '()
+  b16 b b b b b b b b b b b ; beatlength is used to breatk these beams
+  % use beatGrouping to get 1/8 groups
+  \set Timing.beatGrouping = #'(2 2 2 2 2 2) % 6*2 = 12 so beatGrouping applies
+  b16 b b b b b b b b b b b  ;  beam groups are 1/8
+  % use beatLength to get 1/8 groups -- beatGrouping no longer applies
+  \set Score.beatLength = #(ly:make-moment 2 16 )  % 12*2/16 = 24/16
+                                                   % bad beatGrouping; use
+                                                   % beatLength (1/8 notes)
+  b16 b b b b b b b b b b b
+  % make custom beatGrouping
+  \set Timing.beatGrouping = #'(3 1 2)  % 6*2/16 = 12/16
+  b16 b b b b b b b b b b b
+  % change beatLength
+  \set Score.beatLength = #(ly:make-moment 3 16 )  % 6*3/16 = 18/16; use beatLength
+  b16 b b b b b b b b b b b
+  \set Score.beatLength = #(ly:make-moment 4 16 )  % 6*4/16 = 24/16; use beatLength
+  b16 b b b b b b b b b b b
+}
index 475788697baa4442e37706b36a803955a596ffa0..2b622fda6f416ea2e96df77a5c8b218a58727308 100644 (file)
@@ -173,7 +173,12 @@ a fresh copy of the list-head is made."
 ;;  2. end   *      *     *
 ;;  3. end <type> <num> <den>
 ;;  4. end   *    <num> <den>
-;;  5. if 1-4 not specified: begin anywhere, end at every beat
+;;  5. if 1-4 not specified, begin anywhere, end at time determined by
+;;          beatGrouping and beatLength:
+;;     if beatGrouping and beatLength are consistent with measureLength,
+;;        use beatGrouping to determine end of beams.
+;;     if beatGrouping and beatLength are inconsistent with measureLength,
+;;        use beatLength to determine end of beams.
 ;;
 ;;  Rationale:
 ;;
@@ -186,40 +191,68 @@ a fresh copy of the list-head is made."
 ;;  4. exceptions for specific time signature
 ;;  5. easy catch-all rule for non-specified measure types
 
+
 (define-public (default-auto-beam-check context dir test)
   (define (get name default)
     (let ((value (ly:context-property context name)))
       (if (not (null? value)) value default)))
 
+  (define (ending-moments group-list start-beat beat-length)
+  (if (null? group-list)
+      '()
+      (let ((new-start (+ start-beat (car group-list))))
+        (cons (ly:moment-mul (ly:make-moment new-start 1) beat-length)
+              (ending-moments (cdr group-list) new-start beat-length)))))
+
+  (define (make-end-settings time ending-list moment-den)
+    (if (null? ending-list)
+        '()
+        (cons (cons (append '(end * *) time)
+                    (ly:make-moment (car ending-list) moment-den))
+              (make-end-settings time (cdr ending-list) moment-den))))
+  
   ;; Don't start auto beams on grace notes
   (if (and (!= (ly:moment-grace-numerator (ly:context-now context)) 0)
           (= dir START))
       #f
-      (let* ((beat-length (get 'beatLength (ly:make-moment 1 1)))
+      (let* ((beat-length (get 'beatLength (ly:make-moment 1 4)))
             (measure-length (get 'measureLength (ly:make-moment 1 1)))
             (measure-pos (get 'measurePosition ZERO-MOMENT))
+             (beat-grouping (get 'beatGrouping '()))
             (settings (get 'autoBeamSettings '()))
             (function (list (if (= dir START) 'begin 'end)))
+             ;; Calculate implied time signature based on measureLength
+             ;; and beatLength for default value in get
             (num-mom (ly:moment-div 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))
+             (time-signature-fraction 
+               (get 'timeSignatureFraction (cons num den)))
+            (time (list (car time-signature-fraction)
+                         (cdr time-signature-fraction)))
             (type (list (ly:moment-main-numerator test)
                         (ly:moment-main-denominator test)))
             (pos (if (>= (ly:moment-main-numerator measure-pos) 0)
                      measure-pos
                      (ly:moment-add measure-length measure-pos)))
-            (lst (list
+             (grouping-moments (ending-moments beat-grouping 0 beat-length))
+             ;; Calculate implied measure length from beatGrouping
+             ;; and beatLength
+            (grouping-length (if (null? grouping-moments)
+                                  ZERO-MOMENT
+                                  (list-ref grouping-moments 
+                                            (1- (length grouping-moments)))))
+             (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
+                  (append function '(* *) time)))
+             (predefined-setting (first-assoc lst settings)))
+         (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))
@@ -227,9 +260,13 @@ a fresh copy of the list-head is made."
            (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:moment-div pos beat-length)) 1)))))))
+               (not predefined-setting)
+               ;; if entry matches our function + time or type, check moment
+               (if predefined-setting
+                    (equal? measure-pos (cdr predefined-setting))
+                    ;; if measure-length matches grouping-length, use
+                    ;; grouping moments, else use beat-length
+                    (if (equal? measure-length grouping-length)
+                       (member measure-pos grouping-moments)
+                        (= (ly:moment-main-denominator
+                            (ly:moment-div pos beat-length)) 1))))))))