]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 3682/1: Implement \beamExceptions function fishing exceptions from beamed music.
authorDavid Kastrup <dak@gnu.org>
Thu, 28 Nov 2013 14:24:17 +0000 (15:24 +0100)
committerDavid Kastrup <dak@gnu.org>
Wed, 4 Dec 2013 09:03:51 +0000 (10:03 +0100)
ly/music-functions-init.ly
scm/auto-beam.scm

index bf738074cda120346f26b231c6854bd427ac72e7..bb577e28b58c63bb651a09be26d0ac1bb0c6ab62 100644 (file)
@@ -221,6 +221,14 @@ barNumberCheck =
                                         "Barcheck failed got ~a expect ~a"
                                         cbn n))))))
 
+beamExceptions =
+#(define-scheme-function (parser location music) (ly:music?)
+   (_i "Extract a value suitable for setting
+@code{Timing.beamExceptions} from the given pattern with explicit
+beams in @var{music}.  A bar check @code{|} has to be used between
+bars of patterns in order to reset the timing.")
+   (extract-beam-exceptions music))
+
 bendAfter =
 #(define-event-function (parser location delta) (real?)
    (_i "Create a fall or doit of pitch interval @var{delta}.")
index 14e0209675d02c1b220745d39c14c46271625b2b..b863e5c5a7195c989257a42418fc21c0286f81a7 100644 (file)
                 (if (null? exception-grouping)
                     (beat-end? pos beat-endings) ;; no exception, so check beat ending
                     (member pos exception-moments))))))) ;; check exception rule
+
+(define-public (extract-beam-exceptions music)
+  "Creates a value useful for setting @code{beamExceptions} from @var{music}."
+  (define (car> a b) (> (car a) (car b)))
+  (define (beatify lst)
+    ;; takes a collection of end points, sorts them, and returns the
+    ;; non-zero differences as beaming pattern
+    (let ((s (sort lst <)))
+      (remove zero?
+              (map - s (cons 0 s)))))
+  ;; TODO: let this do something useful with simultaneous music.
+  (let loop
+      ((lst (extract-typed-music (unfold-repeats-fully (event-chord-reduce music))
+                                 '(rhythmic-event bar-check)))
+       (pos 0) (res '()))
+    (cond ((null? lst)
+           (list
+            (cons 'end
+                  (map
+                   (lambda (l)
+                     (cons (cons (numerator (car l)) (denominator (car l)))
+                           (beatify (cdr l))))
+                   (sort res car>)))))
+          ((music-is-of-type? (car lst) 'bar-check)
+           (loop (cdr lst) 0 res))
+          ;; Have rhythmic event.
+          ((any
+            (lambda (art)
+              (and (music-is-of-type? art 'beam-event)
+                   (= (ly:music-property art 'span-direction START) STOP)))
+            (ly:music-property (car lst) 'articulations))
+           (let* ((dur (ly:music-property (car lst) 'duration))
+                  (len (if (ly:duration? dur) (duration-length dur) 0))
+                  (pos (+ pos len))
+                  (ass (assoc len res)))
+             (cond ((or (zero? len) (not (integer? (/ pos len))))
+                    (ly:warning (car lst) (_ "Beam end fits no pattern"))
+                    (loop (cdr lst) pos res))
+                   (ass
+                    (set-cdr! ass (cons (/ pos len) (cdr ass)))
+                    (loop (cdr lst) pos res))
+                   (else
+                    (loop (cdr lst) pos (cons (list len (/ pos len)) res))))))
+          (else
+           (let* ((dur (ly:music-property (car lst) 'duration))
+                  (len (if (ly:duration? dur) (duration-length dur) 0)))
+             (loop (cdr lst)
+                   (+ pos len)
+                   res))))))