1 ;;;; This file is part of LilyPond, the GNU music typesetter.
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>
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.
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.
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/>.
21 ;; TODO: should link back into user manual.
23 (define (mm-rest-child-list music)
24 "Generate events for multimeasure rests,
25 to be used by the sequential-iterator"
26 (ly:set-origin! (list (make-music 'BarCheck)
27 (make-music 'MultiMeasureRestEvent
28 (ly:music-deep-copy music))
29 (make-music 'BarCheck))
32 (define (make-unfolded-set music)
33 (let ((n (ly:music-property music 'repeat-count))
34 (alts (ly:music-property music 'elements))
35 (body (ly:music-property music 'element)))
37 ((null? alts) (make-list n body))
40 (zip (make-list n body)
41 (append! (make-list (max 0 (- n (length alts)))
45 (define (make-volta-set music)
46 (let* ((alts (ly:music-property music 'elements))
48 (times (ly:music-property music 'repeat-count)))
53 ;; set properties for proper bar numbering
55 (list (make-music 'AlternativeEvent
56 'alternative-dir (if (= y 0)
59 'alternative-increment
66 (list (make-music 'AlternativeEvent
68 'alternative-increment 0))
73 (define (make-ottava-set music)
74 "Set context properties for an ottava bracket."
75 (let ((octavation (ly:music-property music 'ottava-number)))
77 (list (context-spec-music
80 (let ((offset (* -7 octavation))
81 (string (assoc-get octavation '((2 . "15ma")
86 (set! (ly:context-property context 'middleCOffset) offset)
87 (set! (ly:context-property context 'ottavation) string)
88 (ly:set-middle-C! context))))
91 (define (make-time-signature-set music)
92 "Set context properties for a time signature."
93 (let* ((num (ly:music-property music 'numerator))
94 (den (ly:music-property music 'denominator))
95 (structure (ly:music-property music 'beat-structure))
96 (fraction (cons num den)))
97 (list (descend-to-context
101 (let* ((time-signature-settings
102 (ly:context-property context 'timeSignatureSettings))
104 (base-length fraction time-signature-settings))
106 (if (null? structure)
107 (beat-structure my-base-length
109 time-signature-settings)
112 (beam-exceptions fraction time-signature-settings))
113 (new-measure-length (ly:make-moment num den)))
114 (ly:context-set-property!
115 context 'timeSignatureFraction fraction)
116 (ly:context-set-property!
117 context 'baseMoment (ly:make-moment my-base-length))
118 (ly:context-set-property!
119 context 'beatStructure my-beat-structure)
120 (ly:context-set-property!
121 context 'beamExceptions beaming-exception)
122 (ly:context-set-property!
123 context 'measureLength new-measure-length))))
126 ;; (make-music 'TimeSignatureEvent music) would always
127 ;; create a Bottom context. So instead, we just send the
128 ;; event to whatever context may be currently active. If
129 ;; that is not contained within an existing context with
130 ;; TimeSignatureEngraver at the time \time is iterated, it
131 ;; will drop through the floor which mostly means that
132 ;; point&click and tweaks are not available for any time
133 ;; signatures engraved due to the Timing property changes
134 ;; but without a \time of its own. This is more a
135 ;; "notification" rather than an "event" (which is always
136 ;; sent to Bottom) but we don't currently have iterators for
140 (ly:broadcast (ly:context-event-source context)
141 (ly:make-stream-event
142 (ly:make-event-class 'time-signature-event)
143 (ly:music-mutable-properties music))))))))
145 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
146 ;; Some MIDI callbacks -- is this a good place for them?
148 (define-public (breathe::midi-length len context)
149 ;;Shorten by half, or by up to a second, but always by a power of 2
150 (let* ((desired (min (ly:moment-main (seconds->moment 1 context))
151 (* (ly:moment-main len) 1/2)))
152 (scale (inexact->exact (ceiling (/ (log desired) (log 1/2)))))
153 (breath (ly:make-moment (expt 1/2 scale))))
154 (ly:moment-sub (ly:make-moment (ly:moment-main len)) breath)))