Implementation of Graham Percival's composite dynamics
[opera_libre.git] / definitions / functions.ly
bloba60a2060b075c146dccd4cd4466f9d9d09d1dfd1
1 %------------------------------------------------------------------%
2 % Opéra Libre -- functions.ly %
3 % %
4 % (c) Valentin Villenave, 2008 %
5 % %
6 %------------------------------------------------------------------%
9 %%%%%%%%%%%%%%%%%%%%%%%%% Music Shortcuts %%%%%%%%%%%%%%%%%%%%%%%%%%
11 %% Rhythm shortcuts -----------------------------------------------%
13 t =
14 #(define-music-function (parser location music) (ly:music?)
15 #{ \times 2/3 $music #})
17 tt =
18 #(define-music-function (parser location music) (ly:music?)
19 #{ \times 4/5 $music #})
21 ttt =
22 #(define-music-function (parser location music) (ly:music?)
23 #{ \times 4/6 $music #})
25 tttt =
26 #(define-music-function (parser location music) (ly:music?)
27 #{ \times 4/7 $music #})
30 %% Polyphony shortcuts --------------------------------------------%
32 pl =
33 #(define-music-function (parser location one two) (ly:music? ly:music?)
34 #{ << { \voiceTwo $one } \\ { \voiceOne $two } >> #})
36 parallel=
37 #(define-music-function (parser location droite gauche) (ly:music? ly:music?)
38 #{ <<
39 \context Staff = "droite" $droite
40 \context Staff = "gauche" $gauche
41 >> #})
43 PianoDeuxMains=
44 #(define-music-function (parser location droite gauche) (ly:music? ly:music?)
45 #{ <<
46 \new Staff = "droite" \with { \override VerticalAxisGroup #'remove-empty = ##f }
47 { \clef treble $droite }
48 \new Staff = "gauche" \with { \override VerticalAxisGroup #'remove-empty = ##f }
49 { \clef bass $gauche }
50 >> #})
52 harmo =
53 #(define-music-function (parser location chord result) (ly:music? ly:music?)
54 #{ << \oneVoice $chord \\ { \voiceTwo %FIXME: ties could look better.
55 \override NoteHead #'stencil = #ly:text-interface::print
56 \override NoteHead #'text = \markup { \null \musicglyph #"noteheads.s2"}
57 \once \override NoteHead #'text = \markup {\null \override #'(direction . 1)
58 \dir-column {\musicglyph #"noteheads.s2" \teeny \musicglyph #"eight"}}
59 \override Stem #'stencil = ##f $result
60 \revert Stem #'stencil \revert NoteHead #'stencil } >> #})
62 %% Articulation shortcuts -----------------------------------------%
64 % Are these really needed?
65 #(define (make-script x)
66 (make-music 'ArticulationEvent
67 'articulation-type x))
69 #(define (add-script m x)
70 (let ( (eventname (ly:music-property m 'name)))
71 (if (equal? eventname 'EventChord)
72 (let ( (elements (ly:music-property m 'elements)) )
73 (if (not (equal? (ly:music-property (car elements)
74 'name) 'RestEvent))
75 (set! (ly:music-property m 'elements)
76 (append elements (list
77 (make-script x)))))))
78 m))
80 #(define (double-script m t tt)
81 (add-script (add-script m t) tt))
83 st =
84 #(define-music-function (parser location music)
85 (ly:music?)
86 (define (make-script-music m)
87 (add-script m "staccato"))
88 (music-map make-script-music music))
90 acc =
91 #(define-music-function (parser location music)
92 (ly:music?)
93 (define (make-script-music m)
94 (add-script m "accent"))
95 (music-map make-script-music music))
97 det =
98 #(define-music-function (parser location music)
99 (ly:music?)
100 (define (make-script-music m)
101 (add-script m "tenuto"))
102 (music-map make-script-music music))
104 marc =
105 #(define-music-function (parser location music)
106 (ly:music?)
107 (define (make-script-music m)
108 (add-script m "marcato"))
109 (music-map make-script-music music))
111 stdet =
112 #(define-music-function (parser location music)
113 (ly:music?)
114 (define (make-script-music m)
115 (add-script m "portato"))
116 (music-map make-script-music music))
118 accdet =
119 #(define-music-function (parser location music)
120 (ly:music?)
121 (define (make-script-music m)
122 (double-script m "tenuto" "accent"))
123 (music-map make-script-music music))
125 marcdet =
126 #(define-music-function (parser location music)
127 (ly:music?)
128 (define (make-script-music m)
129 (double-script m "tenuto" "marcato"))
130 (music-map make-script-music music))
132 accst =
133 #(define-music-function (parser location music)
134 (ly:music?)
135 (define (make-script-music m)
136 (double-script m "accent" "staccato"))
137 (music-map make-script-music music))
139 marcst =
140 #(define-music-function (parser location music)
141 (ly:music?)
142 (define (make-script-music m)
143 (double-script m "marcato" "staccato"))
144 (music-map make-script-music music))
147 CaV=
148 #(let ((m (make-music 'ArticulationEvent
149 'articulation-type "flageolet")))
150 (set! (ly:music-property m 'tweaks)
151 (acons 'font-size -3
152 (ly:music-property m 'tweaks)))
155 thumbpizz =
156 #(make-music 'TextScriptEvent
157 'direction 1
158 'text (markup #:hspace .4 #:rotate 45
159 #:musicglyph "scripts.stopped"))
161 %% Music shortcuts ------------------------------------------------%
163 % This might not be needed
164 #(define (octave-up noteevent)
165 (let* ((pitch (ly:music-property noteevent 'pitch))
166 (octave (ly:pitch-octave pitch))
167 (note (ly:pitch-notename pitch))
168 (alteration (ly:pitch-alteration pitch))
169 (duration (ly:music-property noteevent 'duration))
170 (newnoteevent
171 (make-music 'NoteEvent
172 'duration duration
173 'pitch (ly:make-pitch (1- octave) note alteration))))
174 newnoteevent))
176 #(define (octavize-chord elements)
177 (cond ((null? elements) elements)
178 ((eq? (ly:music-property (car elements) 'name) 'NoteEvent)
179 (cons (car elements)
180 (cons (octave-up (car elements))
181 (octavize-chord (cdr elements)))))
182 (else (cons (car elements) (octavize-chord (cdr elements))))))
184 #(define (octavize music)
185 (let* ((es (ly:music-property music 'elements))
186 (e (ly:music-property music 'element))
187 (name (ly:music-property music 'name)))
188 (cond ((eq? name 'EventChord)
189 (ly:music-set-property! music 'elements (octavize-chord es)))
190 ((pair? es)
191 (for-each (lambda(x) (octavize x)) es))
192 ((ly:music? e)
193 (octavize e))))
194 music)
196 oct = #(define-music-function (parser location mus) (ly:music?)
197 (octavize mus))
199 %%%%%%%%%%%%%%%%%%%%%%%% Layout Functions %%%%%%%%%%%%%%%%%%%%%%%%%%
201 %% Music layout ---------------------------------------------------%
203 droite = { \change Staff = "droite" }
205 gauche = { \change Staff = "gauche" }
207 #(define modern-auto-beam-settings
208 (append default-auto-beam-settings
210 ((end * * 3 4) . ,(ly:make-moment 1 4))
211 ((end * * 3 4) . ,(ly:make-moment 1 2))
212 ((end * * 4 4) . ,(ly:make-moment 1 4))
213 ((end * * 4 4) . ,(ly:make-moment 3 4))
214 ((end * * 2 2) . ,(ly:make-moment 1 4))
215 ((end * * 2 2) . ,(ly:make-moment 1 2))
216 ((end * * 2 2) . ,(ly:make-moment 3 4))
217 ((end * * 2 8) . ,(ly:make-moment 1 4))
218 ((be * * 5 8) . ,(ly:make-moment 1 8))
219 ((end * * 5 8) . ,(ly:make-moment 5 8))
222 #(define modern-accidentals-style
223 `(Staff ,(make-accidental-rule 'same-octave 0)
224 ,(make-accidental-rule 'any-octave 0)
225 ,(make-accidental-rule 'same-octave 1)
226 ,neo-modern-accidental-rule))
227 #(define modern-cautionaries-style
228 `(Staff ,(make-accidental-rule 'same-octave 1)
229 ,(make-accidental-rule 'any-octave 1)))
231 %% Music formatting -----------------------------------------------%
233 graceNotes =
234 #(define-music-function (parser location notes) (ly:music?)
235 #{ \tiny $notes \normalsize #})
237 parlato =
238 #(define-music-function (parser location notes) (ly:music?)
239 #{ \override NoteHead #'style = #'cross
240 $notes
241 \revert NoteHead #'style #})
243 hideNote = {
244 \once \override NoteHead #'transparent = ##t
245 \once \override NoteHead #'no-ledgers = ##t
246 \once \override Stem #'transparent = ##t
247 \once \override Beam #'transparent = ##t
248 \once \override Accidental #'transparent = ##t
251 noTuplet = {
252 \once \override TupletBracket #'transparent = ##t
253 \once \override TupletNumber #'transparent = ##t
255 %%%%%%%%%%%%%%%%%%%%%%%%%% In-score Text %%%%%%%%%%%%%%%%%%%%%%%%%%%
257 %% Expressive indications -----------------------------------------%
259 #(define-markup-command (indic layout props arg) (markup?)
260 (interpret-markup layout props
261 (markup #:whiteout #:small #:italic arg)))
263 % because of the use of a music-function,
264 % non-predefined composite dynamics have to be entered *before*
265 % the affected beat (unlike standard or predefined dynamics).
266 cmb =
267 #(define-music-function (parser location dyn str) (string? string?)
268 (make-music 'SequentialMusic 'elements
269 (list
270 (make-music 'OverrideProperty
271 'symbol 'DynamicText
272 'grob-property-path (list 'self-alignment-X)
273 'grob-value -0.6 'once #t)
274 (make-music 'AbsoluteDynamicEvent
275 'text
276 (markup #:dynamic dyn
277 #:hspace .5
278 #:text #:medium #:upright str)))))
280 bmc =
281 #(define-music-function (parser location str dyn) (string? string?)
282 (make-music 'SequentialMusic 'elements
283 (list
284 (make-music 'OverrideProperty
285 'symbol 'DynamicText
286 'grob-property-path (list 'self-alignment-X)
287 'grob-value -0.6 'once #t)
288 (make-music 'AbsoluteDynamicEvent
289 'text
290 (markup #:text #:medium #:upright str
291 #:hspace .5
292 #:dynamic dyn)))))
294 %%% This function was provided by Graham Percival.
295 #(define (make-dynamic-extra dynamic string)
296 (make-music
297 'AbsoluteDynamicEvent
298 'tweaks
299 ;; calculate centering for text
300 (list (cons (quote X-offset)
301 (+ -0.5 (* -0.5 (string-length dynamic)))))
302 'text
303 (markup
304 ;; uncomment next line for debugging
305 ;;#:box
306 #:line(
307 dynamic
308 #:hspace -0.3
309 #:normal-text #:italic string))
312 #(define (make-extra-dynamic string dynamic)
313 (make-music
314 'AbsoluteDynamicEvent
315 'tweaks
316 ;; calculate centering for text
317 (list (cons (quote X-offset)
318 (+ -0.5 (* -0.5 (string-length dynamic)))))
319 'text
320 (markup
321 ;; uncomment next line for debugging
322 ;;#:box
323 #:line(
324 #:normal-text #:italic string
325 #:hspace -0.3
326 #:dynamic dynamic))
329 ffsubito = #(make-dynamic-extra "ff" "subito")
330 fsubito = #(make-dynamic-extra "f" "subito")
331 fmolto = #(make-dynamic-extra "f" "molto")
332 ppsempre = #(make-dynamic-extra "pp" "sempre")
333 mfsempre = #(make-dynamic-extra "mf" "sempre")
334 mpsostenuto = #(make-dynamic-extra "mp" "sostenuto")
335 pdolce = #(make-dynamic-extra "p" "dolce")
336 mfleggiero = #(make-dynamic-extra "mf" "leggiero")
338 piuf = #(make-extra-dynamic "più" "f")
339 pocof = #(make-extra-dynamic "poco" "f")
341 nind =
342 #(define-music-function (parser location texte)
343 (string? )
344 (make-dynamic-script
345 (markup #:text #:indic texte)))
347 ten =
348 #(define-music-function (parser location music) (ly:music?)
350 (equal? (ly:music-property music 'name) 'EventChord)
351 (set! (ly:music-property music 'elements)
352 (append (ly:music-property music 'elements)
353 (list (make-music 'TextScriptEvent 'text
354 (markup #:translate (cons 4 0)
355 #:indic "(ten.)"))))))
356 music)
358 ind =
359 #(define-music-function (parser location text music) (string? ly:music?)
361 (equal? (ly:music-property music 'name) 'EventChord)
362 (set! (ly:music-property music 'elements)
363 (append (ly:music-property music 'elements)
364 (list (make-music 'TextScriptEvent 'direction 1
365 'text (markup #:indic text))))))
366 music)
368 pizz =
369 #(define-music-function (parser location music) (ly:music?)
370 #{ \ind #"pizz." $music #})
372 arco =
373 #(define-music-function (parser location music) (ly:music?)
374 #{ \ind #"arco" $music #})
376 simile =
377 #(define-music-function (parser location music) (ly:music?)
378 #{ \ind #"simile" $music #})
380 loco =
381 #(define-music-function (parser location music) (ly:music?)
382 #{ \ind #"loco" $music #})
384 ordin =
385 #(define-music-function (parser location music) (ly:music?)
386 #{ \ind #"(ordin.)" $music #})
388 #(define (make-text-span music t)
389 (set! (ly:music-property music 'elements)
390 (append (ly:music-property music 'elements)
391 (list (make-music 'TextSpanEvent
392 'span-direction t))))
393 music)
394 startTxt =
395 #(define-music-function (parser location texte music ) (string? ly:music?)
396 #{ \override TextSpanner #'bound-details #'left #'text =
397 \markup { \bold $texte }
398 $(make-text-span music -1)#})
400 stopTxt =
401 #(define-music-function (parser location music ) (ly:music?)
402 (make-text-span music 1))
404 %% Tempo indications ----------------------------------------------%
405 #(define-markup-command (mvt layout props arg) (markup?)
406 (interpret-markup layout props
407 (markup #:huge #:bold arg)))
409 %%%%%%%%%%%%%%%%%%%%%%%%%% Text Functions %%%%%%%%%%%%%%%%%%%%%%%%%%
411 %% Lyrics formatting ----------------------------------------------%
413 freestyleOn = {
414 \override Lyrics . LyricExtender #'stencil = ##f }
416 freestyleOff = {
417 \revert Lyrics . LyricExtender #'stencil }
419 leftSyl = {
420 \once \override LyricText #'self-alignment-X = #0.9 }
422 dash = {
423 \once \override LyricHyphen #'minimum-distance = #4
424 \once \override LyricHyphen #'length = #2
425 \once \override LyricHyphen #'thickness = #1.2
428 ital = {
429 \once \override LyricText #'font-shape = #'italic }
431 smallcaps = {
432 \override LyricText #'font-shape = #'caps }
434 normal = {
435 \revert LyricText #'font-shape }
438 %% Scenography formatting ---------------------------------------%
439 long = {
440 \once \override TextScript #'extra-spacing-width = #'(0 . 0)
441 \once \override TextScript #'infinite-spacing-height = ##t
444 #(define-markup-command (did layout props text) (markup?)
445 (interpret-markup layout props
446 (markup #:override '(line-width . 40)
447 #:override '(box-padding . 1)
448 #:override '(corner-radius . 2)
449 #:rounded-box #:sans #:italic #:small #:justify-string text)))
451 #(define-markup-command (init-did layout props text) (markup?)
452 (interpret-markup layout props
453 (markup
454 ; #:override (cons 'line-width (* 1 (chain-assoc-get 'line-width props)))
455 #:fill-line (
456 #:override '(line-width . 60)
457 #:override '(box-padding . 1.5)
458 #:override '(corner-radius . 2)
459 #:rounded-box #:sans #:italic #:small #:justify-string text))))
461 #(define-markup-command (vspace layout props amount) (number?)
462 (let ((amount (* amount 3.0)))
463 (if (> amount 0)
464 (ly:make-stencil "" (cons -1 1) (cons 0 amount))
465 (ly:make-stencil "" (cons -1 1) (cons amount amount)))))