]> git.donarmstrong.com Git - lilypond.git/blob - scm/define-music-callbacks.scm
Merge remote branch 'origin/master' into release/unstable
[lilypond.git] / scm / define-music-callbacks.scm
1 ;;;; This file is part of LilyPond, the GNU music typesetter.
2 ;;;;
3 ;;;; Copyright (C) 1998--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
4 ;;;;                 Jan Nieuwenhuizen <janneke@gnu.org>
5 ;;;;                 Neil Puttock <n.puttock@gmail.com>
6 ;;;;                 Carl Sorensen <c_sorensen@byu.edu>
7 ;;;;
8 ;;;; LilyPond is free software: you can redistribute it and/or modify
9 ;;;; it under the terms of the GNU General Public License as published by
10 ;;;; the Free Software Foundation, either version 3 of the License, or
11 ;;;; (at your option) any later version.
12 ;;;;
13 ;;;; LilyPond is distributed in the hope that it will be useful,
14 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;;;; GNU General Public License for more details.
17 ;;;;
18 ;;;; You should have received a copy of the GNU General Public License
19 ;;;; along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
20
21 ;; TODO: should link back into user manual.
22
23 (define (mm-rest-child-list music)
24   "Generate events for multimeasure rests,
25 to be used by the sequential-iterator"
26   (let ((location (ly:music-property music 'origin))
27         (duration (ly:music-property music 'duration)))
28     (list (make-music 'BarCheck
29                       'origin location)
30           (make-event-chord (cons (make-music 'MultiMeasureRestEvent
31                                               'origin location
32                                               'duration duration)
33                                   (ly:music-property music 'articulations)))
34           (make-music 'BarCheck
35                       'origin location))))
36
37 (define (make-unfolded-set music)
38   (let ((n (ly:music-property music 'repeat-count))
39         (alts (ly:music-property music 'elements))
40         (body (ly:music-property music 'element)))
41     (cond ((<= n 0) '())
42           ((null? alts) (make-list n body))
43           (else
44            (concatenate
45             (zip (make-list n body)
46                  (append! (make-list (max 0 (- n (length alts)))
47                                      (car alts))
48                           alts)))))))
49
50 (define (make-volta-set music)
51   (let* ((alts (ly:music-property music 'elements))
52          (lalts (length alts))
53          (times (ly:music-property music 'repeat-count)))
54     (map (lambda (x y)
55            (make-music
56             'SequentialMusic
57             'elements
58             ;; set properties for proper bar numbering
59             (append
60              (list (make-music 'AlternativeEvent
61                                'alternative-dir (if (= y 0)
62                                                     -1
63                                                     0)
64                                'alternative-increment
65                                (if (= 0 y)
66                                    (1+ (- times
67                                           lalts))
68                                    1)))
69              (list x)
70              (if (= y (1- lalts))
71                  (list (make-music 'AlternativeEvent
72                                    'alternative-dir 1
73                                    'alternative-increment 0))
74                  '()))))
75          alts
76          (iota lalts))))
77
78 (define (make-ottava-set music)
79   "Set context properties for an ottava bracket."
80   (let ((octavation (ly:music-property music 'ottava-number)))
81
82     (list (context-spec-music
83            (make-apply-context
84             (lambda (context)
85               (let ((offset (* -7 octavation))
86                     (string (assoc-get octavation '((2 . "15ma")
87                                                     (1 . "8va")
88                                                     (0 . #f)
89                                                     (-1 . "8vb")
90                                                     (-2 . "15mb")))))
91                 (set! (ly:context-property context 'middleCOffset) offset)
92                 (set! (ly:context-property context 'ottavation) string)
93                 (ly:set-middle-C! context))))
94            'Staff))))
95
96 (define (make-time-signature-set music)
97   "Set context properties for a time signature."
98   (let* ((num (ly:music-property music 'numerator))
99          (den (ly:music-property music 'denominator))
100          (structure (ly:music-property music 'beat-structure))
101          (fraction (cons num den)))
102     (list (descend-to-context
103            (context-spec-music
104             (make-apply-context
105              (lambda (context)
106                (let* ((time-signature-settings
107                        (ly:context-property context 'timeSignatureSettings))
108                       (my-base-length
109                        (base-length fraction time-signature-settings))
110                       (my-beat-structure
111                        (if (null? structure)
112                            (beat-structure my-base-length
113                                            fraction
114                                            time-signature-settings)
115                            structure))
116                       (beaming-exception
117                        (beam-exceptions fraction time-signature-settings))
118                       (new-measure-length (ly:make-moment num den)))
119                  (ly:context-set-property!
120                   context 'timeSignatureFraction fraction)
121                  (ly:context-set-property!
122                   context 'baseMoment (ly:make-moment my-base-length))
123                  (ly:context-set-property!
124                   context 'beatStructure my-beat-structure)
125                  (ly:context-set-property!
126                   context 'beamExceptions beaming-exception)
127                  (ly:context-set-property!
128                   context 'measureLength new-measure-length))))
129             'Timing)
130            'Score)
131           (make-music 'TimeSignatureEvent music))))
132
133 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
134 ;; Some MIDI callbacks -- is this a good place for them?
135
136 (define-public (breathe::midi-length len context)
137   ;;Shorten by half, or by up to a second, but always by a power of 2
138   (let* ((desired (min (ly:moment-main (seconds->moment 1 context))
139                        (* (ly:moment-main len) 1/2)))
140          (scale (inexact->exact (ceiling (/ (log desired) (log 1/2)))))
141          (breath (ly:make-moment (expt 1/2 scale))))
142     (ly:moment-sub (ly:make-moment (ly:moment-main len)) breath)))