1 ;;;; This file is part of LilyPond, the GNU music typesetter.
3 ;;;; Copyright (C) 2010--2011 Mike Solomon <mikesol@stanfordalumni.org>
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.
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.
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/>.
20 (define CENTRAL-COLUMN-HOLE-PLACEMENTS '((one . (0.0 . 6.5))
27 (define CENTRAL-COLUMN-HOLE-LIST (map car CENTRAL-COLUMN-HOLE-PLACEMENTS))
28 (define CENTRAL-COLUMN-HOLE-H-LIST (cons 'h CENTRAL-COLUMN-HOLE-LIST))
32 (define (return-1 x) 1.0)
34 (define (make-spreadsheet parameter-list)
35 "Makes a spreadsheet function with columns of parameter-list.
36 This function can then be filled with rows.
38 @code{guile> ((make-spreadsheet '(foo bar)) '((1 2) (3 4) (5 6)))}
39 @code{(((foo . 1) (bar . 2)) ((foo . 3) (bar . 4)) ((foo . 5) (bar . 6)))}"
41 (map (lambda (list-to-translate)
42 (map (lambda (name element)
48 (define (get-spreadsheet-column column spreadsheet)
49 "Gets all the values in @code{column} form @code{spreadsheet}
50 made by @{make-spreadsheet}.
52 @code{guile> (get-spreadsheet-column 'bar ((make-spreadsheet '(foo bar)) '((1 2) (3 4) (5 6))))}
54 (map (lambda (row) (assoc-get column row)) spreadsheet))
56 (define (make-named-spreadsheet parameter-list)
57 "Makes a named spreadsheet function with columns of parameter-list.
58 This function can then be filled with named rows
60 @code{guile> ((make-named-spreadsheet '(foo bar)) '((x . (1 2)) (y . (3 4)) (z . (5 6))))}
61 @code{((x (foo . 1) (bar . 2)) (y (foo . 3) (bar . 4)) (z (foo . 5) (bar . 6)))}"
63 (map (lambda (list-to-translate)
64 `(,(list-ref list-to-translate 0)
65 . ,(map (lambda (name element)
68 (list-tail list-to-translate 1))))
71 (define (get-named-spreadsheet-column column spreadsheet)
72 "Gets all the values in @code{column} form @code{spreadsheet}
73 made by @{make-named-spreadsheet}.
75 @code{guile> (get-spreadsheet-column 'bar ((make-named-spreadsheet '(foo bar)) '((x . (1 2)) (y . (3 4)) (z . (5 6)))))}
76 @code{((x . 2) (y . 4) (z . 6))}"
78 (lambda (row) (cons (car row) (assoc-get column (cdr row))))
81 (define make-key-alist
82 (make-named-spreadsheet '(name offset graphical textual)))
84 (define (simple-stencil-alist stencil offset)
85 "A stencil alist that contains one and only one stencil.
86 Shorthand used repeatedly in various instruments."
87 `((stencils . (,stencil))
90 (xy-scale-function . (,return-1 . ,return-1))))
92 (define (make-central-column-hole-addresses keys)
93 "Takes @code{keys} and ascribes them to the central column."
95 (lambda (key) `(central-column . ,key))
98 (define (make-key-symbols hand)
99 "Takes @code{hand} and ascribes @code{key} to it."
101 (map (lambda (key) `(,hand . ,key))
104 (define make-left-hand-key-addresses (make-key-symbols 'left-hand))
106 (define make-right-hand-key-addresses (make-key-symbols 'right-hand))
108 ;; Flute assembly instructions
110 (define flute-change-points
111 ((make-named-spreadsheet '(piccolo flute flute-b-extension))
112 `((bottom-group-key-names
114 . ((offset . (-0.45 . -1.05))
115 (stencil . ,piccolo-rh-x-key-stencil)
117 (complexity . trill))))
119 . ((offset . (0.0 . 0.0))
120 (stencil . ,flute-rh-cis-key-stencil)
122 (complexity . trill)))
124 . ((offset . (0.3 . 0.0))
125 (stencil . ,flute-rh-c-key-stencil)
127 (complexity . trill)))
129 . ((offset . (0.0 . -1.2))
130 (stencil . ,flute-rh-gz-key-stencil)
131 (text? . ("gz" . #f))
132 (complexity . trill))))
134 . ((offset . (0.0 . 0.0))
135 (stencil . ,flute-rh-cis-key-stencil)
137 (complexity . trill)))
139 . ((offset . (0.3 . 0.0))
140 (stencil . ,flute-rh-c-key-stencil)
142 (complexity . trill)))
144 . ((offset . (1.0 . 0.0))
145 (stencil . ,flute-rh-b-key-stencil)
147 (complexity . trill)))
149 . ((offset . (0.0 . -1.2))
150 (stencil . ,flute-rh-gz-key-stencil)
151 (text? . ("gz" . #f))
152 (complexity . trill))))))
153 (bottom-group-graphical-stencil
154 . (((right-hand . ees) (right-hand . x))
155 ,(make-right-hand-key-addresses '(ees cis c gz))
156 ,(make-right-hand-key-addresses '(ees cis c b gz))))
157 (bottom-group-graphical-draw-instruction
158 . (((right-hand . ees))
159 ,(make-right-hand-key-addresses '(ees cis c))
160 ,(make-right-hand-key-addresses '(ees cis c b))))
161 (bottom-group-special-key-instruction
162 . ((,rich-group-draw-rule ((right-hand . x)) ((right-hand . ees)))
163 (,rich-group-draw-rule ((right-hand . gz))
164 ,(make-right-hand-key-addresses
166 (,rich-group-draw-rule ((right-hand . gz))
167 ,(make-right-hand-key-addresses
169 (bottom-group-text-stencil
170 . (,(make-right-hand-key-addresses '(bes d dis ees x))
171 ,(make-right-hand-key-addresses '(bes d dis ees cis c gz))
172 ,(make-right-hand-key-addresses '(bes d dis ees cis c b gz)))))))
174 (define (generate-flute-family-entry flute-name)
177 (get-named-spreadsheet-column
179 flute-change-points)))
184 . ((offset . (0.0 . 0.0))
185 (stencil . ,midline-stencil)
187 (complexity . basic)))))
190 . ((offset . ,(assoc-get 'one CENTRAL-COLUMN-HOLE-PLACEMENTS))
191 (stencil . ,ring-column-circle-stencil)
193 (complexity . ring)))
195 . ((offset . ,(assoc-get 'two CENTRAL-COLUMN-HOLE-PLACEMENTS))
196 (stencil . ,ring-column-circle-stencil)
198 (complexity . ring)))
200 . ((offset . ,(assoc-get 'three CENTRAL-COLUMN-HOLE-PLACEMENTS))
201 (stencil . ,ring-column-circle-stencil)
203 (complexity . ring)))
205 . ((offset . ,(assoc-get 'four CENTRAL-COLUMN-HOLE-PLACEMENTS))
206 (stencil . ,ring-column-circle-stencil)
208 (complexity . ring)))
210 . ((offset . ,(assoc-get 'five CENTRAL-COLUMN-HOLE-PLACEMENTS))
211 (stencil . ,ring-column-circle-stencil)
213 (complexity . ring)))
215 . ((offset . ,(assoc-get 'six CENTRAL-COLUMN-HOLE-PLACEMENTS))
216 (stencil . ,ring-column-circle-stencil)
218 (complexity . ring)))))
221 . ((offset . (0.5 . 1.8))
222 (stencil . ,flute-lh-bes-key-stencil)
224 (complexity . trill)))
226 . ((offset . (0.0 . 0.0))
227 (stencil . ,flute-lh-b-key-stencil)
229 (complexity . trill)))
231 . ((offset . (0.0 . 0.0))
232 (stencil . ,flute-lh-gis-key-stencil)
234 (complexity . trill)))))
237 . ((offset . (0.0 . 0.0))
238 (stencil . ,flute-rh-bes-key-stencil)
240 (complexity . trill)))
242 . ((offset . (0.0 . 0.0))
243 (stencil . ,flute-rh-d-key-stencil)
245 (complexity . trill)))
247 . ((offset . (0.0 . 0.0))
248 (stencil . ,flute-rh-dis-key-stencil)
250 (complexity . trill)))
252 . ((offset . (1.5 . 1.3))
253 (stencil . ,flute-rh-ees-key-stencil)
255 (complexity . trill))))
256 (assoc-get 'bottom-group-key-names change-points)))))
260 . (,(simple-stencil-alist '(hidden . midline) '(0.0 . 3.75))
262 . ,(make-central-column-hole-addresses
263 CENTRAL-COLUMN-HOLE-LIST))
264 (xy-scale-function . (,identity . ,identity))
266 (offset . (0.0 . 0.0)))
267 ((stencils . ((left-hand . bes) (left-hand . b)))
268 (xy-scale-function . (,return-1 . ,return-1))
270 (offset . (-1.5 . 6.5)))
271 ,(simple-stencil-alist '(left-hand . gis) '(1.0 . 4.0))
272 ,(simple-stencil-alist '(right-hand . bes) '(-1.75 . 3.05))
273 ,(simple-stencil-alist '(right-hand . d) '(-1.0 . 2.5))
274 ,(simple-stencil-alist '(right-hand . dis) '(-1.0 . 1.5))
276 . ,(assoc-get 'bottom-group-graphical-stencil
278 (xy-scale-function . (,return-1 . ,return-1))
280 (offset . (0.0 . -0.6)))))
281 (xy-scale-function . (,identity . ,identity))
283 (offset . (0.0 . 0.0))))
285 . ((,apply-group-draw-rule-series
286 (((left-hand . bes) (left-hand . b))
287 ,(assoc-get 'bottom-group-graphical-draw-instruction
289 ,(assoc-get 'bottom-group-special-key-instruction
291 (,group-automate-rule
292 ,(make-central-column-hole-addresses CENTRAL-COLUMN-HOLE-LIST))
293 (,group-automate-rule ((hidden . midline)))))
294 (extra-offset-instructions
295 . ((,uniform-extra-offset-rule (0.0 . 0.0))))))
299 . (,(simple-stencil-alist '(hidden . midline) '(0.0 . 3.75))
301 . ,(make-central-column-hole-addresses
302 CENTRAL-COLUMN-HOLE-LIST))
303 (xy-scale-function . (,identity . ,identity))
305 (offset . (0.0 . 0.0)))
306 ((stencils . ,(make-left-hand-key-addresses '(bes b gis)))
307 (textual? . ,lh-woodwind-text-stencil)
308 (offset . (1.5 . 3.75)))
309 ((stencils . ,(assoc-get 'bottom-group-text-stencil
311 (textual? . ,rh-woodwind-text-stencil)
312 (offset . (-1.25 . 0.0)))))
313 (xy-scale-function . (,identity . ,identity))
315 (offset . (0.0 . 0.0))))
317 . ((,apply-group-draw-rule-series
318 (,(make-left-hand-key-addresses '(bes b gis))
319 ,(assoc-get 'bottom-group-text-stencil change-points)))
320 (,group-automate-rule
321 ,(make-central-column-hole-addresses CENTRAL-COLUMN-HOLE-LIST))
322 (,group-automate-rule ((hidden . midline)))))
323 (extra-offset-instructions
324 . ((,uniform-extra-offset-rule (0.0 . 0.0))))))))))
326 ;;; Tin whistle assembly instructions
328 (define tin-whistle-change-points
329 ((make-named-spreadsheet '(tin-whistle)) '()))
331 (define (generate-tin-whistle-family-entry tin-whistle-name)
334 (get-named-spreadsheet-column tin-whistle-name tin-whistle-change-points)))
339 . ((offset . (0.0 . 0.0))
340 (stencil . ,midline-stencil)
342 (complexity . basic)))))
345 . ((offset . ,(assoc-get 'one CENTRAL-COLUMN-HOLE-PLACEMENTS))
346 (stencil . ,column-circle-stencil)
348 (complexity . covered)))
350 . ((offset . ,(assoc-get 'two CENTRAL-COLUMN-HOLE-PLACEMENTS))
351 (stencil . ,column-circle-stencil)
353 (complexity . covered)))
355 . ((offset . ,(assoc-get 'three CENTRAL-COLUMN-HOLE-PLACEMENTS))
356 (stencil . ,column-circle-stencil)
358 (complexity . covered)))
360 . ((offset . ,(assoc-get 'four CENTRAL-COLUMN-HOLE-PLACEMENTS))
361 (stencil . ,column-circle-stencil)
363 (complexity . covered)))
365 . ((offset . ,(assoc-get 'five CENTRAL-COLUMN-HOLE-PLACEMENTS))
366 (stencil . ,column-circle-stencil)
368 (complexity . covered)))
370 . ((offset . ,(assoc-get 'six CENTRAL-COLUMN-HOLE-PLACEMENTS))
371 (stencil . ,column-circle-stencil)
373 (complexity . covered)))))
379 . (,(simple-stencil-alist '(hidden . midline) '(0.0 . 3.75))
381 . ,(make-central-column-hole-addresses
382 CENTRAL-COLUMN-HOLE-LIST))
383 (xy-scale-function . (,identity . ,identity))
385 (offset . (0.0 . 0.0)))))
386 (xy-scale-function . (,identity . ,identity))
388 (offset . (0.0 . 0.0))))
390 . ((,group-automate-rule
391 ,(make-central-column-hole-addresses CENTRAL-COLUMN-HOLE-LIST))
392 (,group-automate-rule ((hidden . midline)))))
393 (extra-offset-instructions
394 . ((,uniform-extra-offset-rule (0.0 . 0.0))))))
398 (,(simple-stencil-alist '(hidden . midline) '(0.0 . 3.75))
400 . ,(make-central-column-hole-addresses
401 CENTRAL-COLUMN-HOLE-H-LIST))
402 (xy-scale-function . (,identity . ,identity))
404 (offset . (0.0 . 0.0)))))
405 (xy-scale-function . (,identity . ,identity))
407 (offset . (0.0 . 0.0))))
409 . ((,group-automate-rule
410 ,(make-central-column-hole-addresses CENTRAL-COLUMN-HOLE-LIST))
411 (,group-automate-rule ((hidden . midline)))))
412 (extra-offset-instructions
413 . ((,uniform-extra-offset-rule (0.0 . 0.0))))))))))
415 ;;; Oboe assembly instructions
417 (define oboe-change-points
418 ((make-named-spreadsheet '(oboe)) '()))
420 (define (generate-oboe-family-entry oboe-name)
423 (get-named-spreadsheet-column oboe-name oboe-change-points)))
428 . ((offset . (0.0 . 0.0))
429 (stencil . ,midline-stencil)
431 (complexity . basic)))))
434 . ((offset . ,(assoc-get 'one CENTRAL-COLUMN-HOLE-PLACEMENTS))
435 (stencil . ,ring-column-circle-stencil)
437 (complexity . ring)))
439 . ((offset . ,(assoc-get 'two CENTRAL-COLUMN-HOLE-PLACEMENTS))
440 (stencil . ,ring-column-circle-stencil)
442 (complexity . ring)))
444 . ((offset . ,(assoc-get 'three CENTRAL-COLUMN-HOLE-PLACEMENTS))
445 (stencil . ,ring-column-circle-stencil)
447 (complexity . ring)))
449 . ((offset . ,(assoc-get 'four CENTRAL-COLUMN-HOLE-PLACEMENTS))
450 (stencil . ,ring-column-circle-stencil)
452 (complexity . ring)))
454 . ((offset . ,(assoc-get 'five CENTRAL-COLUMN-HOLE-PLACEMENTS))
455 (stencil . ,ring-column-circle-stencil)
457 (complexity . ring)))
459 . ((offset . ,(assoc-get 'six CENTRAL-COLUMN-HOLE-PLACEMENTS))
460 (stencil . ,ring-column-circle-stencil)
462 (complexity . ring)))
464 . ((offset . (0.0 . 6.25))
465 (stencil . ,(variable-column-circle-stencil 0.4))
467 (complexity . trill)))))
470 . ((offset . (0.0 . 0.0))
471 (stencil . ,oboe-lh-I-key-stencil)
473 (complexity . trill)))
475 . ((offset . (0.0 . 2.6))
476 (stencil . ,oboe-lh-III-key-stencil)
477 (text? . ("III" . #f))
478 (complexity . trill)))
480 . ((offset . (0.0 . 0.0))
481 (stencil . ,oboe-lh-II-key-stencil)
482 (text? . ("II" . #f))
483 (complexity . trill)))
485 . ((offset . (0.0 . 0.0))
486 (stencil . ,oboe-lh-b-key-stencil)
488 (complexity . trill)))
490 . ((offset . (0.0 . 0.0))
491 (stencil . ,oboe-lh-d-key-stencil)
493 (complexity . trill)))
495 . ((offset . (0.0 . 0.0))
496 (stencil . ,oboe-lh-cis-key-stencil)
498 (complexity . trill)))
500 . ((offset . (-0.85 . 0.2))
501 (stencil . ,oboe-lh-gis-key-stencil)
503 (complexity . trill)))
505 . ((offset . (2.05 . -3.65))
506 (stencil . ,oboe-lh-ees-key-stencil)
508 (complexity . trill)))
510 . ((offset . (3.6 . 0.5))
511 (stencil . ,oboe-lh-low-b-key-stencil)
513 (complexity . trill)))
515 . ((offset . (2.25 . -4.15))
516 (stencil . ,oboe-lh-bes-key-stencil)
518 (complexity . trill)))
520 . ((offset . (2.15 . -3.85))
521 (stencil . ,oboe-lh-f-key-stencil)
523 (complexity . trill)))))
526 . ((offset . (1.5 . 1.2))
527 (stencil . ,oboe-rh-a-key-stencil)
529 (complexity . trill)))
531 . ((offset . (0.0 . 0.0))
532 (stencil . ,oboe-rh-gis-key-stencil)
534 (complexity . trill)))
536 . ((offset . (0.0 . 0.0))
537 (stencil . ,oboe-rh-d-key-stencil)
539 (complexity . trill)))
541 . ((offset . (0.0 . 0.0))
542 (stencil . ,oboe-rh-f-key-stencil)
544 (complexity . trill)))
546 . ((offset . (0.0 . 0.0))
547 (stencil . ,oboe-rh-banana-key-stencil)
548 (text? . ("ban" . #f))
549 (complexity . trill)))
551 . ((offset . (0.0 . 0.0))
552 (stencil . ,oboe-rh-c-key-stencil)
554 (complexity . trill)))
556 . ((offset . (3.8 . -0.6))
557 (stencil . ,oboe-rh-cis-key-stencil)
559 (complexity . trill)))
561 . ((offset . (0.0 . -1.8))
562 (stencil . ,oboe-rh-ees-key-stencil)
564 (complexity . trill)))))))
568 . (,(simple-stencil-alist '(hidden . midline) '(0.0 . 3.75))
570 . ,(make-central-column-hole-addresses
571 CENTRAL-COLUMN-HOLE-H-LIST))
572 (xy-scale-function . (,identity . ,identity))
574 (offset . (0.0 . 0.0)))
575 ((stencils . ((left-hand . I) (left-hand . III)))
576 (xy-scale-function . (,return-1 . ,return-1))
578 (offset . (-2.5 . 6.5)))
579 ,(simple-stencil-alist '(left-hand . II) '(2.5 . 6.0))
580 ,(simple-stencil-alist '(left-hand . b) '(-1.35 . 6.0))
581 ,(simple-stencil-alist '(left-hand . d) '(1.0 . 6.0))
582 ,(simple-stencil-alist '(left-hand . cis) '(1.0 . 5.0))
584 . ,(make-left-hand-key-addresses '(gis bes low-b ees f)))
585 (xy-scale-function . (,return-1 . ,return-1))
587 (offset . (0.0 . 3.9)))
589 ,(make-right-hand-key-addresses '(a gis)))
590 (xy-scale-function . (,return-1 . ,return-1))
592 (offset . (-3.5 . 3.5)))
593 ,(simple-stencil-alist '(right-hand . d) '(1.0 . 2.5))
594 ,(simple-stencil-alist '(right-hand . f) '(-1.0 . 1.5))
595 ,(simple-stencil-alist '(right-hand . banana) '(1.7 . 1.0))
596 ((stencils . ,(make-right-hand-key-addresses '(c cis ees)))
597 (xy-scale-function . (,return-1 . ,return-1))
599 (offset . (-3.4 . 0.3)))))
600 (xy-scale-function . (,identity . ,identity))
602 (offset . (0.0 . 0.0))))
604 . ((,apply-group-draw-rule-series
605 (((right-hand . a) (right-hand . gis))
606 ,(make-left-hand-key-addresses '(gis bes low-b ees))
607 ,(make-right-hand-key-addresses '(cis c ees))))
608 (,rich-group-draw-rule
611 (,rich-group-draw-rule
613 ,(make-left-hand-key-addresses '(gis bes low-b ees)))
614 (,group-automate-rule
615 ,(make-central-column-hole-addresses CENTRAL-COLUMN-HOLE-LIST))
616 (,group-automate-rule ((hidden . midline)))))
617 (extra-offset-instructions
618 . ((,rich-group-extra-offset-rule
619 ((central-column . h)) ((central-column . one)) (0.0 . 0.8))
620 (,uniform-extra-offset-rule (0.0 . 0.0))))))
624 (,(simple-stencil-alist '(hidden . midline) '(0.0 . 3.75))
626 . ,(make-central-column-hole-addresses
627 CENTRAL-COLUMN-HOLE-H-LIST))
628 (xy-scale-function . (,identity . ,identity))
630 (offset . (0.0 . 0.0)))
631 ((stencils . ,(make-left-hand-key-addresses '(III I)))
632 (textual? . ,lh-woodwind-text-stencil)
633 (offset . (-2.8 . 7.0)))
634 ((stencils . ,(make-left-hand-key-addresses '(II)))
635 (textual? . ,lh-woodwind-text-stencil)
636 (offset . (2.2 . 7.0)))
638 . ,(make-left-hand-key-addresses
639 '(b d cis gis ees low-b bes f)))
640 (textual? . ,lh-woodwind-text-stencil)
641 (offset . (1.5 . 3.75)))
643 . ,(make-right-hand-key-addresses
644 '(a gis d f banana c cis ees)))
645 (textual? . ,rh-woodwind-text-stencil)
646 (offset . (-1.25 . 0.0)))))
647 (xy-scale-function . (,identity . ,identity))
649 (offset . (0.0 . 0.0))))
651 . ((,apply-group-draw-rule-series
652 (,(make-left-hand-key-addresses '(b d cis gis ees low-b bes f))
653 ,(make-left-hand-key-addresses '(III I))
654 ,(make-right-hand-key-addresses '(a gis d f banana c cis ees))))
655 (,group-automate-rule
656 ,(make-central-column-hole-addresses CENTRAL-COLUMN-HOLE-LIST))
657 (,group-automate-rule ((hidden . midline)))))
658 (extra-offset-instructions
659 . ((,rich-group-extra-offset-rule
660 ((central-column . h))
661 ((central-column . one))
663 (,uniform-extra-offset-rule (0.0 . 0.0))))))))))
665 ;; Clarinet assembly instructions
667 (define clarinet-change-points
668 ((make-named-spreadsheet '(clarinet bass-clarinet low-bass-clarinet))
669 `((bottom-group-key-names
672 . ((offset . (0.0 . ,(* 0 (+ 0.75 CL-RH-HAIR))))
673 (stencil . ,bass-clarinet-rh-f-key-stencil)
675 (complexity . trill))))
677 . ((offset . (0.0 . ,(* 0 (+ 0.75 CL-RH-HAIR))))
678 (stencil . ,low-bass-clarinet-rh-f-key-stencil)
680 (complexity . trill)))
682 . ((offset . (,(+ 1.5 CL-RH-HAIR) . ,(* -1 (+ 0.75 CL-RH-HAIR))))
683 (stencil . ,clarinet-rh-d-key-stencil)
685 (complexity . trill)))
687 . ((offset . (0.0 . 1.4))
688 (stencil . ,clarinet-rh-low-cis-key-stencil)
690 (complexity . trill)))
692 . ((offset . (0.0 . 2.4))
693 (stencil . ,clarinet-rh-low-d-key-stencil)
695 (complexity . trill)))
697 . ((offset . (0.0 . 0.0))
698 (stencil . ,clarinet-rh-low-c-key-stencil)
700 (complexity . trill))))))
701 (left-extra-key-names
705 . ((offset . (4.0 . -0.8))
706 (stencil . ,clarinet-lh-d-key-stencil)
708 (complexity . trill))))))
713 . ,(make-right-hand-key-addresses '(low-c low-cis)))
714 (xy-scale-function . (,return-1 . ,return-1))
716 (offset . (-1.3 . 4.0))))))
717 (low-left-hand-key-addresses
718 . (,(make-left-hand-key-addresses '(cis f e fis))
719 ,(make-left-hand-key-addresses '(cis f e fis))
720 ,(make-left-hand-key-addresses '(cis f e fis d))))
721 (all-left-hand-key-addresses
722 . (,(make-left-hand-key-addresses '(a gis ees cis f e fis))
723 ,(make-left-hand-key-addresses '(a gis ees cis f e fis))
724 ,(make-left-hand-key-addresses '(a gis ees cis f e fis d))))
728 (,(make-right-hand-key-addresses '(low-c low-cis)))))
732 ((,rich-group-draw-rule
734 ,(make-left-hand-key-addresses '(cis f e fis)))
735 (,rich-group-draw-rule
736 ((right-hand . low-d))
737 ((right-hand . low-cis) (right-hand . low-c))))))
738 (low-extra-offset-rule
741 ((,rich-group-extra-offset-rule
742 ,(make-right-hand-key-addresses '(low-c low-d low-cis))
743 ,(make-right-hand-key-addresses '(one two three four))
745 (bottom-right-group-key-addresses
746 . (,(make-right-hand-key-addresses '(fis e ees gis))
747 ,(make-right-hand-key-addresses '(fis e ees gis f))
748 ,(make-right-hand-key-addresses '(fis e ees gis f d))))
749 (right-hand-key-addresses
750 . (,(make-right-hand-key-addresses '(fis e ees gis))
751 ,(make-right-hand-key-addresses '(fis e ees gis f))
752 ,(make-right-hand-key-addresses
753 '(low-d low-cis low-c fis e ees gis f d)))))))
755 (define (generate-clarinet-family-entry clarinet-name)
758 (get-named-spreadsheet-column clarinet-name clarinet-change-points)))
763 . ((offset . (0.0 . 0.0))
764 (stencil . ,midline-stencil)
766 (complexity . basic)))))
769 . ((offset . ,(assoc-get 'one CENTRAL-COLUMN-HOLE-PLACEMENTS))
770 (stencil . ,column-circle-stencil)
772 (complexity . covered)))
774 . ((offset . ,(assoc-get 'two CENTRAL-COLUMN-HOLE-PLACEMENTS))
775 (stencil . ,column-circle-stencil)
777 (complexity . covered)))
779 . ((offset . ,(assoc-get 'three CENTRAL-COLUMN-HOLE-PLACEMENTS))
780 (stencil . ,column-circle-stencil)
782 (complexity . covered)))
784 . ((offset . ,(assoc-get 'four CENTRAL-COLUMN-HOLE-PLACEMENTS))
785 (stencil . ,column-circle-stencil)
787 (complexity . covered)))
789 . ((offset . ,(assoc-get 'five CENTRAL-COLUMN-HOLE-PLACEMENTS))
790 (stencil . ,column-circle-stencil)
792 (complexity . covered)))
794 . ((offset . ,(assoc-get 'six CENTRAL-COLUMN-HOLE-PLACEMENTS))
795 (stencil . ,column-circle-stencil)
797 (complexity . covered)))
799 . ((offset . (0.0 . 6.25))
800 (stencil . ,(variable-column-circle-stencil 0.4))
802 (complexity . covered)))))
805 . ((offset . (0.0 . 0.0))
806 (stencil . ,clarinet-lh-thumb-key-stencil)
808 (complexity . trill)))
810 . ((offset . (1.0 . 1.0))
811 (stencil . ,clarinet-lh-R-key-stencil)
813 (complexity . trill)))
815 . ((offset . (0.0 . 0.0))
816 (stencil . ,clarinet-lh-a-key-stencil)
818 (complexity . trill)))
820 . ((offset . (0.8 . 1.0))
821 (stencil . ,clarinet-lh-gis-key-stencil)
823 (complexity . trill)))
825 . ((offset . (0.0 . 0.0))
826 (stencil . ,clarinet-lh-ees-key-stencil)
828 (complexity . trill)))
830 . ((offset . (-0.85 . 0.2))
831 (stencil . ,clarinet-lh-cis-key-stencil)
833 (complexity . trill)))
835 . ((offset . (3.6 . 0.5))
836 (stencil . ,clarinet-lh-f-key-stencil)
838 (complexity . trill)))
840 . ((offset . (2.05 . -3.65))
841 (stencil . ,clarinet-lh-e-key-stencil)
843 (complexity . trill)))
845 . ((offset . (2.25 . -4.15))
846 (stencil . ,clarinet-lh-fis-key-stencil)
848 (complexity . trill))))
849 (assoc-get 'left-extra-key-names change-points)))
852 . ((offset . (0.0 . 0.75))
853 (stencil . ,clarinet-rh-one-key-stencil)
855 (complexity . trill)))
857 . ((offset . (0.0 . 0.25))
858 (stencil . ,clarinet-rh-two-key-stencil)
860 (complexity . trill)))
862 . ((offset . (0.0 . -0.25))
863 (stencil . ,clarinet-rh-three-key-stencil)
865 (complexity . trill)))
867 . ((offset . (0.0 . -0.75))
868 (stencil . ,clarinet-rh-four-key-stencil)
870 (complexity . trill)))
872 . ((offset . (0.0 . 0.0))
873 (stencil . ,clarinet-rh-b-key-stencil)
875 (complexity . trill)))
877 . ((offset . (0.0 . ,(* 4 (+ 0.75 CL-RH-HAIR))))
878 (stencil . ,clarinet-rh-fis-key-stencil)
880 (complexity . trill)))
882 . ((offset . (,(+ 1.5 CL-RH-HAIR)
883 . ,(* 3 (+ 0.75 CL-RH-HAIR))))
884 (stencil . ,clarinet-rh-e-key-stencil)
886 (complexity . trill)))
888 . ((offset . (0.0 . ,(* 2 (+ 0.75 CL-RH-HAIR))))
889 (stencil . ,clarinet-rh-ees-key-stencil)
891 (complexity . trill)))
893 . ((offset . (,(+ 1.5 CL-RH-HAIR)
894 . ,(* 1 (+ 0.75 CL-RH-HAIR))))
895 (stencil . ,clarinet-rh-gis-key-stencil)
897 (complexity . trill))))
898 (assoc-get 'bottom-group-key-names change-points)))))
902 . ,(append (assoc-get 'right-thumb-group change-points)
903 `(,(simple-stencil-alist '(hidden . midline)
906 . ,(make-central-column-hole-addresses
907 CENTRAL-COLUMN-HOLE-H-LIST))
908 (xy-scale-function . (,identity . ,identity))
910 (offset . (0.0 . 0.0)))
912 . ,(make-left-hand-key-addresses '(thumb R)))
913 (xy-scale-function . (,identity . ,identity))
915 (offset . (-2.5 . 6.5)))
917 . ((left-hand . a) (left-hand . gis)))
918 (xy-scale-function . (,return-1 . ,return-1))
920 (offset . (0.0 . 7.5)))
921 ,(simple-stencil-alist '(left-hand . ees)
924 . ,(make-left-hand-key-addresses '(cis f e fis)))
925 (xy-scale-function . (,return-1 . ,return-1))
927 (offset . (0.0 . 3.9)))
929 . ,(make-right-hand-key-addresses
930 '(one two three four)))
931 (xy-scale-function . (,return-1 . ,return-1))
933 (offset . (-1.25 . 3.75)))
934 ,(simple-stencil-alist '(right-hand . b)
937 . ,(assoc-get 'bottom-right-group-key-addresses
939 (xy-scale-function . (,return-1 . ,return-1))
941 (offset . (-4.0 . -0.75))))))
942 (xy-scale-function . (,identity . ,identity))
944 (offset . (0.0 . 0.0))))
946 . ,(append (assoc-get 'low-rich-draw-rules change-points)
947 `((,apply-group-draw-rule-series
948 ,(append (assoc-get 'low-key-group change-points)
949 `(((left-hand . a) (left-hand . gis))
950 ,(make-right-hand-key-addresses
951 '(one two three four))
952 ,(assoc-get 'low-left-hand-key-addresses
954 ,(assoc-get 'right-hand-key-addresses
956 (,rich-group-draw-rule
958 ((left-hand . thumb)))
959 (,group-automate-rule
960 ,(make-central-column-hole-addresses
961 CENTRAL-COLUMN-HOLE-LIST))
962 (,group-automate-rule ((hidden . midline))))))
963 (extra-offset-instructions
964 . ,(append (assoc-get 'low-extra-offset-rule change-points)
965 `((,rich-group-extra-offset-rule
966 ((central-column . h))
967 ((central-column . one)
971 (,uniform-extra-offset-rule (0.0 . 0.0)))))))
975 . (,(simple-stencil-alist '(hidden . midline) '(0.0 . 3.75))
977 . ,(make-central-column-hole-addresses
978 CENTRAL-COLUMN-HOLE-LIST))
979 (xy-scale-function . (,identity . ,identity))
981 (offset . (0.0 . 0.0)))
982 ((stencils . ((left-hand . thumb) (left-hand . R)))
983 (xy-scale-function . (,identity . ,identity))
985 (offset . (-2.5 . 6.5)))
987 . ,(assoc-get 'all-left-hand-key-addresses change-points))
988 (textual? . ,lh-woodwind-text-stencil)
989 (offset . (1.5 . 3.75)))
991 . ,(make-right-hand-key-addresses '(one two three four)))
992 (textual? . ,number-column-stencil)
993 (offset . (-1.25 . 3.75)))
994 ((stencils . ,(assoc-get 'right-hand-key-addresses
996 (textual? . ,rh-woodwind-text-stencil)
997 (offset . (-1.25 . 0.0)))))
998 (xy-scale-function . (,identity . ,identity))
1000 (offset . (0.0 . 0.0))))
1002 . ((,apply-group-draw-rule-series
1003 (,(assoc-get 'all-left-hand-key-addresses change-points)
1004 ,(make-right-hand-key-addresses '(one two three four))
1005 ,(assoc-get 'right-hand-key-addresses change-points)))
1006 (,group-automate-rule
1007 ,(make-central-column-hole-addresses
1008 CENTRAL-COLUMN-HOLE-LIST))
1009 (,group-automate-rule ((hidden . midline)))))
1010 (extra-offset-instructions
1011 . ((,rich-group-extra-offset-rule
1012 ((central-column . h))
1013 ((central-column . one) (left-hand . a) (left-hand . gis))
1015 (,uniform-extra-offset-rule (0.0 . 0.0))))))))))
1017 ;; Saxophone assembly instructions
1019 (define (saxophone-name-passerelle name)
1020 (cond ((eqv? name 'saxophone) 'saxophone)
1021 ((eqv? name 'soprano-saxophone) 'saxophone)
1022 ((eqv? name 'alto-saxophone) 'saxophone)
1023 ((eqv? name 'tenor-saxophone) 'saxophone)
1024 ((eqv? name 'baritone-saxophone) 'baritone-saxophone)))
1026 (define saxophone-change-points
1027 ((make-named-spreadsheet '(saxophone baritone-saxophone))
1028 `((low-a-key-definition
1031 . ((offset . (0.0 . 0.0))
1032 (stencil . ,saxophone-lh-low-a-key-stencil)
1034 (complexity . trill))))))
1037 (,(simple-stencil-alist '(left-hand . low-a) '(-5.0 . 7.0)))))
1040 ((left-hand . low-a))))
1041 (left-hand-key-names
1042 . (,(make-right-hand-key-addresses
1043 '(ees d f front-f bes gis cis b low-bes))
1044 ,(make-right-hand-key-addresses
1045 '(ees d f front-f bes gis cis b low-bes low-a)))))))
1047 (define (generate-saxophone-family-entry saxophone-name)
1050 (get-named-spreadsheet-column
1051 (saxophone-name-passerelle saxophone-name) saxophone-change-points)))
1056 . ((offset . (0.0 . 0.0))
1057 (stencil . ,midline-stencil)
1059 (complexity . basic)))))
1062 . ((offset . ,(assoc-get 'one CENTRAL-COLUMN-HOLE-PLACEMENTS))
1063 (stencil . ,column-circle-stencil)
1065 (complexity . trill)))
1067 . ((offset . ,(assoc-get 'two CENTRAL-COLUMN-HOLE-PLACEMENTS))
1068 (stencil . ,column-circle-stencil)
1070 (complexity . trill)))
1072 . ((offset . ,(assoc-get 'three CENTRAL-COLUMN-HOLE-PLACEMENTS))
1073 (stencil . ,column-circle-stencil)
1075 (complexity . trill)))
1077 . ((offset . ,(assoc-get 'four CENTRAL-COLUMN-HOLE-PLACEMENTS))
1078 (stencil . ,column-circle-stencil)
1080 (complexity . trill)))
1082 . ((offset . ,(assoc-get 'five CENTRAL-COLUMN-HOLE-PLACEMENTS))
1083 (stencil . ,column-circle-stencil)
1085 (complexity . trill)))
1087 . ((offset . ,(assoc-get 'six CENTRAL-COLUMN-HOLE-PLACEMENTS))
1088 (stencil . ,column-circle-stencil)
1090 (complexity . trill)))))
1092 . ,(append (assoc-get 'low-a-key-definition change-points)
1094 . ((offset . (0.0 . 0.0))
1095 (stencil . ,saxophone-lh-T-key-stencil)
1096 (text? . ("T" . #f))
1097 (complexity . trill)))
1099 . ((offset . (0.4 . 1.6))
1100 (stencil . ,saxophone-lh-ees-key-stencil)
1102 (complexity . trill)))
1104 . ((offset . (1.5 . 0.5))
1105 (stencil . ,saxophone-lh-d-key-stencil)
1106 (text? . ("D" . #f))
1107 (complexity . trill)))
1109 . ((offset . (0.0 . 0.0))
1110 (stencil . ,saxophone-lh-f-key-stencil)
1111 (text? . ("F" . #f))
1112 (complexity . trill)))
1114 . ((offset . (0.0 . 0.0))
1115 (stencil . ,saxophone-lh-front-f-key-stencil)
1116 (text? . ("f" . #f))
1117 (complexity . trill)))
1119 . ((offset . (0.0 . 0.0))
1120 (stencil . ,saxophone-lh-bes-key-stencil)
1122 (complexity . trill)))
1124 . ((offset . (0.0 . 1.1))
1125 (stencil . ,saxophone-lh-gis-key-stencil)
1127 (complexity . trill)))
1129 . ((offset . (2.4 . 0.0))
1130 (stencil . ,saxophone-lh-cis-key-stencil)
1132 (complexity . trill)))
1134 . ((offset . (0.0 . 0.0))
1135 (stencil . ,saxophone-lh-b-key-stencil)
1136 (text? . ("B" . #f))
1137 (complexity . trill)))
1139 . ((offset . (0.0 . -0.2))
1140 (stencil . ,saxophone-lh-low-bes-key-stencil)
1142 (complexity . trill))))))
1145 . ((offset . (0.0 . 2.0))
1146 (stencil . ,saxophone-rh-e-key-stencil)
1147 (text? . ("E" . #f))
1148 (complexity . trill)))
1150 . ((offset . (0.0 . 0.9))
1151 (stencil . ,saxophone-rh-c-key-stencil)
1152 (text? . ("C" . #f))
1153 (complexity . trill)))
1155 . ((offset . (0.0 . 0.0))
1156 (stencil . ,saxophone-rh-bes-key-stencil)
1158 (complexity . trill)))
1160 . ((offset . (0.0 . 0.0))
1161 (stencil . ,saxophone-rh-high-fis-key-stencil)
1162 (text? . ("hF" . 1))
1163 (complexity . trill)))
1165 . ((offset . (0.0 . 0.0))
1166 (stencil . ,saxophone-rh-fis-key-stencil)
1168 (complexity . trill)))
1170 . ((offset . (0.0 . 0.7))
1171 (stencil . ,saxophone-rh-ees-key-stencil)
1173 (complexity . trill)))
1175 . ((offset . (-1.2 . -0.1))
1176 (stencil . ,saxophone-rh-low-c-key-stencil)
1177 (text? . ("c" . #f))
1178 (complexity . trill)))))))
1182 . ,(append (assoc-get 'low-a-key-group change-points)
1183 `(,(simple-stencil-alist '(hidden . midline)
1186 . ,(make-central-column-hole-addresses
1187 CENTRAL-COLUMN-HOLE-LIST))
1188 (xy-scale-function . (,identity . ,identity))
1190 (offset . (0.0 . 0.0)))
1192 . ,(make-left-hand-key-addresses '(ees d f)))
1193 (xy-scale-function . (,return-1 . ,return-1))
1195 (offset . (1.5 . 6.8)))
1196 ,(simple-stencil-alist '(left-hand . front-f)
1198 ,(simple-stencil-alist '(left-hand . T)
1200 ,(simple-stencil-alist '(left-hand . bes)
1203 . ,(make-left-hand-key-addresses
1204 '(gis cis b low-bes)))
1205 (xy-scale-function . (,return-1 . ,return-1))
1207 (offset . (1.2 . 3.5)))
1209 . ,(make-right-hand-key-addresses '(e c bes)))
1210 (xy-scale-function . (,return-1 . ,return-1))
1212 (offset . (-2.3 . 3.4)))
1213 ,(simple-stencil-alist '(right-hand . high-fis)
1215 ,(simple-stencil-alist '(right-hand . fis)
1218 . ,(make-right-hand-key-addresses '(ees low-c)))
1219 (xy-scale-function . (,return-1 . ,return-1))
1221 (offset . (-2.0 . 0.3))))))
1222 (xy-scale-function . (,identity . ,identity))
1224 (offset . (0.0 . 0.0))))
1226 . ((,apply-group-draw-rule-series
1227 (,(make-left-hand-key-addresses '(ees d f))
1228 ,(make-left-hand-key-addresses '(gis cis b low-bes))
1229 ,(make-right-hand-key-addresses '(e c bes))
1230 ,(make-right-hand-key-addresses '(ees low-c))))
1231 (,group-automate-rule
1232 ,(make-central-column-hole-addresses CENTRAL-COLUMN-HOLE-LIST))
1233 (,group-automate-rule ((hidden . midline)))))
1234 (extra-offset-instructions
1235 . ((,rich-group-extra-offset-rule
1237 ,(append (assoc-get 'low-a-presence change-points)
1238 '((central-column . one)
1239 (left-hand . front-f)
1245 (,uniform-extra-offset-rule (0.0 . 0.0))))))
1249 . (,(simple-stencil-alist '(hidden . midline) '(0.0 . 3.75))
1251 . ,(make-central-column-hole-addresses
1252 CENTRAL-COLUMN-HOLE-LIST))
1253 (xy-scale-function . (,identity . ,identity))
1255 (offset . (0.0 . 0.0)))
1256 ,(simple-stencil-alist '(left-hand . T) '(-1.0 . 7.0))
1258 . ,(assoc-get 'left-hand-key-names change-points))
1259 (textual? . ,lh-woodwind-text-stencil)
1260 (offset . (1.5 . 3.75)))
1262 . ,(make-right-hand-key-addresses
1263 '(e c bes high-fis fis ees low-c)))
1264 (textual? . ,rh-woodwind-text-stencil)
1265 (offset . (-1.25 . 0.0)))))
1266 (xy-scale-function . (,identity . ,identity))
1268 (offset . (0.0 . 0.0))))
1270 . ((,apply-group-draw-rule-series
1271 (,(make-left-hand-key-addresses
1272 '(ees d f front-f bes gis cis b low-bes))
1273 ,(make-right-hand-key-addresses
1274 '(e c bes high-fis fis ees low-c))))
1275 (,group-automate-rule
1276 ,(make-central-column-hole-addresses
1277 CENTRAL-COLUMN-HOLE-LIST))
1278 (,group-automate-rule ((hidden . midline)))))
1279 (extra-offset-instructions
1280 . ((,uniform-extra-offset-rule (0.0 . 0.0))))))))))
1282 ;; Bassoon assembly instructions
1284 (define bassoon-change-points
1285 ((make-named-spreadsheet '(bassoon contrabassoon))
1286 `((left-hand-additional-keys .
1288 ((offset . (0.0 . -0.3))
1289 (stencil . ,bassoon-lh-a-flick-key-stencil)
1290 (text? . ("A" . #f))
1291 (complexity . trill)))
1293 ((offset . (0.0 . 0.0))
1294 (stencil . ,bassoon-lh-whisper-key-stencil)
1295 (text? . ("w" . #f))
1296 (complexity . trill))))
1298 (right-hand-additional-keys .
1300 ((offset . (0.0 . 0.0))
1301 (stencil . ,bassoon-rh-cis-key-stencil)
1303 (complexity . trill)))
1305 ((offset . (0.0 . 0.0))
1306 (stencil . ,bassoon-rh-thumb-gis-key-stencil)
1308 (complexity . trill))))
1310 (left-hand-flick-group .
1311 (((left-hand . d) (left-hand . c) (left-hand . a))
1312 ((left-hand . d) (left-hand . c))))
1313 (left-hand-thumb-group .
1314 (((left-hand . w) (left-hand . thumb-cis))
1315 ((left-hand . thumb-cis))))
1316 (cis-offset-instruction .
1317 (((,rich-group-extra-offset-rule
1318 ((right-hand . cis))
1320 '((hidden . midline) (hidden . long-midline))
1321 (make-central-column-hole-addresses '(three two one))
1322 (make-left-hand-key-addresses
1323 '(low-b low-bes low-c low-d d a c w thumb-cis
1324 high-ees high-e cis ees)))
1327 (right-hand-lower-thumb-group .
1328 (((right-hand . thumb-gis) (right-hand . thumb-fis))
1329 ((right-hand . thumb-fis))))
1330 (right-hand-cis-key .
1331 ((,(simple-stencil-alist '(right-hand . cis) '(-2.3 . 3.22)))
1333 (back-left-hand-key-addresses .
1334 ((low-b low-bes low-c low-d d a c w thumb-cis)
1335 (low-b low-bes low-c low-d d c thumb-cis)))
1336 (front-right-hand-key-addresses .
1337 ((cis bes fis f gis) (bes fis f gis)))
1338 (back-right-hand-key-addresses .
1339 ((thumb-bes thumb-gis thumb-e thumb-fis)
1340 (thumb-bes thumb-e thumb-fis))))))
1342 (define (generate-bassoon-family-entry bassoon-name)
1345 (get-named-spreadsheet-column bassoon-name bassoon-change-points)))
1350 . ((offset . (0.0 . 0.0))
1351 (stencil . ,midline-stencil)
1353 (complexity . basic)))
1355 . ((offset . (0.0 . 0.0))
1356 (stencil . ,long-midline-stencil)
1358 (complexity . basic)))))
1361 . ((offset . ,(assoc-get 'one CENTRAL-COLUMN-HOLE-PLACEMENTS))
1362 (stencil . ,bassoon-cc-one-key-stencil)
1364 (complexity . trill)))
1366 . ((offset . ,(assoc-get 'two CENTRAL-COLUMN-HOLE-PLACEMENTS))
1367 (stencil . ,ring-column-circle-stencil)
1369 (complexity . ring)))
1371 . ((offset . ,(assoc-get 'three CENTRAL-COLUMN-HOLE-PLACEMENTS))
1372 (stencil . ,ring-column-circle-stencil)
1374 (complexity . ring)))
1376 . ((offset . ,(assoc-get 'four CENTRAL-COLUMN-HOLE-PLACEMENTS))
1377 (stencil . ,ring-column-circle-stencil)
1379 (complexity . ring)))
1381 . ((offset . ,(assoc-get 'five CENTRAL-COLUMN-HOLE-PLACEMENTS))
1382 (stencil . ,ring-column-circle-stencil)
1384 (complexity . ring)))
1386 . ((offset . ,(assoc-get 'six CENTRAL-COLUMN-HOLE-PLACEMENTS))
1387 (stencil . ,ring-column-circle-stencil)
1389 (complexity . ring)))))
1391 . ,(append (assoc-get 'left-hand-additional-keys
1394 . ((offset . (0.0 . 0.0))
1395 (stencil . ,bassoon-lh-he-key-stencil)
1396 (text? . ("hE" . #f))
1397 (complexity . trill)))
1399 . ((offset . (0.0 . 0.0))
1400 (stencil . ,bassoon-lh-hees-key-stencil)
1401 (text? . ("hE" . 0))
1402 (complexity . trill)))
1404 . ((offset . (-1.0 . 1.0))
1405 (stencil . ,bassoon-lh-ees-key-stencil)
1407 (complexity . trill)))
1409 . ((offset . (0.0 . 0.0))
1410 (stencil . ,bassoon-lh-cis-key-stencil)
1412 (complexity . trill)))
1414 . ((offset . (0.0 . 0.0))
1415 (stencil . ,bassoon-lh-lbes-key-stencil)
1417 (complexity . trill)))
1419 . ((offset . (-1.0 . -0.7))
1420 (stencil . ,bassoon-lh-lb-key-stencil)
1421 (text? . ("b" . #f))
1422 (complexity . trill)))
1424 . ((offset . (0.0 . 0.0))
1425 (stencil . ,bassoon-lh-lc-key-stencil)
1426 (text? . ("c" . #f))
1427 (complexity . trill)))
1429 . ((offset . (0.0 . 0.0))
1430 (stencil . ,bassoon-lh-ld-key-stencil)
1431 (text? . ("d" . #f))
1432 (complexity . trill)))
1434 . ((offset . (-1.5 . 2.0))
1435 (stencil . ,bassoon-lh-d-flick-key-stencil)
1436 (text? . ("D" . #f))
1437 (complexity . trill)))
1439 . ((offset . (-0.8 . 1.1))
1440 (stencil . ,bassoon-lh-c-flick-key-stencil)
1441 (text? . ("C" . #f))
1442 (complexity . trill)))
1444 . ((offset . (2.0 . -1.0))
1445 (stencil . ,bassoon-lh-thumb-cis-key-stencil)
1447 (complexity . trill))))))
1449 . ,(append (assoc-get 'right-hand-additional-keys
1452 . ((offset . (0.0 . 0.8))
1453 (stencil . ,bassoon-rh-bes-key-stencil)
1455 (complexity . trill)))
1457 . ((offset . (-2.2 . 4.35))
1458 (stencil . ,bassoon-rh-f-key-stencil)
1459 (text? . ("F" . #f))
1460 (complexity . trill)))
1462 . ((offset . (1.5 . 1.0))
1463 (stencil . ,bassoon-rh-fis-key-stencil)
1465 (complexity . trill)))
1467 . ((offset . (0.0 . -0.15))
1468 (stencil . ,bassoon-rh-gis-key-stencil)
1470 (complexity . trill)))
1472 . ((offset . (0.0 . 0.0))
1473 (stencil . ,bassoon-rh-thumb-bes-key-stencil)
1475 (complexity . trill)))
1477 . ((offset . (1.75 . 0.4))
1478 (stencil . ,bassoon-rh-thumb-e-key-stencil)
1479 (text? . ("E" . #f))
1480 (complexity . trill)))
1482 . ((offset . (-1.0 . 1.6))
1483 (stencil . ,bassoon-rh-thumb-fis-key-stencil)
1485 (complexity . trill))))))))
1489 . ,(append (assoc-get 'right-hand-cis-key change-points)
1490 `(,(simple-stencil-alist '(hidden . midline)
1492 ,(simple-stencil-alist '(hidden . long-midline)
1495 . ,(make-central-column-hole-addresses
1496 CENTRAL-COLUMN-HOLE-LIST))
1497 (xy-scale-function . (,identity . ,identity))
1499 (offset . (0.0 . 0.0)))
1500 ,(simple-stencil-alist '(left-hand . high-e)
1502 ,(simple-stencil-alist '(left-hand . high-ees)
1505 . ((left-hand . ees) (left-hand . cis)))
1506 (xy-scale-function . (,return-1 . ,return-1))
1508 (offset . (3.0 . 3.75)))
1511 . ((left-hand . low-b)
1512 (left-hand . low-bes)))
1514 . (,return-1 . ,return-1))
1516 (offset . (-2.0 . 9.0)))
1518 . ,(assoc-get 'left-hand-flick-group
1521 . (,return-1 . ,return-1))
1523 (offset . (3.0 . 7.0)))
1524 ,(simple-stencil-alist '(left-hand . low-c)
1526 ,(simple-stencil-alist '(left-hand . low-d)
1529 . ,(assoc-get 'left-hand-thumb-group
1532 . (,return-1 . ,return-1))
1534 (offset . (1.5 . -0.6)))))
1535 (xy-scale-function . (,return-1 . ,return-1))
1537 (offset . (-5.5 . 4.7)))
1538 ,(simple-stencil-alist '(right-hand . bes)
1541 . ,(make-right-hand-key-addresses '(gis f fis)))
1542 (xy-scale-function . (,return-1 . ,return-1))
1544 (offset . (2.0 . -1.25)))
1547 . ((right-hand . thumb-bes)
1548 (right-hand . thumb-e)))
1550 . (,return-1 . ,return-1))
1552 (offset . (-1.22 . 5.25)))
1554 . ,(assoc-get 'right-hand-lower-thumb-group
1557 . (,return-1 . ,return-1))
1559 (offset . (0.0 . 0.0)))))
1561 . (,return-1 . ,return-1))
1563 (offset . (-5.0 . 0.0))))))
1564 (xy-scale-function . (,identity . ,identity))
1566 (offset . (0.0 . 0.0))))
1568 . ((,apply-group-draw-rule-series
1569 (,(make-left-hand-key-addresses '(ees cis))
1570 ,(make-left-hand-key-addresses
1571 (assoc-get 'back-left-hand-key-addresses change-points))
1572 ,(make-right-hand-key-addresses '(f fis gis))
1573 ,(make-right-hand-key-addresses
1574 (assoc-get 'back-right-hand-key-addresses change-points))))
1575 (,group-automate-rule
1576 ,(make-central-column-hole-addresses
1577 CENTRAL-COLUMN-HOLE-LIST))
1578 (,bassoon-midline-rule
1580 (make-left-hand-key-addresses
1581 (assoc-get 'back-left-hand-key-addresses change-points))
1582 (make-right-hand-key-addresses
1583 (assoc-get 'back-right-hand-key-addresses
1585 (extra-offset-instructions
1587 (assoc-get 'cis-offset-instruction change-points)
1588 `((,uniform-extra-offset-rule (0.0 . 0.0)))))))
1592 . (,(simple-stencil-alist '(hidden . midline) '(0.0 . 3.75))
1594 . ,(make-central-column-hole-addresses
1595 CENTRAL-COLUMN-HOLE-LIST))
1596 (xy-scale-function . (,identity . ,identity))
1598 (offset . (0.0 . 0.0)))
1600 . ,(make-left-hand-key-addresses
1601 '(high-e high-ees ees cis)))
1602 (textual? . ,lh-woodwind-text-stencil)
1603 (offset . (1.5 . 3.75)))
1605 . ,(make-left-hand-key-addresses
1606 (assoc-get 'back-left-hand-key-addresses
1608 (textual? . ,rh-woodwind-text-stencil)
1609 (offset . (-1.25 . 3.75)))
1611 . ,(make-right-hand-key-addresses
1612 (assoc-get 'front-right-hand-key-addresses
1614 (textual? . ,lh-woodwind-text-stencil)
1615 (offset . (1.5 . 0.0)))
1617 ,(make-right-hand-key-addresses
1618 (assoc-get 'back-right-hand-key-addresses
1620 (textual? . ,rh-woodwind-text-stencil)
1621 (offset . (-1.25 . 0.0)))))
1622 (xy-scale-function . (,identity . ,identity))
1624 (offset . (0.0 . 0.0))))
1626 . ((,apply-group-draw-rule-series
1627 (,(make-left-hand-key-addresses
1628 (assoc-get 'back-left-hand-key-addresses change-points))
1629 ,(make-right-hand-key-addresses
1630 (assoc-get 'front-right-hand-key-addresses change-points))
1631 ,(make-right-hand-key-addresses
1632 (assoc-get 'back-right-hand-key-addresses change-points))
1633 ,(make-left-hand-key-addresses '(high-e high-ees ees cis))))
1634 (,group-automate-rule
1635 ,(make-central-column-hole-addresses
1636 CENTRAL-COLUMN-HOLE-LIST))
1637 (,group-automate-rule ((hidden . midline)))))
1638 (extra-offset-instructions
1639 . ((,uniform-extra-offset-rule (0.0 . 0.0))))))))))
1641 ;; Assembly functions
1643 ; Scans a bank for name.
1644 ; for example, '(left-hand . bes) will return bes in the left-hand
1646 (define (get-key name bank)
1647 (assoc-get (cdr name) (assoc-get (car name) bank)))
1649 (define (translate-key-instruction key-instruction)
1651 ((key-name (car key-instruction))
1652 (key-complexity (assoc-get 'complexity (cdr key-instruction))))
1654 ((eqv? key-complexity 'basic)
1655 `((,key-name . ,(assoc-get 'F HOLE-FILL-LIST))))
1656 ((eqv? key-complexity 'trill)
1657 (make-symbol-alist key-name #t #f))
1658 ((eqv? key-complexity 'covered)
1659 (make-symbol-alist key-name #f #f))
1660 ((eqv? key-complexity 'ring)
1661 (make-symbol-alist key-name #f #t)))))
1663 (define (update-possb-list input-key possibility-list canonic-list)
1664 (if (null? possibility-list)
1665 (ly:error "woodwind markup error - invalid key or hole requested")
1667 (assoc-get input-key (cdar possibility-list))
1669 `(((,(caaar possibility-list) .
1670 ,(assoc-get input-key (cdar possibility-list))) .
1671 ,(assoc-get (caar possibility-list) canonic-list)))
1672 (assoc-remove (caar possibility-list) canonic-list))
1673 (update-possb-list input-key (cdr possibility-list) canonic-list))))
1675 (define (key-crawler input-list possibility-list)
1676 (if (null? input-list)
1677 (map car possibility-list)
1683 possibility-list))))
1685 (define (translate-draw-instructions input-alist key-name-alist)
1687 (map (lambda (short long)
1690 (map (lambda (instr)
1691 `(((,long . ,(car instr)) . 0)
1692 . ,(translate-key-instruction instr)))
1693 (assoc-get long key-name-alist))))
1694 (key-crawler (assoc-get short input-alist) key-instructions)))
1696 '(hidden central-column left-hand right-hand))))
1698 (define (uniform-draw-instructions key-name-alist)
1701 (map (lambda (key-instructions)
1702 `((,long . ,(car key-instructions)) . 1))
1703 (assoc-get long key-name-alist)))
1704 '(hidden central-column left-hand right-hand))))
1706 (define (list-all-possible-keys key-name-alist)
1707 (map (lambda (short long)
1709 . ,(map (lambda (key-instructions)
1710 (car key-instructions))
1711 (assoc-get long key-name-alist))))
1713 '(central-column left-hand right-hand)))
1715 (define (list-all-possible-keys-verbose key-name-alist)
1716 (map (lambda (short long)
1718 . ,(map (lambda (key-instructions)
1719 `(,(car key-instructions)
1722 (translate-key-instruction key-instructions))))
1723 (assoc-get long key-name-alist))))
1725 '(central-column left-hand right-hand)))
1727 (define woodwind-data-assembly-instructions
1728 `((,generate-flute-family-entry . piccolo)
1729 (,generate-flute-family-entry . flute)
1730 (,generate-flute-family-entry . flute-b-extension)
1731 (,generate-tin-whistle-family-entry . tin-whistle)
1732 (,generate-oboe-family-entry . oboe)
1733 (,generate-clarinet-family-entry . clarinet)
1734 (,generate-clarinet-family-entry . bass-clarinet)
1735 (,generate-clarinet-family-entry . low-bass-clarinet)
1736 (,generate-saxophone-family-entry . saxophone)
1737 (,generate-saxophone-family-entry . soprano-saxophone)
1738 (,generate-saxophone-family-entry . alto-saxophone)
1739 (,generate-saxophone-family-entry . tenor-saxophone)
1740 (,generate-saxophone-family-entry . baritone-saxophone)
1741 (,generate-bassoon-family-entry . bassoon)
1742 (,generate-bassoon-family-entry . contrabassoon)))
1744 (define-public woodwind-instrument-list
1745 (map cdr woodwind-data-assembly-instructions))
1747 (define woodwind-data-alist
1748 (map (lambda (instruction)
1749 ((car instruction) (cdr instruction)))
1750 woodwind-data-assembly-instructions))
1752 ;;; The brains of the markup function: takes drawing and offset information
1753 ;;; about a key region and calls the appropriate stencils to draw the region.
1760 extra-offset-instructions
1769 (ly:stencil-translate
1770 (if (pair? (cdr node))
1771 (if (assoc-get 'textual? node)
1772 ((assoc-get 'textual? node) (map (lambda (key)
1773 (assoc-get 'text? key))
1774 (map (lambda (instr)
1778 (assoc-get 'stencils node)))
1784 (assoc-get 'stencils
1792 extra-offset-instructions
1795 (coord-apply (assoc-get 'xy-scale-function stencil-alist)
1799 (if (= 0 (assoc-get node draw-instructions))
1801 ((assoc-get 'stencil (get-key node key-bank))
1804 (assoc-get node draw-instructions)
1812 (if (pair? (cdr node))
1814 (get-key node key-bank)))
1816 (assoc-get 'xy-scale-function stencil-alist)
1819 (assoc-get node extra-offset-instructions)
1820 (assoc-get node extra-offset-instructions)
1823 (assoc-get 'stencils stencil-alist))))
1825 (define-public (print-keys instrument)
1829 (format #t "\nPrinting keys for: ~a\n" instrument)
1830 (assoc-get instrument woodwind-data-alist)))
1831 (key-list (list-all-possible-keys (assoc-get 'keys chosen-instrument))))
1832 (define (key-list-loop key-list)
1833 (if (null? key-list)
1836 (format #t "~a\n ~a\n" (caar key-list) (cdar key-list))
1837 (key-list-loop (cdr key-list)))))
1838 (key-list-loop key-list)))
1840 (define-public (get-woodwind-key-list instrument)
1841 (list-all-possible-keys-verbose
1844 (assoc-get instrument woodwind-data-alist))))
1846 (define-public (print-keys-verbose instrument)
1850 (format #t "\nPrinting keys in verbose mode for: ~a\n" instrument)
1851 (assoc-get instrument woodwind-data-alist)))
1853 (list-all-possible-keys-verbose (assoc-get 'keys chosen-instrument))))
1854 (define (key-list-loop key-list)
1855 (if (null? key-list)
1858 (format #t "~a\n" (caar key-list))
1860 (format #t " possibilities for ~a:\n ~a\n" (car x) (cdr x)))
1862 (key-list-loop (cdr key-list)))))
1863 (key-list-loop key-list)))
1865 (define-markup-command
1866 (woodwind-diagram layout props instrument user-draw-commands)
1868 #:category instrument-specific-markup ; markup category
1869 #:properties ((size 1)
1872 "Make a woodwind-instrument diagram. For example, say
1875 \\markup \\woodwind-diagram #'oboe #'((lh . (d ees)) (cc . (five3qT1q)) (rh . (gis)))
1879 for an oboe with the left-hand d key, left-hand ees key,
1880 and right-hand gis key depressed while the five-hole of
1881 the central column effectuates a trill between 1/4 and 3/4 closed.
1883 The following instruments are supported:
1912 To see all of the callable keys for a given instrument,
1913 include the function @code{(print-keys 'instrument)}
1914 in your .ly file, where instrument is the instrument
1915 whose keys you want to print.
1917 Certain keys allow for special configurations. The entire gamut of
1918 configurations possible is as follows:
1935 F (fully covered; the default if no state put)
1939 Additionally, these configurations can be used in trills. So, for example,
1940 @code{three3qTR} effectuates a trill between 3/4 full and ring depressed
1941 on the three hole. As another example, @code{threeRT} effectuates a trill
1942 between R and open, whereas @code{threeTR} effectuates a trill between open
1943 and shut. To see all of the possibilities for all of the keys of a given
1944 instrument, invoke @code{(print-keys-verbose 'instrument)}.
1946 Lastly, substituting an empty list for the pressed-key alist will result in
1947 a diagram with all of the keys drawn but none filled. ie...
1950 \\markup \\woodwind-diagram #'oboe #'()
1952 (let* ((radius size)
1953 (thick (* size thickness))
1954 (display-graphic graphical)
1955 (xy-stretch `(1.0 . 2.5))
1956 (chosen-instrument (assoc-get instrument woodwind-data-alist))
1958 (if (not chosen-instrument)
1959 (ly:error "~a is not a valid woodwind instrument."
1964 (if display-graphic 'graphical-commands 'text-commands)
1967 (if (null? user-draw-commands)
1968 (uniform-draw-instructions (assoc-get 'keys chosen-instrument))
1969 (translate-draw-instructions
1970 (append '((hd . ())) user-draw-commands)
1971 (assoc-get 'keys chosen-instrument))))
1975 (assoc-get 'draw-instructions stencil-info)))
1979 (assoc-get 'extra-offset-instructions stencil-info))))
1981 (assoc-get 'stencil-alist stencil-info)
1982 (assoc-get 'keys chosen-instrument)