]> git.donarmstrong.com Git - lilypond.git/blob - scm/auto-beam.scm
43ec64e9b4e82e1a2b431d36935f16b9ec3a0209
[lilypond.git] / scm / auto-beam.scm
1 ;;;; This file is part of LilyPond, the GNU music typesetter.
2 ;;;;
3 ;;;; Copyright (C) 2000--2010 Jan Nieuwenhuizen <janneke@gnu.org>
4 ;;;;
5 ;;;; LilyPond is free software: you can redistribute it and/or modify
6 ;;;; it under the terms of the GNU General Public License as published by
7 ;;;; the Free Software Foundation, either version 3 of the License, or
8 ;;;; (at your option) any later version.
9 ;;;;
10 ;;;; LilyPond is distributed in the hope that it will be useful,
11 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 ;;;; GNU General Public License for more details.
14 ;;;;
15 ;;;; You should have received a copy of the GNU General Public License
16 ;;;; along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
17
18 ;;  Determine end moment for auto beaming (or begin moment, but mostly
19 ;;  0== anywhere).  We only consider the current time signature.
20 ;;  In order of decreasing priority:
21 ;;
22 ;;  1. end <type>
23 ;;  2. end   *
24 ;;  3. if 1-2 not specified, begin anywhere, end at beatLength intervals
25 ;;
26 ;;  Rationale:
27 ;;
28 ;;  [user override]
29 ;;  1. override for specific duration type
30 ;;  2. override for all duration types in a time signature.
31 ;;
32 ;;  defined in scm/beam-settings.scm:
33 ;;  1. Default grouping for common time signatures
34 ;;  2. exceptions for specific time signature, for specific duration type
35
36
37 (define-public (default-auto-beam-check context dir measure-pos test-beam)
38   (define (get name default)
39     (let ((value (ly:context-property context name)))
40       (if (not (null? value)) value default)))
41
42   (define (ending-moments group-list start-beat beat-length)
43     (if (null? group-list)
44         '()
45         (let ((new-start (+ start-beat (car group-list))))
46           (cons (ly:moment-mul (ly:make-moment new-start 1) beat-length)
47                 (ending-moments (cdr group-list) new-start beat-length)))))
48
49   ;; Start of actual auto-beam test routine
50   ;;
51   ;;
52   ;; Don't start auto beams on grace notes
53   (if (and (!= (ly:moment-grace-numerator (ly:context-now context)) 0)
54            (= dir START))
55       #f
56       (if (= dir START)
57           ;; start anywhere is currently implemented
58           #t
59           (let* ((beat-length (get 'beatLength (ly:make-moment 1 4)))
60                  (measure-length (get 'measureLength (ly:make-moment 1 1)))
61                  (time-signature-fraction
62                    (get 'timeSignatureFraction '(4 . 4)))
63                  (settings (get 'beamSettings '()))
64                  (function (if (= dir START) 'begin 'end))
65                  (type (cons (ly:moment-main-numerator test-beam)
66                              (ly:moment-main-denominator test-beam)))
67                  (pos (if (>= (ly:moment-main-numerator measure-pos) 0)
68                         measure-pos
69                         (ly:moment-add measure-length measure-pos)))
70                  (type-grouping (ly:beam-grouping
71                                   settings
72                                   time-signature-fraction
73                                   function
74                                   type))
75                  (default-grouping (ly:beam-grouping
76                                      settings
77                                      time-signature-fraction
78                                      function
79                                      '*))
80                  (beat-grouping (if (null? type-grouping)
81                                   default-grouping
82                                   type-grouping))
83                  (grouping-moment (if (null? type-grouping)
84                                     beat-length
85                                     test-beam))
86                  (grouping-moments (ending-moments
87                                       beat-grouping 0 grouping-moment)))
88            (if (null? beat-grouping)
89                ;; no rule applies, so end at beatLength
90                (= (ly:moment-main-denominator
91                    (ly:moment-div pos beat-length)) 1)
92                ;; otherwise, end at beginning of measure or
93                ;; at specified moment
94                (or
95                 ;; start/end at beginning of measure
96                 (= (ly:moment-main-numerator pos) 0)
97                 ;; end if measure-pos matches a specified ending moment
98                 (member pos grouping-moments)))))))