(let ((value (ly:context-property context name)))
(if (not (null? value)) value default)))
- (define (beaming<? a b)
- (ly:moment<? (fraction->moment (car a))
- (fraction->moment (car b))))
-
- (define (ending-moments group-list start-beat base-moment)
+ (define (ending-moments group-list start-beat base-length)
(if (null? group-list)
'()
(let ((new-start (+ start-beat (car group-list))))
- (cons (ly:moment-mul (ly:make-moment new-start 1) base-moment)
- (ending-moments (cdr group-list) new-start base-moment)))))
+ (cons (* new-start base-length)
+ (ending-moments (cdr group-list) new-start base-length)))))
- (define (larger-setting test-beam sorted-alist)
- (if (null? sorted-alist)
- '()
- (let* ((first-key (caar sorted-alist))
- (first-moment (fraction->moment first-key)))
- (if (moment<=? test-beam first-moment)
- (car sorted-alist)
- (larger-setting test-beam (cdr sorted-alist))))))
+ (define (larger-setting type sorted-alist)
+ (assoc type sorted-alist <=))
- (define (beat-end? moment beat-structure)
- (pair? (member moment beat-structure))) ;; member returns a list if found, not #t
+ (define (beat-end? moment beat-endings)
+ (pair? (memv moment beat-endings))) ;; member returns a list if found, not #t
;; Start of actual auto-beam test routine
;;
;;
;; Don't start auto beams on grace notes
- (if (and (!= (ly:moment-grace-numerator (ly:context-now context)) 0)
- (= dir START))
- #f
- (let* ((base-moment (get 'baseMoment (ly:make-moment 1 4)))
- (measure-length (get 'measureLength (ly:make-moment 1 1)))
+ (and (or (zero? (ly:moment-grace (ly:context-now context)))
+ (!= dir START))
+ (let* ((base-length (cond ((get 'baseMoment #f) => ly:moment-main)
+ (else 1/4)))
+ (measure-length (cond ((get 'measureLength #f) => ly:moment-main)
+ (else 1)))
(time-signature-fraction
(get 'timeSignatureFraction '(4 . 4)))
(beat-structure (get 'beatStructure '(1 1 1 1)))
- (beat-endings (ending-moments beat-structure 0 base-moment))
- (exceptions (sort (assoc-get 'end
- (get 'beamExceptions '())
- '())
- beaming<?))
+ (beat-endings (ending-moments beat-structure 0 base-length))
+ (exceptions (sort (map
+ (lambda (a)
+ (if (pair? (car a))
+ (cons (/ (caar a) (cdar a))
+ (cdr a))
+ a))
+ (assoc-get 'end
+ (get 'beamExceptions '())
+ '()))
+ car<))
(function (if (= dir START) 'begin 'end))
(beam-half-measure (get 'beamHalfMeasure #t))
- (type (moment->fraction test-beam))
- (non-grace (ly:make-moment
- (ly:moment-main-numerator measure-pos)
- (ly:moment-main-denominator measure-pos)))
- (pos (if (ly:moment<? non-grace ZERO-MOMENT)
- (ly:moment-add measure-length non-grace)
+ (type (ly:moment-main test-beam))
+ (non-grace (ly:moment-main measure-pos))
+ (pos (if (negative? non-grace)
+ (+ measure-length non-grace)
non-grace))
(type-grouping (assoc-get type exceptions '()))
- (default-rule (if (null? type-grouping)
- (larger-setting test-beam exceptions)
- '()))
- (default-grouping (if (pair? default-rule)
- (cdr default-rule)
- '()))
- (default-beat-length (if (pair? default-rule)
- (car default-rule)
- '()))
+ (default-rule (and (null? type-grouping)
+ (larger-setting type exceptions)))
+ (default-grouping (and default-rule (cdr default-rule)))
+ (default-beat-length (and default-rule (car default-rule)))
(exception-grouping (if (null? type-grouping)
default-grouping
type-grouping))
(grouping-moment (if (null? type-grouping)
- (fraction->moment default-beat-length)
- test-beam))
- (exception-moments (ending-moments
- exception-grouping 0 grouping-moment)))
+ default-beat-length
+ type))
+ (exception-moments (and exception-grouping
+ (ending-moments
+ exception-grouping 0 grouping-moment))))
(if (= dir START)
;; Start rules -- #t if beam is allowed to start
(or beam-half-measure ;; Start anywhere, but option for mid-measure
- (not (equal? (ly:moment-add pos pos) measure-length))
+ (not (= (+ pos pos) measure-length))
(not (= 3 (car time-signature-fraction))) ;; in triple meter
- (not (= (cdr type) ;; when the beamed note is 1/6 of a measure
+ (not (= (denominator type) ;; when the beamed note is 1/6 of a measure
(* 2 (cdr time-signature-fraction)))))
;; End rules -- #t if beam is required 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
+ (or (zero? pos) ;; end at measure beginning
+ (if exception-grouping
+ (beat-end? pos exception-moments) ;; check exception rule
+ (beat-end? pos beat-endings))))))) ;; no exception, so check beat ending
+
(define-public (extract-beam-exceptions music)
"Creates a value useful for setting @code{beamExceptions} from @var{music}."
;;; time signature. Each default-properties set can contain the
;;; following entries:
;;;
-;;; (baseMoment . (numerator . denominator))
+;;; (baseMoment . (/ numerator denominator))
;;; (beatStructure . structure-list)
;;; (beamExceptions . (alist of beam exceptions that don't follow beats))
;;;
;;;
;;; grouping-rules is an alist containing (beam-type . grouping-list) entries
;;;
-;;; beam-type is (numerator . denominator)
+;;; beam-type is the length as a rational number
;;; grouping-list is a list that specifies the
;;; number of stems of the given duration that are grouped in a beamed unit.
;;; For an exception, the duration used is beam-type. For measureBeats,
;;;
;;; If an exception is specified for a given beam-type, it will apply to all
;;; beams of shorter durations that don't have an individual exception, so
-;;; ((1 . 8) . (3 3 2))
+;;; (1/8 . (3 3 2))
;;; will cause all primary beams to be broken at 3/8, 6/8, and 8/8.
;;;
-;;; ((1 . 32) . (16 8 4 4))
+;;; (1/32 . (16 8 4 4))
;;; will cause all 1/32, 1/64, and 1/128 beams to be broken at 1/2, 3/4,
;;; 7/8, and 8/8.
;;;
+;;; Tuplets are referenced using their actual (scaled) length, so
+;;; a 3/2 tuplet of the 1/8 kind would get exceptions looked up
+;;; under 1/12.
+;;;
;;; If no values are given for baseMoment and measureBeats, default values
;;; will be assigned:
-;;; baseMoment gets the value (ly:make-moment 1 time-signature-denominator)
+;;; baseMoment gets the value (/ time-signature-denominator)
;;; beatStructure gets a list of (3 3 3 ...), where the number of entries is the
;;; number of beats, each containing 3 base-moments, if the time
;;; signature numerator is greater than 3 and divisible by 3, and
;;; a list of (1 1 1 ...), where the number of entries is the
;;; number of base moments in a measure otherwise.
-;;;
-;;; 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
'(
;; in 2/2 time:
;; use defaults, but end beams with 32nd notes each 1 4 beat
((2 . 2) .
- ((beamExceptions . ((end . (((1 . 32) . (8 8 8 8))))))))
+ ((beamExceptions . ((end . ((1/32 . (8 8 8 8))))))))
;; in 2/4, 2/8 and 2/16 time:
;; use defaults, so no entries are necessary
;; use defaults, but end beams with 32nd notes and higher each 1 4 beat
((3 . 2) .
- ((beamExceptions . ((end . (((1 . 32) . (8 8 8 8 8 8))))))))
+ ((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
;; in order to avoid beaming every beam type for the entire measure, we set
;; triplets back to every beat.
((3 . 4) .
- ((beamExceptions . ((end . (((1 . 8) . (6)) ;1/8 note whole measure
- ((1 . 12) . (3 3 3)))))))) ;Anything shorter by beat
+ ((beamExceptions . ((end . ((1/8 . (6)) ;1/8 note whole measure
+ (1/12 . (3 3 3)))))))) ;Anything shorter by beat
;; in 3 8 time:
;; beam entire measure together
- ((3 . 8) . ((beamExceptions . ((end . (((1 . 8) . (3))))))))
+ ((3 . 8) . ((beamExceptions . ((end . ((1/8 . (3))))))))
;; in 3 16 time:
;; use defaults -- no entries necessary
;; in 4 2 time:
;; use defaults, but end beams with 16th notes or finer each 1 4 beat
((4 . 2) .
- ((beamExceptions . ((end . (((1 . 16) . (4 4 4 4 4 4 4 4))))))))
+ ((beamExceptions . ((end . ((1/16 . (4 4 4 4 4 4 4 4))))))))
;; in 4 4 (common) time:
;; use defaults, but combine beats 1,2 and 3,4 if only 8th notes
;; ly/engraver-init.ly where the default time signature is set
;; are set
((4 . 4) .
- ((beamExceptions . ((end . (((1 . 8) . (4 4)) ; 1/8 notes half measure
- ((1 . 12) . (3 3 3 3)))))))) ;Anything shorter by beat
+ ((beamExceptions . ((end . ((1/8 . (4 4)) ; 1/8 notes half measure
+ (1/12 . (3 3 3 3)))))))) ;Anything shorter by beat
;; in 4/8 time:
;; combine beats 1 and 2, so beam in 2
;; in 6 4 time:
;; use defaults, but end beams with 32nd or finer each 1/4 beat
((6 . 4) .
- ((beamExceptions . ((end . (((1 . 16) . (4 4 4 4 4 4))))))))
+ ((beamExceptions . ((end . ((1/16 . (4 4 4 4 4 4))))))))
;; in 6 8 time:
;; use defaults, so no entries necessary
;; in 9 4 time:
;; use defaults, but end beams with 32nd or finer each 1 4 beat
((9 . 4) .
- ((beamExceptions . ((end . (((1 . 32) . (8 8 8 8 8 8 8 8))))))))
+ ((beamExceptions . ((end . ((1/32 . (8 8 8 8 8 8 8 8))))))))
;; in 9 8 time
;; use defaults, so no entries necessary
;; in 12 4 time:
;; use defaults, but end beams with 32nd or finer notes each 1 4 beat
((12 . 4) .
- ((beamExceptions . ((end . (((1 . 32) . (8 8 8 8 8 8 8 8 8 8 8 8))))))))
+ ((beamExceptions . ((end . ((1/32 . (8 8 8 8 8 8 8 8 8 8 8 8))))))))
;; in 12 8 time:
;; use defaults, so no entries necessary