2 ;;; chord-name.scm -- Compile chord name
4 ;;; source file of the GNU LilyPond music typesetter
6 ;;; (c) 2000--2002 Jan Nieuwenhuizen <janneke@gnu.org>
19 ;(define (dbg x) (write-me "" x))
22 ;;(define (write-me x) (write x) (newline) x)
23 ;;(define (write-me-2 x y) (write "FOO") (write x) (write y) (newline) y)
29 * Use lilypond Pitch objects -- SCM pitch objects lead to
30 duplication. LilyPond pitch objects force meaningful names
31 (i.e. (ly:pitch-octave PITCH) )
33 * Pitches are musical objects. The pitches -> markup step should
34 happen earlier (during interpreting), brew-molecule () should only
35 dump reinterpret the markup as a molecule.
37 * chord:: prefix is a poor-man's namespace device.
38 We have a module system to prevent export to userland.
39 Nested functions can take care of many other clashes. --hwn.
41 * easier tweakability:
43 - split chord::names-alists up into logical bits,
44 such as chord::exceptions-delta, exceptions-oslash
45 - iso just the 'style parameter, use a list, eg:
46 \property ChordNames.ChordName \set
47 #'style = #'(jazz delta oslash german-tonic german-Bb)
49 * clean split/merge of bass/banter/american stuff.
50 GET RID OF code duplication.
58 ;; " hey Emacs: string has ended
61 ;; pitch = (octave notename alteration)
63 ;; note = (notename . alteration)
65 ;; markup = markup text -- see font.scm and input/test/markup.ly
68 (define-public chord::exception-alist-banter
71 (((0 . 0)) . ,empty-markup)
73 (((0 . 0) (2 . 0)) . ,empty-markup)
75 (((0 . 0) (2 . -1)) . ,(make-simple-markup "m"))
77 (((0 . 0) (1 . 0) (4 . 0))
78 . ,(make-normal-size-super-markup (make-simple-markup "2 ")))
80 (((0 . 0) (3 . 0) (4 . 0))
81 . ,(make-normal-size-super-markup (make-simple-markup "4 ")))
83 (((0 . 0) (2 . -1) (4 . -1)) . ,(make-simple-markup "dim"))
84 ; URG: Simply C:m5-/maj7 iso Cdim maj7
85 (((0 . 0) (2 . -1) (4 . -1) (6 . 0))
88 (make-simple-markup "m")
89 (make-normal-size-super-markup (make-simple-markup "5-/maj7 ")))))
90 ; URG: Simply C:m5-/7 iso Cdim7
91 (((0 . 0) (2 . -1) (4 . -1) (6 . -1))
94 (make-simple-markup "m")
95 (make-normal-size-super-markup (make-simple-markup "5-/7 ")))))
97 (((0 . 0) (2 . -1) (4 . -1) (6 . -2))
98 . ,(make-super-markup (make-simple-markup "o")))
100 (((0 . 0) (2 . -1) (4 . -1) (6 . -2) (1 . -1))
102 (list (make-simple-markup "dim")
103 (make-normal-size-super-markup (make-simple-markup "9 ")))))
104 (((0 . 0) (2 . -1) (4 . -1) (6 . -2) (1 . -1) (3 . -1))
106 (list (make-simple-markup "dim")
107 (make-normal-size-super-markup
108 (make-simple-markup "11 ")))))
112 ; pitch->note-name: drops octave
113 (define (pitch->note-name pitch)
114 (cons (cadr pitch) (caddr pitch)))
116 (define (accidental->markup acc)
117 "ACC is an int, return a markup making an accidental."
119 (make-line-markup (list empty-markup))
120 (make-smaller-markup (make-musicglyph-markup
121 (string-append "accidentals-"
122 (number->string acc))))))
125 (define (accidental->markupp acc pos)
129 (let ((acc-markup (make-musicglyph-markup
130 (string-append "accidentals-"
131 (number->string acc)))))
133 (if (equal? pos 'columns)
134 (make-line-markup (list (make-smaller-markup acc-markup)))
135 (if (equal? pos 'super)
136 (make-line-markup (list (make-super-markup acc-markup)))
137 ;; not 'super or 'columns must be 'sub...
138 (make-line-markup (list (make-sub-markup acc-markup))))))))
143 ;; FIXME: possibly to be used for american/jazz style
144 ;; However, only pos == columns is used, which seems to do
145 ;; exactly what accidental->markup does...
146 (define (amy-accidental->text acc) (accidental->textp acc 'columns))
150 ;;;(define (accidental->text-super acc) (accidental->textp acc 'simple-super))
151 ;;(define (accidental->text-super acc) (accidental->textp acc 'super))
152 ;;(define (accidental->text-sub acc) (accidental->textp acc 'sub))
156 ;; TODO: invent sensible way to make note name tweaking possible?
158 (define (old-pitch->markup pitch)
162 (vector-ref #("C" "D" "E" "F" "G" "A" "B") (cadr pitch)))
163 (make-normal-size-super-markup
164 (accidental->markup (caddr pitch))))))
166 ;;; Hooks to override chord names and note names,
167 ;;; see input/tricks/german-chords.ly
169 (define old-pitch->markup-banter old-pitch->markup)
171 ;; We need also steps, to allow for Cc name override,
172 ;; see input/test/Cc-chords.ly
173 (define (pitch->chord-name-markup-banter pitch steps)
174 (old-pitch->markup-banter pitch))
176 (define pitch->note-name-markup-banter old-pitch->markup-banter)
178 (define (step->markup pitch)
180 (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))
188 (define (step->markup-banter pitch)
190 (if (= (cadr pitch) 6)
197 (step->markup pitch))))
199 (define (step->markup-previously-alternate-jazz pitch)
202 (accidental->markup (caddr pitch))
204 (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))))))
206 (define (step->markup-previously-jazz pitch)
207 (if (= (cadr pitch) 6)
209 ;; sharp 7 only included for completeness?
210 ((-2) (make-line-markup
212 (accidental->markup -1)
213 (make-simple-markup "7"))))
214 ((-1) (make-simple-markup "7"))
215 ((0) (make-simple-markup "maj7"))
216 ;;((0) (make-line-markup
217 ;; (list (make-simple-markup "maj7"))))
218 ((1) (make-line-markup
220 (accidental->markup 1) (make-simple-markup "7"))))
221 ((2) (make-line-markup
222 (list (accidental->markup 1)
223 (make-simple-markup "7")))))
224 (step->markup-previously-alternate-jazz pitch)))
227 (define pitch::semitone-vec #(0 2 4 5 7 9 11))
229 (define (pitch::semitone pitch)
230 (+ (* (car pitch) 12)
231 (vector-ref pitch::semitone-vec (modulo (cadr pitch) 7))
234 (define (pitch::< l r)
235 (< (pitch::semitone l) (pitch::semitone r)))
237 (define (pitch::transpose pitch delta)
238 (let ((simple-octave (+ (car pitch) (car delta)))
239 (simple-notename (+ (cadr pitch) (cadr delta))))
240 (let ((octave (+ simple-octave (quotient simple-notename 7)))
241 (notename (modulo simple-notename 7)))
242 (let ((accidental (- (+ (pitch::semitone pitch) (pitch::semitone delta))
243 (pitch::semitone `(,octave ,notename 0)))))
244 `(,octave ,notename ,accidental)))))
246 (define (pitch::diff pitch tonic)
247 (let ((simple-octave (- (car pitch) (car tonic)))
248 (simple-notename (- (cadr pitch) (cadr tonic))))
249 (let ((octave (+ simple-octave (quotient simple-notename 7)
250 (if (< simple-notename 0) -1 0)))
251 (notename (modulo simple-notename 7)))
252 (let ((accidental (- (pitch::semitone pitch)
253 (pitch::semitone tonic)
254 (pitch::semitone `(,octave ,notename 0)))))
255 `(,octave ,notename ,accidental)))))
257 (define (pitch::note-pitch pitch)
258 (+ (* (car pitch) 7) (cadr pitch)))
262 (define chord::minor-major-vec #(0 -1 -1 0 -1 -1 0))
265 ;; compute the relative-to-tonic pitch that goes with 'step'
266 (define (chord::step-pitch tonic step)
267 ;; urg, we only do this for thirds
268 (if (= (modulo step 2) 0)
270 (let loop ((i 1) (pitch tonic))
274 pitch `(0 2 ,(vector-ref chord::minor-major-vec
275 ;; -1 (step=1 -> vector=0) + 7 = 6
276 (modulo (+ i 6) 7)))))))))
278 (define (chord::additions steps)
280 * any even step (2, 4, 6)
281 * any uneven step that is chromatically altered,
282 (where 7-- == -1, 7- == 0, 7 == +1)
285 ?and jazz needs also:
287 * TODO: any uneven step that's lower than an uneven step which is
288 chromatically altered
290 (let ((evens (filter-list (lambda (x) (!= 0 (modulo (cadr x) 2))) steps))
292 (filter-list (lambda (x)
293 (let ((n (cadr x)) (a (caddr x)))
294 (or (and (= 6 n) (!= -1 a))
299 (highest (let ((h (car (last-pair steps))))
300 (if (and (not (null? h))
305 ;; Hmm, what if we have a step twice, can we ignore that?
306 (uniq-list (sort (apply append evens altered-unevens highest)
310 ;; FIXME: unLOOP, see ::additions
311 ;; find the pitches that are missing from `normal' chord
312 (define (chord::subtractions chord-pitches)
313 (let ((tonic (car chord-pitches)))
314 (let loop ((step 1) (pitches chord-pitches) (subtractions '()))
316 (let* ((pitch (car pitches))
317 (p-step (+ (- (pitch::note-pitch pitch)
318 (pitch::note-pitch tonic))
320 ;; pitch is an subtraction if
321 ;; a step is missing or
323 (loop (+ step 2) pitches
324 (cons (chord::step-pitch tonic step) subtractions))
325 ;; there are no pitches left, but base thirds are not yet done and
327 (= (length pitches) 1))
328 ;; present pitch is not missing step
330 (loop (+ step 2) pitches subtractions)
331 (loop (+ step 2) pitches
332 (cons (chord::step-pitch tonic step) subtractions)))
334 (loop (+ step 2) (cdr pitches) subtractions)
335 (loop step (cdr pitches) subtractions)))))
336 (reverse subtractions)))))
338 (define (chord::additions->markup-banter additions subtractions)
339 (if (pair? additions)
342 (let ((step (step->markup-banter (car additions))))
343 (if (or (pair? (cdr additions))
344 (pair? subtractions))
346 (list step (make-simple-markup "/")))
348 (chord::additions->markup-banter (cdr additions) subtractions)))
351 (define (chord::subtractions->markup-banter subtractions)
352 (if (pair? subtractions)
355 (make-simple-markup "no")
356 (let ((step (step->markup-previously-jazz
357 (car subtractions))))
358 (if (pair? (cdr subtractions))
360 (list step (make-simple-markup "/")))
362 (chord::subtractions->markup-banter (cdr subtractions))))
365 (define (chord::bass-and-inversion->markup-banter bass-and-inversion)
366 (if (and (pair? bass-and-inversion)
367 (or (car bass-and-inversion)
368 (cdr bass-and-inversion)))
371 (make-simple-markup "/")
372 (pitch->note-name-markup-banter
373 (if (car bass-and-inversion)
374 (car bass-and-inversion)
375 (cdr bass-and-inversion)))))
378 ;; FIXME: merge this function with inner-name-jazz, -american
379 ;; iso using chord::bass-and-inversion->markup-banter,
380 ;; See: chord::exceptions-lookup
381 (define (chord::inner-name-banter tonic exception-part additions subtractions
382 bass-and-inversion steps)
386 Combine tonic, exception-part of chord name,
387 additions, subtractions and bass or inversion into chord name
390 (let* ((tonic-markup (pitch->chord-name-markup-banter tonic steps))
391 (except-markup (if exception-part exception-part empty-markup))
392 ;; UGR. How do we know if we should add a separator or not?
393 ;; maybe just add extra column to exception list?
394 (sep-markup (if (and exception-part
395 (let ((s (format "~s" except-markup)))
397 (string-match "super" s)
399 ;; python: `except_markup`[-5:] != '"o"))'
403 (- (string-length s) 5))))))
404 (or (pair? additions)
405 (pair? subtractions)))
406 (make-super-markup (make-simple-markup "/"))
408 (adds-markup (chord::additions->markup-banter additions subtractions))
409 (subs-markup (chord::subtractions->markup-banter subtractions))
410 (b+i-markup (chord::bass-and-inversion->markup-banter
411 bass-and-inversion)))
418 (make-normal-size-super-markup
419 (make-line-markup (list adds-markup subs-markup)))
422 (define (c++-pitch->scm p)
424 (list (ly:pitch-octave p) (ly:pitch-notename p) (ly:pitch-alteration p))
427 (define (chord::name-banter tonic exception-part unmatched-steps
428 bass-and-inversion steps)
429 (let ((additions (chord::additions unmatched-steps))
430 (subtractions (chord::subtractions unmatched-steps)))
432 (chord::inner-name-banter tonic exception-part additions subtractions
433 bass-and-inversion steps)))
437 (define (chord::exceptions-lookup exceptions steps)
439 return (MATCHED-EXCEPTION . BASE-CHORD-WITH-UNMATCHED-STEPS)
440 BASE-CHORD-WITH-UNMATCHED-STEPS always includes (tonic 3 5)
443 ;; this is unintelligible.
445 (define (chord::exceptions-lookup-helper
446 exception-alist try-steps unmatched-steps exception-part)
449 check exception-alist for biggest matching part of try-steps
450 return (MATCHED-EXCEPTION . UNMATCHED-STEPS)
453 (if (pair? try-steps)
454 ;; FIXME: junk '(0 . 0) from exceptions lists?
455 ;; if so: how to handle first '((0 . 0) . #f) entry?
457 ;; FIXME: either format exceptions list as real pitches, ie,
458 ;; including octave '((0 2 -1) ..), or drop octave
459 ;; from rest of calculations,
461 (map (lambda (x) (pitch->note-name x))
462 (append '((0 0 0)) try-steps))
465 (chord::exceptions-lookup-helper
466 #f '() unmatched-steps (cdr entry))
467 (let ((r (reverse try-steps)))
468 (chord::exceptions-lookup-helper
471 (cons (car r) unmatched-steps) #f))))
472 (cons exception-part unmatched-steps)))
474 (let* ((result (chord::exceptions-lookup-helper
477 (exception-part (car result))
478 (unmatched-steps (cdr result))
479 (matched-steps (if (= (length unmatched-steps) 0)
481 (+ 1 (- (length steps)
482 (length unmatched-steps)))))
483 (unmatched-with-1-3-5
484 (append (do ((i matched-steps (- i 1))
485 (base '() (cons `(0 ,(* (- i 1) 2) 0) base)))
489 (list exception-part unmatched-with-1-3-5)))
496 ;; See input/test/american-chords.ly
498 ;; Original Version by James Hammons, <jlhamm@pacificnet.net>
499 ;; Complete rewrite by Amelie Zapf, <amy@loueymoss.com>
501 ;; DONT use non-ascii characters, even if ``it works'' in Windows
504 (define mathm-markup-object
505 (make-override-markup '(font-family . math) (make-simple-markup "M")))
508 (define mathn-markup-object
509 (make-override-markup '(font-family . math) (make-simple-markup "N")))
511 (define (step->markup-accidental pitch)
515 ((-2) (accidental->markup -2))
516 ((-1) (accidental->markup -1))
518 ((1) (accidental->markup 1))
519 ((2) (accidental->markup 2)))
520 (make-simple-markup (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))))))
522 (define-public chord::exception-alist-american
524 (((0 . 0)) . ,empty-markup)
525 (((0 . 0) (2 . -1)) . ,(make-simple-markup "m"))
527 ;; these should probably be normal-size? --jcn
528 ;;(((0 . 0) (4 . 0)) . ,(make-super-markup (make-simple-markup "5 ")))
529 ;;(((0 . 0) (1 . 0) (4 . 0)) . ,(make-super-markup (make-simple-markup "2 ")))
531 (((0 . 0) (4 . 0)) . ,(make-normal-size-super-markup (make-simple-markup "5 ")))
532 (((0 . 0) (1 . 0) (4 . 0)) . ,(make-normal-size-super-markup (make-simple-markup "2 ")))
534 ;;choose your symbol for the fully diminished chord
535 (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ,(make-simple-markup "dim"))
536 ;;(((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ,(make-line-markup (list empty-markup (make-super-markup (make-simple-markup "o")))))
539 (define (step->markup-american pitch)
541 ((6) (case (caddr pitch)
542 ((-2) (make-line-markup (list (accidental->markup -1) (make-simple-markup "7"))))
543 ((-1) (make-simple-markup "7"))
544 ((0) (make-simple-markup "maj7"))
545 ((1) (make-line-markup (list (accidental->markup 1) (make-simple-markup "7"))))
546 ((2) (make-line-markup (list (accidental->markup 2) (make-simple-markup "7"))))))
547 ((4) (case (caddr pitch)
548 ((-2) (make-line-markup (list (accidental->markup -2) (make-simple-markup "5"))))
549 ;;choose your symbol for the diminished fifth
550 ((-1) (make-simple-markup "-5"))
551 ;;((-1) (make-line-markup (list (accidental->markup -1) (make-simple-markup "5")))))
553 ;;choose your symbol for the augmented fifth
554 ;;((1) (make-simple-markup "aug"))
555 ;;((1) (make-line-markup (list (accidental->markup 1) (make-simple-markup "5")))))
556 ((1) (make-simple-markup "+5"))
557 ((2) (make-line-markup (list (accidental->markup 2) (make-simple-markup "5"))))))
558 (else (if (and (= (car pitch) 0)
561 (make-simple-markup "sus4")
562 (step->markup-accidental pitch)))))
564 (define (chord::additions->markup-american additions subtractions)
565 (if (pair? additions)
566 ;; I don't like all this reasoning here, when we're actually typesetting.
567 (if(and(pair? (cdr additions)) ;a further addition left over
568 (or(and(= 0 (caddr(car additions))) ;this addition natural
569 (not(= 6 (cadr(car additions)))))
570 (and(= -1 (caddr(car additions)))
571 (= 6 (cadr(car additions)))))
572 (or(and(= 0 (caddr(cadr additions))) ;the following addition natural
573 (not(= 6 (cadr(cadr additions)))))
574 (and(= -1 (caddr(cadr additions)))
575 (= 6 (cadr(cadr additions)))))
576 (or(and(= (car(car additions)) (car(cadr additions))) ;both a third apart
577 (= 2 (- (cadr(cadr additions)) (cadr(car additions)))))
578 (and(= 1 (- (car(cadr additions)) (car(car additions))))
579 (= 5 (- (cadr(car additions)) (cadr(cadr additions))))))
580 (or(null? subtractions) ;this or clause protects the "adds"
581 (and (pair? subtractions)
582 (or (< (car(cadr additions)) (car(car subtractions)))
583 (and(= (car(cadr additions)) (car(car subtractions)))
584 (< (cadr(cadr additions)) (cadr(car subtractions))))))))
585 (chord::additions->markup-american (cdr additions) subtractions)
588 (let ((step (step->markup-american (car additions))))
589 (if (or (pair? (cdr additions))
590 (pair? subtractions))
591 (if (and (pair? (cdr additions))
592 (or(< 3 (- (cadr(cadr additions)) (cadr(car additions))))
593 (and(< 0 (- (car(cadr additions)) (car(car additions))))
594 (> 4 (- (cadr(car additions)) (cadr(cadr additions)))))))
595 (make-line-markup (list step (make-simple-markup " add")))
596 ;; tweak your favorite separator here
597 ;; (make-line-markup (list step (make-simple-markup "/")))
598 (make-line-markup (list step (make-simple-markup " "))))
600 (chord::additions->markup-american (cdr additions) subtractions))))
603 (define (chord::inner-name-american tonic exception-part additions subtractions
604 bass-and-inversion steps)
605 (let* ((tonic-markup (pitch->chord-name-markup-banter tonic steps))
606 (except-markup (if exception-part exception-part empty-markup))
607 ;; UGR. How do we know if we should add a separator or not?
608 ;; maybe just add extra column to exception list?
609 (sep-markup (if (and exception-part
610 (let ((s (format "~s" except-markup)))
612 (string-match "super" s)
614 ;; python: `except_markup`[-7:] != '"o"))'
618 (- (string-length s) 7))))))
619 (or (pair? additions)
620 (pair? subtractions)))
621 (make-super-markup (make-simple-markup "/"))
623 ;;this list contains all the additions that go "in line"
627 (let ((o (car x)) (n (cadr x)) (a (caddr x)))
628 (and (not (and (= 0 o) (= 2 n))) ;gets rid of unwanted thirds
629 ;;change this if you want it differently
630 (not (and (= 0 o) (= 3 n) (= 0 a))) ;sus4
631 (not (and (= 0 o) (= 4 n) (!= 0 a)))))) ;alt5
633 ;;this list contains all the additions that are patched onto the end
634 ;;of the chord symbol, usually sus4 and altered 5ths.
636 ;;take out the reverse if it bothers you in a pathological chord
640 (let ((o (car x)) (n (cadr x)) (a (caddr x)))
641 (and(not (and (= 0 o) (= 2 n))) ;gets rid of unwanted thirds
642 ;;change this correspondingly
643 (or(and (= 0 o) (= 3 n) (= 0 a)) ;sus4
644 (and (= 0 o) (= 4 n) (!= 0 a)))))) ;alt5
646 (relevant-subs (filter-list
647 (lambda (x) ;catches subtractions higher than 5th
648 (let((o (car x)) (n (cadr x)))
652 (pref-markup (chord::additions->markup-american prefixes relevant-subs))
653 (suff-markup (chord::additions->markup-american suffixes relevant-subs))
654 (b+i-markup (chord::bass-and-inversion->markup-banter bass-and-inversion)))
657 tonic-markup except-markup sep-markup
658 (make-normal-size-super-markup
659 (make-line-markup (list pref-markup suff-markup)))
662 (define (chord::additions-american steps)
663 (let ((evens (filter-list (lambda (x) (!= 0 (modulo (cadr x) 2))) steps))
664 ;we let all the unevens pass for now, we'll fix that later.
666 (filter-list (lambda (x)
667 (let ((n (cadr x)) (a (caddr x)))
668 (or (and (= 6 n) (!= -1 a))
670 (= 0 (modulo n 2))))))
672 (highest (let ((h (car (last-pair steps))))
673 (if (and (not (null? h))
678 (uniq-list (sort (apply append evens unevens highest)
681 ;; American style chordnames use no "no",
682 ;; but otherwise very similar to banter for now
683 (define-public (chord::name-american tonic exception-part unmatched-steps
684 bass-and-inversion steps)
685 (let ((additions (chord::additions-american unmatched-steps))
686 (subtractions (chord::subtractions unmatched-steps)))
687 (chord::inner-name-american tonic exception-part additions subtractions
688 bass-and-inversion steps)))
692 ;; Jazz chords, by Atte Andr'e Jensen <atte@post.com>
693 ;; Complete rewrite by Amelie Zapf (amy@loueymoss.com)
695 ;; FIXME: identical to chord::exception-alist-american, apart from commented
696 ;; dim chord. should merge.
697 (define-public chord::exception-alist-jazz
699 (((0 . 0)) . ,empty-markup)
700 (((0 . 0) (2 . -1)) . ,(make-simple-markup "m"))
702 ;; these should probably be normal-size? --jcn
703 ;;(((0 . 0) (4 . 0)) . ,(make-super-markup (make-simple-markup "5 ")))
704 ;;(((0 . 0) (1 . 0) (4 . 0)) . ,(make-super-markup (make-simple-markup "2 ")))
706 (((0 . 0) (4 . 0)) . ,(make-normal-size-super-markup (make-simple-markup "5 ")))
707 (((0 . 0) (1 . 0) (4 . 0)) . ,(make-normal-size-super-markup (make-simple-markup "2 ")))
709 ;;choose your symbol for the fully diminished chord
710 ;;(((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ,(make-simple-markup "dim"))
711 (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ,(make-line-markup (list (make-simple-markup "") (make-super-markup (make-simple-markup "o")))))
714 ;; FIXME: rather similar to step->markup-american. should merge.
715 (define (step->markup-jazz pitch)
717 ((6) (case (caddr pitch)
718 ((-2) (make-line-markup (list (accidental->markup -1) (make-simple-markup "7"))))
719 ((-1) (make-simple-markup "7"))
720 ;;Pick your favorite maj7
721 ((0) mathm-markup-object) ;;a white triangle
722 ;;((0) mathn-markup-object) ;;a black triangle
723 ;;((0) (make-simple-markup "maj7")) ;;good old maj7
724 ((1) (make-line-markup (list (accidental->markup 1) (make-simple-markup "7"))))
725 ((2) (make-line-markup (list (accidental->markup 2) (make-simple-markup "7"))))))
726 ((4) (case (caddr pitch)
727 ((-2) (make-line-markup (list (accidental->markup -2) (make-simple-markup "5"))))
728 ;;choose your symbol for the diminished fifth
729 ;;((-1) (make-simple-markup "-5"))
730 ((-1) (make-line-markup (list (accidental->markup -1) (make-simple-markup "5"))))
732 ;;choose your symbol for the augmented fifth
733 ;;((1) (make-simple-markup "aug"))
734 ((1) (make-line-markup (list (accidental->markup 1) (make-simple-markup "5"))))
735 ;;((1) (make-simple-markup "+5"))
736 ((2) (make-line-markup (list (accidental->markup 2) (make-simple-markup "5"))))))
737 (else (if (and (= (car pitch) 0)
740 (make-simple-markup "sus4")
741 (step->markup-accidental pitch)))))
743 ;; FIXME: identical to chord::additions->markup-american,
744 ;; except for -jazz / -american suffixes on calls
745 (define (chord::additions->markup-jazz additions subtractions)
746 (if (pair? additions)
747 ;; I don't like all this reasoning here, when we're actually typesetting.
748 (if(and(pair? (cdr additions)) ;a further addition left over
749 (or(and(= 0 (caddr(car additions))) ;this addition natural
750 (not(= 6 (cadr(car additions)))))
751 (and(= -1 (caddr(car additions)))
752 (= 6 (cadr(car additions)))))
753 (or(and(= 0 (caddr(cadr additions))) ;the following addition natural
754 (not(= 6 (cadr(cadr additions)))))
755 (and(= -1 (caddr(cadr additions)))
756 (= 6 (cadr(cadr additions)))))
757 (or(and(= (car(car additions)) (car(cadr additions))) ;both a third apart
758 (= 2 (- (cadr(cadr additions)) (cadr(car additions)))))
759 (and(= 1 (- (car(cadr additions)) (car(car additions))))
760 (= 5 (- (cadr(car additions)) (cadr(cadr additions))))))
761 (or(null? subtractions) ;this or clause protects the "adds"
762 (and (pair? subtractions)
763 (or (< (car(cadr additions)) (car(car subtractions)))
764 (and(= (car(cadr additions)) (car(car subtractions)))
765 (< (cadr(cadr additions)) (cadr(car subtractions))))))))
766 (chord::additions->markup-jazz (cdr additions) subtractions)
769 (let ((step (step->markup-jazz (car additions))))
770 (if (or (pair? (cdr additions))
771 (pair? subtractions))
772 (if (and (pair? (cdr additions))
773 (or(< 3 (- (cadr(cadr additions)) (cadr(car additions))))
774 (and(< 0 (- (car(cadr additions)) (car(car additions))))
775 (> 4 (- (cadr(car additions)) (cadr(cadr additions)))))))
776 (make-line-markup (list step (make-simple-markup " add")))
777 ;; tweak your favorite separator here
778 ;; (make-line-markup (list step (make-simple-markup "/")))
779 (make-line-markup (list step (make-simple-markup " "))))
781 (chord::additions->markup-jazz (cdr additions) subtractions))))
784 ;; FIXME: identical to chord::additions->markup-american.
785 ;; except for -jazz / -american suffixes on calls
786 (define (chord::inner-name-jazz tonic exception-part additions subtractions
787 bass-and-inversion steps)
788 (let* ((tonic-markup (pitch->chord-name-markup-banter tonic steps))
789 (except-markup (if exception-part exception-part empty-markup))
790 ;; UGR. How do we know if we should add a separator or not?
791 ;; maybe just add extra column to exception list?
792 (sep-markup (if (and exception-part
793 (let ((s (format "~s" except-markup)))
795 (string-match "super" s)
797 ;; python: `except_markup`[-7:] != '"o"))'
801 (- (string-length s) 7))))))
802 (or (pair? additions)
803 (pair? subtractions)))
804 (make-super-markup (make-simple-markup "/"))
806 ;;this list contains all the additions that go "in line"
810 (let ((o (car x)) (n (cadr x)) (a (caddr x)))
811 (and (not (and (= 0 o) (= 2 n))) ;gets rid of unwanted thirds
812 ;;change this if you want it differently
813 (not (and (= 0 o) (= 3 n) (= 0 a))) ;sus4
814 (not (and (= 0 o) (= 4 n) (!= 0 a)))))) ;alt5
816 ;;this list contains all the additions that are patched onto the end
817 ;;of the chord symbol, usually sus4 and altered 5ths.
819 ;;take out the reverse if it bothers you in a pathological chord
823 (let ((o (car x)) (n (cadr x)) (a (caddr x)))
824 (and(not (and (= 0 o) (= 2 n))) ;gets rid of unwanted thirds
825 ;;change this correspondingly
826 (or(and (= 0 o) (= 3 n) (= 0 a)) ;sus4
827 (and (= 0 o) (= 4 n) (!= 0 a)))))) ;alt5
829 (relevant-subs (filter-list
830 (lambda (x) ;catches subtractions higher than 5th
831 (let((o (car x)) (n (cadr x)))
835 (pref-markup (chord::additions->markup-jazz prefixes relevant-subs))
836 (suff-markup (chord::additions->markup-jazz suffixes relevant-subs))
837 (b+i-markup (chord::bass-and-inversion->markup-banter bass-and-inversion)))
840 tonic-markup except-markup sep-markup
841 (make-normal-size-super-markup
842 (make-line-markup (list pref-markup suff-markup)))
845 (define (chord::name-jazz tonic exception-part unmatched-steps
846 bass-and-inversion steps)
847 (let ((additions (chord::additions-american unmatched-steps))
848 (subtractions (chord::subtractions unmatched-steps)))
849 (chord::inner-name-jazz tonic exception-part additions subtractions
850 bass-and-inversion steps)))
853 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
856 (define-public (new-chord->markup func ly-pitches bass inversion context)
857 "Entry point for New_chord_name_engraver. See chord-name.scm for the
858 signature of FUNC. LY-PITCHES, BASS and INVERSION are lily
859 pitches. EXCEPTIONS is an alist (see scm file).
862 (let* ((pitches (map c++-pitch->scm ly-pitches))
863 (exceptions (ly:get-context-property context 'chordNameExceptions))
865 (cons (c++-pitch->scm bass)
866 (c++-pitch->scm inversion)))
867 (diff (pitch::diff '(0 0 0) (car pitches)))
868 (steps (if (cdr pitches) (map (lambda (x)
869 (pitch::transpose x diff))
872 (lookup (dbg (chord::exceptions-lookup exceptions steps)))
873 (exception-part (dbg (car lookup)))
874 (unmatched-steps (cadr lookup))
875 (tonic (car pitches))
878 (func tonic exception-part unmatched-steps bass-and-inversion steps)
881 (define-public (chord->markup-jazz . args)
882 (apply new-chord->markup (cons chord::name-jazz args))
885 (define-public (chord->markup-american . args)
886 (apply new-chord->markup (cons chord::name-american args))
889 (define-public (chord->markup-banter . args)
890 (apply new-chord->markup (cons chord::name-banter args))
893 (define-public (new-chord-name-brew-molecule grob)
896 (ws (ly:get-grob-property grob 'word-space))
897 (markup (ly:get-grob-property grob 'text))
898 (molecule (interpret-markup grob
899 (cons '((word-space . 0.0))
900 (Font_interface::get_property_alist_chain grob))
905 ;; chord names aren't in staffs, so WS is in global staff space.
907 (ly:combine-molecule-at-edge
909 X RIGHT (ly:make-molecule "" (cons 0 ws) '(-1 . 1) )
914 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
916 (define-public (set-chord-name-style sym)
917 "Return music expressions that set the chord naming style. For
918 inline use in .ly file"
920 (define (chord-name-style-setter function exceptions)
922 (make-sequential-music
923 (list (make-property-set 'chordNameFunction function)
924 (make-property-set 'chordNameExceptions exceptions)))
932 (chord-name-style-setter chord->markup-jazz
933 chord::exception-alist-jazz))
935 (chord-name-style-setter chord->markup-banter
936 chord::exception-alist-banter))
938 (chord-name-style-setter chord->markup-american
939 chord::exception-alist-american))
942 (chord-name-style-setter ignatzek-chord-names
944 ((double-plus-new-banter)
945 (chord-name-style-setter double-plus-new-chord->markup-banter
946 chord::exception-alist-banter))
948 ((double-plus-new-jazz)
949 (chord-name-style-setter double-plus-new-chord->markup-jazz
950 chord::exception-alist-jazz))
953 ;; can't put this in double-plus-new-chord-name.scm, because we can't
954 ;; ly:load that very easily.
955 (define-public (set-double-plus-new-chord-name-style style options)
956 "Return music expressions that set the chord naming style. For
957 inline use in .ly file"
959 (define (chord-name-style-setter function)
961 (make-sequential-music
962 (list (make-property-set 'chordNameFunction function)
964 ;; urg , misuse of chordNameExceptions function.
965 (make-property-set 'chordNameExceptions options)))
971 (chord-name-style-setter double-plus-new-chord->markup-banter))
974 (chord-name-style-setter double-plus-new-chord->markup-jazz)))))