LEFT | RIGHT |
1 ;;;; This file is part of LilyPond, the GNU music typesetter. | 1 ;;;; This file is part of LilyPond, the GNU music typesetter. |
2 ;;;; | 2 ;;;; |
3 ;;;; Copyright (C) 2009--2010 Marc Hohl <marc@hohlart.de> | 3 ;;;; Copyright (C) 2009--2010 Marc Hohl <marc@hohlart.de> |
4 ;;;; | 4 ;;;; |
5 ;;;; LilyPond is free software: you can redistribute it and/or modify | 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 | 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 | 7 ;;;; the Free Software Foundation, either version 3 of the License, or |
8 ;;;; (at your option) any later version. | 8 ;;;; (at your option) any later version. |
9 ;;;; | 9 ;;;; |
10 ;;;; LilyPond is distributed in the hope that it will be useful, | 10 ;;;; LilyPond is distributed in the hope that it will be useful, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 ((cross) "2cross")))) | 59 ((cross) "2cross")))) |
60 | 60 |
61 ;; ensure we only call note head callback when | 61 ;; ensure we only call note head callback when |
62 ;; 'style = 'cross | 62 ;; 'style = 'cross |
63 (define-public (tab-note-head::whiteout-if-style-set grob) | 63 (define-public (tab-note-head::whiteout-if-style-set grob) |
64 (let ((style (ly:grob-property grob 'style))) | 64 (let ((style (ly:grob-property grob 'style))) |
65 | 65 |
66 (if (and (symbol? style) | 66 (if (and (symbol? style) |
67 (eq? style 'cross)) | 67 (eq? style 'cross)) |
68 (stencil-whiteout (ly:note-head::print grob)) | 68 (stencil-whiteout (ly:note-head::print grob)) |
69 (ly:text-interface::print grob)))) | 69 (tab-note-head::print grob)))) |
70 | 70 |
71 ;; definitions for the "moderntab" clef: | 71 ;; definitions for the "moderntab" clef: |
72 ;; the "moderntab" clef will be added to the list of known clefs, | 72 ;; the "moderntab" clef will be added to the list of known clefs, |
73 ;; so it can be used as any other clef: \clef "moderntab" | 73 ;; so it can be used as any other clef: \clef "moderntab" |
74 (add-new-clef "moderntab" "markup.moderntab" 0 0 0) | 74 (add-new-clef "moderntab" "markup.moderntab" 0 0 0) |
75 | 75 |
76 ;; define sans serif-style tab-Clefs as a markup: | 76 ;; define sans serif-style tab-Clefs as a markup: |
77 (define-markup-command (customTabClef | 77 (define-markup-command (customTabClef |
78 layout props num-strings staff-space) | 78 layout props num-strings staff-space) |
79 (integer? number?) | 79 (integer? number?) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 (let* ((original (ly:grob-original grob)) | 127 (let* ((original (ly:grob-original grob)) |
128 (left-bound (ly:spanner-bound original LEFT)) | 128 (left-bound (ly:spanner-bound original LEFT)) |
129 (right-bound (ly:spanner-bound original RIGHT)) | 129 (right-bound (ly:spanner-bound original RIGHT)) |
130 (left-pitch (ly:event-property (event-cause left-bound) 'pitch)) | 130 (left-pitch (ly:event-property (event-cause left-bound) 'pitch)) |
131 (right-pitch (ly:event-property (event-cause right-bound) 'pitch))) | 131 (right-pitch (ly:event-property (event-cause right-bound) 'pitch))) |
132 | 132 |
133 (if (< (ly:pitch-semitones right-pitch) (ly:pitch-semitones left-pitch)) | 133 (if (< (ly:pitch-semitones right-pitch) (ly:pitch-semitones left-pitch)) |
134 -0.75 | 134 -0.75 |
135 0.75))) | 135 0.75))) |
136 | 136 |
137 ;; for ties in tablature, fret numbers that are tied to should be invisible, | |
138 ;; except for 'tied to' numbers after a line break;; these will be | |
139 ;; parenthesized (thanks to Neil for his solution): | |
140 (define-public (parenthesize-tab-note-head grob) | |
141 ;; Helper function to parenthesize tab noteheads, | |
142 ;; since we can't use ParenthesesItem at this stage | |
143 ;; This is basically the same as the C++ function | |
144 ;; in accidental.cc, converted to Scheme | |
145 (let* ((font (ly:grob-default-font grob)) | |
146 (open (stencil-whiteout | |
147 (ly:font-get-glyph font "accidentals.leftparen"))) | |
148 (close (stencil-whiteout | |
149 (ly:font-get-glyph font "accidentals.rightparen"))) | |
150 (me (ly:text-interface::print grob))) | |
151 | |
152 (ly:stencil-combine-at-edge | |
153 (ly:stencil-combine-at-edge me X LEFT open) X RIGHT close))) | |
154 | |
155 ;; ParenthesesItem doesn't work very well for TabNoteHead, since | |
156 ;; the parentheses are too small and clash with the staff-lines | |
157 ;; Define a callback for the 'stencils property which will tweak | |
158 ;; the parentheses' appearance for TabNoteHead | |
159 (define-public (parentheses-item::calc-tabstaff-parenthesis-stencils grob) | |
160 ;; the grob we want to parenthesize | |
161 (let ((victim (ly:grob-array-ref (ly:grob-object grob 'elements) 0))) | |
162 | |
163 ;; check whether it's a note head | |
164 (if (grob::has-interface victim 'note-head-interface) | |
165 (begin | |
166 ;; tweak appearance before retrieving | |
167 ;; list of stencils '(left-paren right-paren) | |
168 ;; get the font-size from victim (=TabNoteHead) to handle | |
169 ;; grace notes properly | |
170 (ly:grob-set-property! grob 'font-size | |
171 (ly:grob-property victim 'font-size)) | |
172 (ly:grob-set-property! grob 'padding 0) | |
173 ;; apply whiteout to each element of the list | |
174 (map stencil-whiteout | |
175 (parentheses-item::calc-parenthesis-stencils grob))) | |
176 (parentheses-item::calc-parenthesis-stencils grob)))) | |
177 | |
178 ;; the handler for ties in tablature; according to TabNoteHead #'details, | 137 ;; the handler for ties in tablature; according to TabNoteHead #'details, |
179 ;; the 'tied to' note is handled differently after a line break | 138 ;; the 'tied to' note is handled differently after a line break |
180 (define-public (tie::handle-tab-note-head grob) | 139 (define-public (tie::handle-tab-note-head grob) |
181 (let* ((original (ly:grob-original grob)) | 140 (let* ((original (ly:grob-original grob)) |
182 (tied-tab-note-head (ly:spanner-bound grob RIGHT)) | 141 (tied-tab-note-head (ly:spanner-bound grob RIGHT)) |
183 (tie-follow (ly:grob-property tied-tab-note-head 'tie-follow #f)) | 142 (spanner-start (ly:grob-property tied-tab-note-head 'span-start #f)) |
184 (siblings (if (ly:grob? original) | 143 (siblings (if (ly:grob? original) |
185 (ly:spanner-broken-into original) '()))) | 144 (ly:spanner-broken-into original) '()))) |
186 | 145 |
187 (if tie-follow | 146 (if spanner-start |
188 ;; tab note head is right bound of a tie -> parenthesize it at all event
s | 147 ;; tab note head is right bound of a tie and left of spanner, |
189 (ly:grob-set-property! tied-tab-note-head 'stencil | 148 ;; -> parenthesize it at all events |
190 (lambda (grob) | 149 (begin |
191 (parenthesize-tab-note-head
grob))) | 150 (ly:grob-set-property! tied-tab-note-head 'display-cautionary #t) |
| 151 (ly:grob-set-property! tied-tab-note-head 'stencil tab-note-head::prin
t)) |
192 ;; otherwise, check whether tie is split: | 152 ;; otherwise, check whether tie is split: |
193 (if (and (>= (length siblings) 2) | 153 (if (and (>= (length siblings) 2) |
194 (eq? (car (last-pair siblings)) grob)) | 154 (eq? (car (last-pair siblings)) grob)) |
195 ;; tie is split -> get TabNoteHead #'details | 155 ;; tie is split -> get TabNoteHead #'details |
196 (let* ((details (ly:grob-property tied-tab-note-head 'details)) | 156 (let* ((details (ly:grob-property tied-tab-note-head 'details)) |
197 (tied-properties (assoc-get 'tied-properties details '())) | 157 (tied-properties (assoc-get 'tied-properties details '())) |
198 (tab-note-head-parenthesized (assoc-get 'parenthesize tied-pr
operties #t)) | 158 (tab-note-head-parenthesized (assoc-get 'parenthesize tied-pr
operties #t)) |
199 ;; we need the begin-of-line entry in the 'break-visibility v
ector | 159 ;; we need the begin-of-line entry in the 'break-visibility v
ector |
200 (tab-note-head-visible | 160 (tab-note-head-visible |
201 (vector-ref (assoc-get 'break-visibility | 161 (vector-ref (assoc-get 'break-visibility |
202 tied-properties #(#f #f #t)) 2))) | 162 tied-properties #(#f #f #t)) 2))) |
203 | 163 |
204 (if tab-note-head-visible | 164 (if tab-note-head-visible |
205 ;; tab note head is visible | 165 ;; tab note head is visible |
206 (if tab-note-head-parenthesized | 166 (if tab-note-head-parenthesized |
207 (ly:grob-set-property! tied-tab-note-head 'stencil | 167 (begin |
208 (lambda (grob) | 168 » » » (ly:grob-set-property! tied-tab-note-head 'display-cauti
onary #t) |
209 (parenthesize-
tab-note-head grob)))) | 169 (ly:grob-set-property! tied-tab-note-head 'stencil tab-n
ote-head::print))) |
210 ;; tab note head is invisible | 170 ;; tab note head is invisible |
211 (ly:grob-set-property! tied-tab-note-head 'transparent #t))) | 171 (ly:grob-set-property! tied-tab-note-head 'transparent #t))) |
212 | 172 |
213 ;; tie is not split | 173 ;; tie is not split |
214 (ly:grob-set-property! tied-tab-note-head 'transparent #t))))) | 174 (ly:grob-set-property! tied-tab-note-head 'transparent #t))))) |
215 | 175 |
216 | 176 |
217 | 177 |
218 ;; repeat ties occur within alternatives in a repeat construct; | 178 ;; repeat ties occur within alternatives in a repeat construct; |
219 ;; TabNoteHead #'details handles the appearance in this case | 179 ;; TabNoteHead #'details handles the appearance in this case |
220 (define-public (repeat-tie::handle-tab-note-head grob) | 180 (define-public (repeat-tie::handle-tab-note-head grob) |
221 (let* ((tied-tab-note-head (ly:grob-object grob 'note-head)) | 181 (let* ((tied-tab-note-head (ly:grob-object grob 'note-head)) |
222 (tie-follow (ly:grob-property tied-tab-note-head 'tie-follow #f))) | 182 (spanner-start (ly:grob-property tied-tab-note-head 'span-start #f))) |
223 (if tie-follow | 183 (if spanner-start |
224 ;; tab note head is right bound of a tie -> parenthesize it at all event
s | 184 ;; tab note head is between a tie and a slur/glissando |
225 (ly:grob-set-property! tied-tab-note-head 'stencil | 185 ;; -> parenthesize it at all events |
226 (lambda (grob) | 186 (begin |
227 (parenthesize-tab-note-head g
rob))) | 187 (ly:grob-set-property! tied-tab-note-head 'display-cautionary #t) |
| 188 (ly:grob-set-property! tied-tab-note-head 'stencil tab-note-head::prin
t)) |
228 ;; otherwise check 'details | 189 ;; otherwise check 'details |
229 (let* ((details (ly:grob-property tied-tab-note-head 'details)) | 190 (let* ((details (ly:grob-property tied-tab-note-head 'details)) |
230 (repeat-tied-properties (assoc-get 'repeat-tied-properties detail
s '())) | 191 (repeat-tied-properties (assoc-get 'repeat-tied-properties detail
s '())) |
231 (tab-note-head-visible (assoc-get 'note-head-visible repeat-tied-
properties #t)) | 192 (tab-note-head-visible (assoc-get 'note-head-visible repeat-tied-
properties #t)) |
232 (tab-note-head-parenthesized (assoc-get 'parenthesize repeat-tied
-properties #t))) | 193 (tab-note-head-parenthesized (assoc-get 'parenthesize repeat-tied
-properties #t))) |
233 | 194 |
234 (if tab-note-head-visible | 195 (if tab-note-head-visible |
235 ;; tab note head is visible | 196 ;; tab note head is visible |
236 (if tab-note-head-parenthesized | 197 (if tab-note-head-parenthesized |
237 (ly:grob-set-property! tied-tab-note-head 'stencil | 198 (begin |
238 (lambda (grob) | 199 (ly:grob-set-property! tied-tab-note-head 'display-cautionary
#t) |
239 (parenthesize-tab-no
te-head grob)))) | 200 (ly:grob-set-property! tied-tab-note-head 'stencil tab-note-he
ad::print))) |
240 ;; tab note head is invisible | 201 ;; tab note head is invisible |
241 (ly:grob-set-property! tied-tab-note-head 'transparent #t)))))) | 202 (ly:grob-set-property! tied-tab-note-head 'transparent #t)))))) |
242 | 203 |
243 ;; the slurs should not be too far apart from the corresponding fret number, so | 204 ;; the slurs should not be too far apart from the corresponding fret number, so |
244 ;; we move the slur towards the TabNoteHeads; moreover, if the left fret number
is | 205 ;; we move the slur towards the TabNoteHeads; moreover, if the left fret number
is |
245 ;; the right-bound of a tie, we'll set it in parentheses: | 206 ;; the right-bound of a tie, we'll set it in parentheses: |
246 (define-public (slur::draw-tab-slur grob) | 207 (define-public (slur::draw-tab-slur grob) |
247 ;; TODO: use a less "brute-force" method to decrease | 208 ;; TODO: use a less "brute-force" method to decrease |
248 ;; the distance between the slur ends and the fret numbers | 209 ;; the distance between the slur ends and the fret numbers |
249 (let* ((original (ly:grob-original grob)) | 210 (let* ((original (ly:grob-original grob)) |
250 (left-bound (ly:spanner-bound original LEFT)) | 211 (left-bound (ly:spanner-bound original LEFT)) |
251 (left-tab-note-head (ly:grob-property left-bound 'cause)) | 212 (left-tab-note-head (ly:grob-property left-bound 'cause)) |
252 (tie-follow (ly:grob-property left-tab-note-head 'tie-follow #f)) | |
253 (staff-space (ly:staff-symbol-staff-space grob)) | 213 (staff-space (ly:staff-symbol-staff-space grob)) |
254 (control-points (ly:grob-property grob 'control-points)) | 214 (control-points (ly:grob-property grob 'control-points)) |
255 (new-control-points (map | 215 (new-control-points (map |
256 (lambda (p) | 216 (lambda (p) |
257 (cons (car p) | 217 (cons (car p) |
258 (- (cdr p) | 218 (- (cdr p) |
259 (* staff-space | 219 (* staff-space |
260 (ly:grob-property grob 'direction) | 220 (ly:grob-property grob 'direction) |
261 0.35)))) | 221 0.35)))) |
262 control-points))) | 222 control-points))) |
263 | 223 |
264 (ly:grob-set-property! grob 'control-points new-control-points) | 224 (ly:grob-set-property! grob 'control-points new-control-points) |
265 (and tie-follow | |
266 (ly:grob-set-property! left-tab-note-head 'stencil | |
267 (lambda (grob) | |
268 (parenthesize-tab-note-head
grob)))) | |
269 (ly:slur::print grob))) | 225 (ly:slur::print grob))) |
270 | 226 |
271 ;; The glissando routine works similarly to the slur routine; if the | 227 ;; The glissando routine works similarly to the slur routine; if the |
272 ;; fret number is "tied to", it should become parenthesized. | 228 ;; fret number is "tied to", it should become parenthesized. |
273 (define-public (glissando::draw-tab-glissando grob) | 229 (define-public (glissando::draw-tab-glissando grob) |
274 (let* ((original (ly:grob-original grob)) | 230 (let* ((original (ly:grob-original grob)) |
275 (left-tab-note-head (ly:spanner-bound original LEFT)) | 231 (left-tab-note-head (ly:spanner-bound original LEFT)) |
276 (tie-follow (ly:grob-property left-tab-note-head 'tie-follow #f))) | 232 (cautionary (ly:grob-property left-tab-note-head 'display-cautionary #f
))) |
277 | 233 |
278 (and tie-follow | 234 (and cautionary |
279 (ly:grob-set-property! left-tab-note-head 'stencil | |
280 (lambda (grob) | |
281 (parenthesize-tab-note-head
grob))) | |
282 ;; increase left padding to avoid collision between | 235 ;; increase left padding to avoid collision between |
283 ;; closing parenthesis and glissando line | 236 ;; closing parenthesis and glissando line |
284 (ly:grob-set-nested-property! grob '(bound-details left padding) 0.75)) | 237 (ly:grob-set-nested-property! grob '(bound-details left padding) 0.5)) |
285 (ly:line-spanner::print grob))) | 238 (ly:line-spanner::print grob))) |
286 | 239 |
287 ;; for \tabFullNotation, the stem tremolo beams are too big in comparison to | 240 ;; for \tabFullNotation, the stem tremolo beams are too big in comparison to |
288 ;; normal staves; this wrapper function scales accordingly: | 241 ;; normal staves; this wrapper function scales accordingly: |
289 (define-public (stem-tremolo::calc-tab-width grob) | 242 (define-public (stem-tremolo::calc-tab-width grob) |
290 (let ((width (ly:stem-tremolo::calc-width grob)) | 243 (let ((width (ly:stem-tremolo::calc-width grob)) |
291 (staff-space (ly:staff-symbol-staff-space grob))) | 244 (staff-space (ly:staff-symbol-staff-space grob))) |
292 (/ width staff-space))) | 245 (/ width staff-space))) |
| 246 |
| 247 |
| 248 ;; a callback for custom fret labels |
| 249 (define-public ((tab-note-head::print-custom-fret-label fret) grob) |
| 250 (ly:grob-set-property! grob 'text fret) |
| 251 (tab-note-head::print grob)) |
| 252 |
| 253 (define-public (tab-note-head::print grob) |
| 254 (define (is-harmonic? grob) |
| 255 (let ((arts (ly:event-property (event-cause grob) 'articulations))) |
| 256 (not (null? (filter (lambda (a) |
| 257 (ly:in-event-class? a 'harmonic-event)) |
| 258 arts))))) |
| 259 |
| 260 (let* ((cautionary (ly:grob-property grob 'display-cautionary #f)) |
| 261 (details (ly:grob-property grob 'details '())) |
| 262 (harmonic-props (assoc-get 'harmonic-properties details '())) |
| 263 (harmonic-angularity (assoc-get 'angularity harmonic-props 2)) |
| 264 (harmonic-half-thick (assoc-get 'half-thickness harmonic-props 0.075)) |
| 265 (harmonic-padding (assoc-get 'padding harmonic-props 0)) |
| 266 (harmonic-proc (assoc-get 'procedure harmonic-props parenthesize-stenci
l)) |
| 267 (harmonic-width (assoc-get 'width harmonic-props 0.25)) |
| 268 (cautionary-props (assoc-get 'cautionary-properties details '())) |
| 269 (cautionary-angularity (assoc-get 'angularity cautionary-props 2)) |
| 270 (cautionary-half-thick (assoc-get 'half-thickness cautionary-props 0.07
5)) |
| 271 (cautionary-padding (assoc-get 'padding cautionary-props 0)) |
| 272 (cautionary-proc (assoc-get 'procedure cautionary-props parenthesize-st
encil)) |
| 273 (cautionary-width (assoc-get 'width cautionary-props 0.25)) |
| 274 (output-grob (ly:text-interface::print grob)) |
| 275 (ref-grob (grob-interpret-markup grob "8")) |
| 276 (column-offset (* 2/3 (interval-length |
| 277 (ly:stencil-extent |
| 278 (grob-interpret-markup grob "8") |
| 279 X))))) |
| 280 |
| 281 (if (is-harmonic? grob) |
| 282 (set! output-grob (harmonic-proc output-grob |
| 283 harmonic-half-thick |
| 284 harmonic-width |
| 285 harmonic-angularity |
| 286 harmonic-padding))) |
| 287 (if cautionary |
| 288 (set! output-grob (cautionary-proc output-grob |
| 289 cautionary-half-thick |
| 290 cautionary-width |
| 291 cautionary-angularity |
| 292 cautionary-padding))) |
| 293 (ly:stencil-translate-axis (centered-stencil output-grob) |
| 294 column-offset |
| 295 X))) |
| 296 |
| 297 ;; Harmonic definitions |
| 298 |
| 299 (define node-positions |
| 300 ;; for the node on m/n-th of the string length, we get the corresponding |
| 301 ;; (exact) fret position by calculating p=(-12/log 2)*log(1-(m/n)); |
| 302 ;; since guitarists normally use the forth fret and not the 3.8th, here |
| 303 ;; are rounded values, ordered by |
| 304 ;; 1/2 |
| 305 ;; 1/3 2/3 |
| 306 ;; 1/4 2/4 3/4 etc. |
| 307 ;; The value for 2/4 is irrelevant in practical, bacause the string sounds |
| 308 ;; only one octave higher, not two, but since scheme normalizes the fractions |
| 309 ;; anyway, these values are simply placeholders for easier indexing. |
| 310 ;; According to the arithmetic sum, the position of m/n is at 1/2*(n-2)(n-1)+(
m-1) |
| 311 ;; if we start counting from zero |
| 312 (vector 12 |
| 313 7 19 |
| 314 5 12 24 |
| 315 4 9 16 28 |
| 316 3 7 12 19 31 |
| 317 2.7 5.8 9.7 14.7 21.7 33.7 |
| 318 2.3 5 8 12 17 24 36 |
| 319 2 4.4 7 10 14 19 26 38 )) |
| 320 |
| 321 (define partial-pitch |
| 322 (vector '(0 0 0) |
| 323 '(1 0 0) |
| 324 '(1 4 0) |
| 325 '(2 0 0) |
| 326 '(2 2 0) |
| 327 '(2 4 0) |
| 328 '(2 6 -1/2) |
| 329 '(3 0 0) |
| 330 '(3 1 0))) |
| 331 |
| 332 (define fret-partials |
| 333 '(("0" . 0) |
| 334 ("12" . 1) |
| 335 ("7" . 2) |
| 336 ("19" . 2) |
| 337 ("5" . 3) |
| 338 ("24" . 3) |
| 339 ("4" . 4) |
| 340 ("9" . 4) |
| 341 ("16" . 4) |
| 342 ("3" . 5) |
| 343 ("2.7" . 6) |
| 344 ("2.3" . 7) |
| 345 ("2" . 8))) |
| 346 |
| 347 (define-public (ratio->fret ratio) |
| 348 "Calculate a fret number given @var{ratio} for the harmonic." |
| 349 (let* ((nom (numerator ratio)) |
| 350 (den (denominator ratio)) |
| 351 (index (+ (* (- den 2) |
| 352 (- den 1) |
| 353 1/2) |
| 354 nom -1))) |
| 355 (number->string (vector-ref node-positions index)))) |
| 356 |
| 357 (define-public (ratio->pitch ratio) |
| 358 "Calculate a pitch given @var{ratio} for the harmonic." |
| 359 (let* ((partial (1- (denominator ratio))) |
| 360 (pitch (vector-ref partial-pitch partial))) |
| 361 |
| 362 (ly:make-pitch (first pitch) |
| 363 (second pitch) |
| 364 (third pitch)))) |
| 365 |
| 366 (define-public (fret->pitch fret) |
| 367 "Calculate a pitch given @var{fret} for the harmonic." |
| 368 (let* ((partial (assoc-get fret fret-partials 0)) |
| 369 (pitch (vector-ref partial-pitch partial))) |
| 370 |
| 371 (ly:make-pitch (first pitch) |
| 372 (second pitch) |
| 373 (third pitch)))) |
| 374 |
| 375 (define-public (calc-harmonic-pitch pitch music) |
| 376 "Calculate the harmonic pitches in @var{music} given |
| 377 @var{pitch} as the non-harmonic pitch." |
| 378 (let ((es (ly:music-property music 'elements)) |
| 379 (e (ly:music-property music 'element)) |
| 380 (p (ly:music-property music 'pitch))) |
| 381 (cond |
| 382 ((pair? es) |
| 383 (ly:music-set-property! music 'elements |
| 384 (map (lambda (x) (calc-harmonic-pitch pitch x)) e
s))) |
| 385 ((ly:music? e) |
| 386 (ly:music-set-property! music 'element (calc-harmonic-pitch pitch e))) |
| 387 ((ly:pitch? p) |
| 388 (begin |
| 389 (set! p (ly:pitch-transpose p pitch)) |
| 390 (ly:music-set-property! music 'pitch p)))) |
| 391 music)) |
| 392 |
| 393 (define-public (make-harmonic mus) |
| 394 "Convert music variable @var{mus} to harmonics." |
| 395 (let ((elts (ly:music-property mus 'elements)) |
| 396 (elt (ly:music-property mus 'element))) |
| 397 (cond |
| 398 ((pair? elts) |
| 399 (map make-harmonic elts)) |
| 400 ((ly:music? elt) |
| 401 (make-harmonic elt)) |
| 402 ((music-is-of-type? mus 'note-event) |
| 403 (set! (ly:music-property mus 'articulations) |
| 404 (append |
| 405 (ly:music-property mus 'articulations) |
| 406 (list (make-music 'HarmonicEvent)))))) |
| 407 mus)) |
LEFT | RIGHT |