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>
18 (define-public (write-me x)
19 "Write and return X. For debugging purposes. "
20 (write x) (newline) x)
22 ;(define (dbg x) (write-me x))
25 ;;(define (write-me x) (write x) (newline) x)
26 ;;(define (write-me-2 x y) (write "FOO") (write x) (write y) (newline) y)
32 * Use lilypond Pitch objects -- SCM pitch objects lead to
33 duplication. LilyPond pitch objects force meaningful names
34 (i.e. (ly:pitch-octave PITCH) )
36 * Pitches are musical objects. The pitches -> markup step should
37 happen earlier (during interpreting), brew-molecule () should only
38 dump reinterpret the markup as a molecule.
40 [* naming chord::... ; this is scheme not C++]
41 (yes - constructive naming suggestion here)
43 * easier tweakability:
44 - split chord::names-alists up into logical bits,
45 such as chord::exceptions-delta, exceptions-oslash
46 - iso just the 'style parameter, use a list, eg:
47 \property ChordNames.ChordName \set
48 #'style = #'(jazz delta oslash german-tonic german-Bb)
50 * clean split/merge of bass/banter/american stuff.
51 GET RID OF code duplication.
59 ;; " hey Emacs: string has ended
62 ;; pitch = (octave notename alteration)
64 ;; note = (notename . alteration)
66 ;; markup = markup text -- see font.scm and input/test/markup.ly
69 (define-public chord::exception-alist-banter
72 (((0 . 0)) . ,empty-markup)
74 (((0 . 0) (2 . 0)) . ,empty-markup)
76 (((0 . 0) (2 . -1)) . ,(make-simple-markup "m"))
78 (((0 . 0) (1 . 0) (4 . 0))
79 . ,(make-normal-size-super-markup (make-simple-markup "2 ")))
81 (((0 . 0) (3 . 0) (4 . 0))
82 . ,(make-normal-size-super-markup (make-simple-markup "4 ")))
84 (((0 . 0) (2 . -1) (4 . -1)) . ,(make-simple-markup "dim"))
85 ; URG: Simply C:m5-/maj7 iso Cdim maj7
86 (((0 . 0) (2 . -1) (4 . -1) (6 . 0))
89 (make-simple-markup "m")
90 (make-normal-size-super-markup (make-simple-markup "5-/maj7 ")))))
91 ; URG: Simply C:m5-/7 iso Cdim7
92 (((0 . 0) (2 . -1) (4 . -1) (6 . -1))
95 (make-simple-markup "m")
96 (make-normal-size-super-markup (make-simple-markup "5-/7 ")))))
98 (((0 . 0) (2 . -1) (4 . -1) (6 . -2))
99 . ,(make-super-markup (make-simple-markup "o")))
101 (((0 . 0) (2 . -1) (4 . -1) (6 . -2) (1 . -1))
103 (list (make-simple-markup "dim")
104 (make-normal-size-super-markup (make-simple-markup "9 ")))))
105 (((0 . 0) (2 . -1) (4 . -1) (6 . -2) (1 . -1) (3 . -1))
107 (list (make-simple-markup "dim")
108 (make-normal-size-super-markup
109 (make-simple-markup "11 ")))))
113 ; pitch->note-name: drops octave
114 (define (pitch->note-name pitch)
115 (cons (cadr pitch) (caddr pitch)))
117 (define (accidental->markup acc)
118 "ACC is an int, return a markup making an accidental."
120 (make-line-markup (list empty-markup))
121 (make-smaller-markup (make-musicglyph-markup
122 (string-append "accidentals-"
123 (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))))))))
141 ;; FIXME: possibly to be used for american/jazz style
142 ;; However, only pos == columns is used, which seems to do
143 ;; exactly what accidental->markup does...
144 (define (amy-accidental->text acc) (accidental->textp acc 'columns))
147 ;;;(define (accidental->text-super acc) (accidental->textp acc 'simple-super))
148 ;;(define (accidental->text-super acc) (accidental->textp acc 'super))
149 ;;(define (accidental->text-sub acc) (accidental->textp acc 'sub))
153 ;; TODO: invent sensible way to make note name tweaking possible?
155 (define (pitch->markup pitch)
159 (vector-ref #("C" "D" "E" "F" "G" "A" "B") (cadr pitch)))
160 (make-normal-size-super-markup
161 (accidental->markup (caddr pitch))))))
163 ;;; Hooks to override chord names and note names,
164 ;;; see input/tricks/german-chords.ly
166 (define pitch->markup-banter pitch->markup)
168 ;; We need also steps, to allow for Cc name override,
169 ;; see input/test/Cc-chords.ly
170 (define (pitch->chord-name-markup-banter pitch steps)
171 (pitch->markup-banter pitch))
173 (define pitch->note-name-markup-banter pitch->markup-banter)
175 (define (step->markup pitch)
177 (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))
185 (define (step->markup-banter pitch)
187 (if (= (cadr pitch) 6)
194 (step->markup pitch))))
196 (define (step->markup-previously-alternate-jazz pitch)
199 (accidental->markup (caddr pitch))
201 (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))))))
203 (define (step->markup-previously-jazz pitch)
204 (if (= (cadr pitch) 6)
206 ;; sharp 7 only included for completeness?
207 ((-2) (make-line-markup
209 (accidental->markup -1)
210 (make-simple-markup "7"))))
211 ((-1) (make-simple-markup "7"))
212 ((0) (make-simple-markup "maj7"))
213 ;;((0) (make-line-markup
214 ;; (list (make-simple-markup "maj7"))))
215 ((1) (make-line-markup
217 (accidental->markup 1) (make-simple-markup "7"))))
218 ((2) (make-line-markup
219 (list (accidental->markup 1)
220 (make-simple-markup "7")))))
221 (step->markup-previously-alternate-jazz pitch)))
224 (define pitch::semitone-vec #(0 2 4 5 7 9 11))
226 (define (pitch::semitone pitch)
227 (+ (* (car pitch) 12)
228 (vector-ref pitch::semitone-vec (modulo (cadr pitch) 7))
231 (define (pitch::< l r)
232 (< (pitch::semitone l) (pitch::semitone r)))
234 (define (pitch::transpose pitch delta)
235 (let ((simple-octave (+ (car pitch) (car delta)))
236 (simple-notename (+ (cadr pitch) (cadr delta))))
237 (let ((octave (+ simple-octave (quotient simple-notename 7)))
238 (notename (modulo simple-notename 7)))
239 (let ((accidental (- (+ (pitch::semitone pitch) (pitch::semitone delta))
240 (pitch::semitone `(,octave ,notename 0)))))
241 `(,octave ,notename ,accidental)))))
243 (define (pitch::diff pitch tonic)
244 (let ((simple-octave (- (car pitch) (car tonic)))
245 (simple-notename (- (cadr pitch) (cadr tonic))))
246 (let ((octave (+ simple-octave (quotient simple-notename 7)
247 (if (< simple-notename 0) -1 0)))
248 (notename (modulo simple-notename 7)))
249 (let ((accidental (- (pitch::semitone pitch)
250 (pitch::semitone tonic)
251 (pitch::semitone `(,octave ,notename 0)))))
252 `(,octave ,notename ,accidental)))))
254 (define (pitch::note-pitch pitch)
255 (+ (* (car pitch) 7) (cadr pitch)))
259 (define chord::minor-major-vec #(0 -1 -1 0 -1 -1 0))
262 ;; compute the relative-to-tonic pitch that goes with 'step'
263 (define (chord::step-pitch tonic step)
264 ;; urg, we only do this for thirds
265 (if (= (modulo step 2) 0)
267 (let loop ((i 1) (pitch tonic))
271 pitch `(0 2 ,(vector-ref chord::minor-major-vec
272 ;; -1 (step=1 -> vector=0) + 7 = 6
273 (modulo (+ i 6) 7)))))))))
275 (define (chord::additions steps)
277 * any even step (2, 4, 6)
278 * any uneven step that is chromatically altered,
279 (where 7-- == -1, 7- == 0, 7 == +1)
282 ?and jazz needs also:
284 * TODO: any uneven step that's lower than an uneven step which is
285 chromatically altered
287 (let ((evens (filter-list (lambda (x) (!= 0 (modulo (cadr x) 2))) steps))
289 (filter-list (lambda (x)
290 (let ((n (cadr x)) (a (caddr x)))
291 (or (and (= 6 n) (!= -1 a))
296 (highest (let ((h (car (last-pair steps))))
297 (if (and (not (null? h))
302 ;; Hmm, what if we have a step twice, can we ignore that?
303 (uniq-list (sort (apply append evens altered-unevens highest)
307 ;; FIXME: unLOOP, see ::additions
308 ;; find the pitches that are missing from `normal' chord
309 (define (chord::subtractions chord-pitches)
310 (let ((tonic (car chord-pitches)))
311 (let loop ((step 1) (pitches chord-pitches) (subtractions '()))
313 (let* ((pitch (car pitches))
314 (p-step (+ (- (pitch::note-pitch pitch)
315 (pitch::note-pitch tonic))
317 ;; pitch is an subtraction if
318 ;; a step is missing or
320 (loop (+ step 2) pitches
321 (cons (chord::step-pitch tonic step) subtractions))
322 ;; there are no pitches left, but base thirds are not yet done and
324 (= (length pitches) 1))
325 ;; present pitch is not missing step
327 (loop (+ step 2) pitches subtractions)
328 (loop (+ step 2) pitches
329 (cons (chord::step-pitch tonic step) subtractions)))
331 (loop (+ step 2) (cdr pitches) subtractions)
332 (loop step (cdr pitches) subtractions)))))
333 (reverse subtractions)))))
335 (define (chord::additions->markup-banter additions subtractions)
336 (if (pair? additions)
339 (let ((step (step->markup-banter (car additions))))
340 (if (or (pair? (cdr additions))
341 (pair? subtractions))
343 (list step (make-simple-markup "/")))
345 (chord::additions->markup-banter (cdr additions) subtractions)))
348 (define (chord::subtractions->markup-banter subtractions)
349 (if (pair? subtractions)
352 (make-simple-markup "no")
353 (let ((step (step->markup-previously-jazz
354 (car subtractions))))
355 (if (pair? (cdr subtractions))
357 (list step (make-simple-markup "/")))
359 (chord::subtractions->markup-banter (cdr subtractions))))
362 (define (chord::bass-and-inversion->markup-banter bass-and-inversion)
363 (if (and (pair? bass-and-inversion)
364 (or (car bass-and-inversion)
365 (cdr bass-and-inversion)))
368 (make-simple-markup "/")
369 (pitch->note-name-markup-banter
370 (if (car bass-and-inversion)
371 (car bass-and-inversion)
372 (cdr bass-and-inversion)))))
375 ;; FIXME: merge this function with inner-name-jazz, -american
376 ;; iso using chord::bass-and-inversion->markup-banter,
377 ;; See: chord::exceptions-lookup
378 (define (chord::inner-name-banter tonic exception-part additions subtractions
379 bass-and-inversion steps)
383 Combine tonic, exception-part of chord name,
384 additions, subtractions and bass or inversion into chord name
387 (let* ((tonic-markup (pitch->chord-name-markup-banter tonic steps))
388 (except-markup (if exception-part exception-part empty-markup))
389 (sep-markup (if (and exception-part
390 (let ((s (format "~s" except-markup)))
392 (string-match "super" s)
394 ;; python: `except_markup`[-5:] != '"o"))'
398 (- (string-length s) 5))))))
399 (or (pair? additions)
400 (pair? subtractions)))
401 (make-super-markup (make-simple-markup "/"))
403 (adds-markup (chord::additions->markup-banter additions subtractions))
404 (subs-markup (chord::subtractions->markup-banter subtractions))
405 (b+i-markup (chord::bass-and-inversion->markup-banter
406 bass-and-inversion)))
413 (make-normal-size-super-markup
414 (make-line-markup (list adds-markup subs-markup)))
417 (define (c++-pitch->scm p)
419 (list (ly:pitch-octave p) (ly:pitch-notename p) (ly:pitch-alteration p))
422 (define (chord::name-banter tonic exception-part unmatched-steps
423 bass-and-inversion steps)
424 (let ((additions (chord::additions unmatched-steps))
425 (subtractions (chord::subtractions unmatched-steps)))
427 (chord::inner-name-banter tonic exception-part additions subtractions
428 bass-and-inversion steps)))
432 (define (chord::exceptions-lookup exceptions steps)
434 return (MATCHED-EXCEPTION . BASE-CHORD-WITH-UNMATCHED-STEPS)
435 BASE-CHORD-WITH-UNMATCHED-STEPS always includes (tonic 3 5)
438 ;; this is unintelligible.
440 (define (chord::exceptions-lookup-helper
441 exception-alist try-steps unmatched-steps exception-part)
444 check exception-alist for biggest matching part of try-steps
445 return (MATCHED-EXCEPTION . UNMATCHED-STEPS)
448 (if (pair? try-steps)
449 ;; FIXME: junk '(0 . 0) from exceptions lists?
450 ;; if so: how to handle first '((0 . 0) . #f) entry?
452 ;; FIXME: either format exceptions list as real pitches, ie,
453 ;; including octave '((0 2 -1) ..), or drop octave
454 ;; from rest of calculations,
456 (map (lambda (x) (pitch->note-name x))
457 (append '((0 0 0)) try-steps))
460 (chord::exceptions-lookup-helper
461 #f '() unmatched-steps (cdr entry))
462 (let ((r (reverse try-steps)))
463 (chord::exceptions-lookup-helper
466 (cons (car r) unmatched-steps) #f))))
467 (cons exception-part unmatched-steps)))
469 (let* ((result (chord::exceptions-lookup-helper
472 (exception-part (car result))
473 (unmatched-steps (cdr result))
474 (matched-steps (if (= (length unmatched-steps) 0)
476 (+ 1 (- (length steps)
477 (length unmatched-steps)))))
478 (unmatched-with-1-3-5
479 (append (do ((i matched-steps (- i 1))
480 (base '() (cons `(0 ,(* (- i 1) 2) 0) base)))
484 (list exception-part unmatched-with-1-3-5)))
491 ;; See input/test/american-chords.ly
493 ;; Original Version by James Hammons, <jlhamm@pacificnet.net>
494 ;; Complete rewrite by Amelie Zapf, <amy@loueymoss.com>
496 ;; DONT use non-ascii characters, even if ``it works'' in Windows
499 (define mathm-markup-object
500 (make-override-markup '(font-family . math) (make-simple-markup "M")))
503 (define mathn-markup-object
504 (make-override-markup '(font-family . math) (make-simple-markup "N")))
506 (define (step->markup-accidental pitch)
508 ((-2) (accidental->markup -2))
509 ((-1) (accidental->markup -1))
511 ((1) (accidental->markup 1))
512 ((2) (accidental->markup 2)))
513 (make-simple-markup (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))))
515 (define-public chord::exception-alist-american
517 (((0 . 0)) . ,empty-markup)
518 (((0 . 0) (2 . -1)) . ,(make-simple-markup "m"))
520 ;; these should probably be normal-size? --jcn
521 ;;(((0 . 0) (4 . 0)) . ,(make-super-markup (make-simple-markup "5 ")))
522 ;;(((0 . 0) (1 . 0) (4 . 0)) . ,(make-super-markup (make-simple-markup "2 ")))
524 (((0 . 0) (4 . 0)) . ,(make-normal-size-super-markup (make-simple-markup "5 ")))
525 (((0 . 0) (1 . 0) (4 . 0)) . ,(make-normal-size-super-markup (make-simple-markup "2 ")))
527 ;;choose your symbol for the fully diminished chord
528 (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ,(make-simple-markup "dim"))
529 ;;(((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ,(make-line-markup (list empty-markup (make-super-markup (make-simple-markup "o")))))
532 (define (step->markup-american pitch)
534 ((6) (case (caddr pitch)
535 ((-2) (make-line-markup (list (accidental->markup -1) (make-simple-markup "7"))))
536 ((-1) (make-simple-markup "7"))
537 ((0) (make-simple-markup "maj7"))
538 ((1) (make-line-markup (list (accidental->markup 1) (make-simple-markup "7"))))
539 ((2) (make-line-markup (list (accidental->markup 2) (make-simple-markup "7"))))))
540 ((4) (case (caddr pitch)
541 ((-2) (make-line-markup (list (accidental->markup -2) (make-simple-markup "5"))))
542 ;;choose your symbol for the diminished fifth
543 ((-1) (make-simple-markup "-5"))
544 ;;((-1) (make-line-markup (list (accidental->markup -1) (make-simple-markup "5")))))
546 ;;choose your symbol for the augmented fifth
547 ;;((1) (make-simple-markup "aug"))
548 ;;((1) (make-line-markup (list (accidental->markup 1) (make-simple-markup "5")))))
549 ((1) (make-simple-markup "+5"))
550 ((2) (make-line-markup (list (accidental->markup 2) (make-simple-markup "5"))))))
551 (else (if (and (= (car pitch) 0)
554 (make-simple-markup "sus4")
555 (step->markup-accidental pitch)))))
557 (define (chord::additions->markup-american additions subtractions)
558 (if (pair? additions)
559 ;; I don't like all this reasoning here, when we're actually typesetting.
560 (if(and(pair? (cdr additions)) ;a further addition left over
561 (or(and(= 0 (caddr(car additions))) ;this addition natural
562 (not(= 6 (cadr(car additions)))))
563 (and(= -1 (caddr(car additions)))
564 (= 6 (cadr(car additions)))))
565 (or(and(= 0 (caddr(cadr additions))) ;the following addition natural
566 (not(= 6 (cadr(cadr additions)))))
567 (and(= -1 (caddr(cadr additions)))
568 (= 6 (cadr(cadr additions)))))
569 (or(and(= (car(car additions)) (car(cadr additions))) ;both a third apart
570 (= 2 (- (cadr(cadr additions)) (cadr(car additions)))))
571 (and(= 1 (- (car(cadr additions)) (car(car additions))))
572 (= 5 (- (cadr(car additions)) (cadr(cadr additions))))))
573 (or(null? subtractions) ;this or clause protects the "adds"
574 (and (pair? subtractions)
575 (or (< (car(cadr additions)) (car(car subtractions)))
576 (and(= (car(cadr additions)) (car(car subtractions)))
577 (< (cadr(cadr additions)) (cadr(car subtractions))))))))
578 (chord::additions->markup-american (cdr additions) subtractions)
581 (let ((step (step->markup-american (car additions))))
582 (if (or (pair? (cdr additions))
583 (pair? subtractions))
584 (if (and (pair? (cdr additions))
585 (or(< 3 (- (cadr(cadr additions)) (cadr(car additions))))
586 (and(< 0 (- (car(cadr additions)) (car(car additions))))
587 (> 4 (- (cadr(car additions)) (cadr(cadr additions)))))))
588 (make-line-markup (list step (make-simple-markup " add")))
589 ;; tweak your favorite separator here
590 ;; (make-line-markup (list step (make-simple-markup "/")))
591 (make-line-markup (list step (make-simple-markup " "))))
593 (chord::additions->markup-american (cdr additions) subtractions))))
596 (define (chord::inner-name-american tonic exception-part additions subtractions
597 bass-and-inversion steps)
598 (let* ((tonic-markup (pitch->chord-name-markup-banter tonic steps))
599 (except-markup (if exception-part exception-part empty-markup))
600 (sep-markup (if (and (string-match "super" (format "~s" except-markup))
601 (or (pair? additions)
602 (pair? subtractions)))
603 (make-super-markup (make-simple-markup "/"))
605 ;;this list contains all the additions that go "in line"
609 (let ((o (car x)) (n (cadr x)) (a (caddr x)))
610 (and (not (and (= 0 o) (= 2 n))) ;gets rid of unwanted thirds
611 ;;change this if you want it differently
612 (not (and (= 0 o) (= 3 n) (= 0 a))) ;sus4
613 (not (and (= 0 o) (= 4 n) (!= 0 a)))))) ;alt5
615 ;;this list contains all the additions that are patched onto the end
616 ;;of the chord symbol, usually sus4 and altered 5ths.
618 ;;take out the reverse if it bothers you in a pathological chord
622 (let ((o (car x)) (n (cadr x)) (a (caddr x)))
623 (and(not (and (= 0 o) (= 2 n))) ;gets rid of unwanted thirds
624 ;;change this correspondingly
625 (or(and (= 0 o) (= 3 n) (= 0 a)) ;sus4
626 (and (= 0 o) (= 4 n) (!= 0 a)))))) ;alt5
628 (relevant-subs (filter-list
629 (lambda (x) ;catches subtractions higher than 5th
630 (let((o (car x)) (n (cadr x)))
634 (pref-markup (chord::additions->markup-american prefixes relevant-subs))
635 (suff-markup (chord::additions->markup-american suffixes relevant-subs))
636 (b+i-markup (chord::bass-and-inversion->markup-banter bass-and-inversion)))
639 tonic-markup except-markup sep-markup
640 (make-normal-size-super-markup
641 (make-line-markup (list pref-markup suff-markup)))
644 (define (chord::additions-american steps)
645 (let ((evens (filter-list (lambda (x) (!= 0 (modulo (cadr x) 2))) steps))
646 ;we let all the unevens pass for now, we'll fix that later.
648 (filter-list (lambda (x)
649 (let ((n (cadr x)) (a (caddr x)))
650 (or (and (= 6 n) (!= -1 a))
652 (= 0 (modulo n 2))))))
654 (highest (let ((h (car (last-pair steps))))
655 (if (and (not (null? h))
660 (uniq-list (sort (apply append evens unevens highest)
663 ;; American style chordnames use no "no",
664 ;; but otherwise very similar to banter for now
665 (define-public (chord::name-american tonic exception-part unmatched-steps
666 bass-and-inversion steps)
667 (let ((additions (chord::additions-american unmatched-steps))
668 (subtractions (chord::subtractions unmatched-steps)))
669 (chord::inner-name-american tonic exception-part additions subtractions
670 bass-and-inversion steps)))
674 ;; Jazz chords, by Atte Andr'e Jensen <atte@post.com>
675 ;; Complete rewrite by Amelie Zapf (amy@loueymoss.com)
677 ;; FIXME: identical to chord::exception-alist-american, apart from commented
678 ;; dim chord. should merge.
679 (define-public chord::exception-alist-jazz
681 (((0 . 0)) . ,empty-markup)
682 (((0 . 0) (2 . -1)) . ,(make-simple-markup "m"))
684 ;; these should probably be normal-size? --jcn
685 ;;(((0 . 0) (4 . 0)) . ,(make-super-markup (make-simple-markup "5 ")))
686 ;;(((0 . 0) (1 . 0) (4 . 0)) . ,(make-super-markup (make-simple-markup "2 ")))
688 (((0 . 0) (4 . 0)) . ,(make-normal-size-super-markup (make-simple-markup "5 ")))
689 (((0 . 0) (1 . 0) (4 . 0)) . ,(make-normal-size-super-markup (make-simple-markup "2 ")))
691 ;;choose your symbol for the fully diminished chord
692 ;;(((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ,(make-simple-markup "dim"))
693 (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ,(make-line-markup (list (make-simple-markup "") (make-super-markup (make-simple-markup "o")))))
696 ;; FIXME: rather similar to step->markup-american. should merge.
697 (define (step->markup-jazz pitch)
699 ((6) (case (caddr pitch)
700 ((-2) (make-line-markup (list (accidental->markup -1) (make-simple-markup "7"))))
701 ((-1) (make-simple-markup "7"))
702 ;;Pick your favorite maj7
703 ((0) mathm-markup-object) ;;a white triangle
704 ;;((0) mathn-markup-object) ;;a black triangle
705 ;;((0) (make-simple-markup "maj7")) ;;good old maj7
706 ((1) (make-line-markup (list (accidental->markup 1) (make-simple-markup "7"))))
707 ((2) (make-line-markup (list (accidental->markup 2) (make-simple-markup "7"))))))
708 ((4) (case (caddr pitch)
709 ((-2) (make-line-markup (list (accidental->markup -2) (make-simple-markup "5"))))
710 ;;choose your symbol for the diminished fifth
711 ;;((-1) (make-simple-markup "-5"))
712 ((-1) (make-line-markup (list (accidental->markup -1) (make-simple-markup "5"))))
714 ;;choose your symbol for the augmented fifth
715 ;;((1) (make-simple-markup "aug"))
716 ((1) (make-line-markup (list (accidental->markup 1) (make-simple-markup "5"))))
717 ;;((1) (make-simple-markup "+5"))
718 ((2) (make-line-markup (list (accidental->markup 2) (make-simple-markup "5"))))))
719 (else (if (and (= (car pitch) 0)
722 (make-simple-markup "sus4")
723 (step->markup-accidental pitch)))))
725 ;; FIXME: identical to chord::additions->markup-american,
726 ;; except for -jazz / -american suffixes on calls
727 (define (chord::additions->markup-jazz additions subtractions)
728 (if (pair? additions)
729 ;; I don't like all this reasoning here, when we're actually typesetting.
730 (if(and(pair? (cdr additions)) ;a further addition left over
731 (or(and(= 0 (caddr(car additions))) ;this addition natural
732 (not(= 6 (cadr(car additions)))))
733 (and(= -1 (caddr(car additions)))
734 (= 6 (cadr(car additions)))))
735 (or(and(= 0 (caddr(cadr additions))) ;the following addition natural
736 (not(= 6 (cadr(cadr additions)))))
737 (and(= -1 (caddr(cadr additions)))
738 (= 6 (cadr(cadr additions)))))
739 (or(and(= (car(car additions)) (car(cadr additions))) ;both a third apart
740 (= 2 (- (cadr(cadr additions)) (cadr(car additions)))))
741 (and(= 1 (- (car(cadr additions)) (car(car additions))))
742 (= 5 (- (cadr(car additions)) (cadr(cadr additions))))))
743 (or(null? subtractions) ;this or clause protects the "adds"
744 (and (pair? subtractions)
745 (or (< (car(cadr additions)) (car(car subtractions)))
746 (and(= (car(cadr additions)) (car(car subtractions)))
747 (< (cadr(cadr additions)) (cadr(car subtractions))))))))
748 (chord::additions->markup-jazz (cdr additions) subtractions)
751 (let ((step (step->markup-jazz (car additions))))
752 (if (or (pair? (cdr additions))
753 (pair? subtractions))
754 (if (and (pair? (cdr additions))
755 (or(< 3 (- (cadr(cadr additions)) (cadr(car additions))))
756 (and(< 0 (- (car(cadr additions)) (car(car additions))))
757 (> 4 (- (cadr(car additions)) (cadr(cadr additions)))))))
758 (make-line-markup (list step (make-simple-markup " add")))
759 ;; tweak your favorite separator here
760 ;; (make-line-markup (list step (make-simple-markup "/")))
761 (make-line-markup (list step (make-simple-markup " "))))
763 (chord::additions->markup-jazz (cdr additions) subtractions))))
766 ;; FIXME: identical to chord::additions->markup-american.
767 ;; except for -jazz / -american suffixes on calls
768 (define (chord::inner-name-jazz tonic exception-part additions subtractions
769 bass-and-inversion steps)
770 (let* ((tonic-markup (pitch->chord-name-markup-banter tonic steps))
771 (except-markup (if exception-part exception-part empty-markup))
772 (sep-markup (if (and (string-match "super" (format "~s" except-markup))
773 (or (pair? additions)
774 (pair? subtractions)))
775 (make-super-markup (make-simple-markup "/"))
777 ;;this list contains all the additions that go "in line"
781 (let ((o (car x)) (n (cadr x)) (a (caddr x)))
782 (and (not (and (= 0 o) (= 2 n))) ;gets rid of unwanted thirds
783 ;;change this if you want it differently
784 (not (and (= 0 o) (= 3 n) (= 0 a))) ;sus4
785 (not (and (= 0 o) (= 4 n) (!= 0 a)))))) ;alt5
787 ;;this list contains all the additions that are patched onto the end
788 ;;of the chord symbol, usually sus4 and altered 5ths.
790 ;;take out the reverse if it bothers you in a pathological chord
794 (let ((o (car x)) (n (cadr x)) (a (caddr x)))
795 (and(not (and (= 0 o) (= 2 n))) ;gets rid of unwanted thirds
796 ;;change this correspondingly
797 (or(and (= 0 o) (= 3 n) (= 0 a)) ;sus4
798 (and (= 0 o) (= 4 n) (!= 0 a)))))) ;alt5
800 (relevant-subs (filter-list
801 (lambda (x) ;catches subtractions higher than 5th
802 (let((o (car x)) (n (cadr x)))
806 (pref-markup (chord::additions->markup-jazz prefixes relevant-subs))
807 (suff-markup (chord::additions->markup-jazz suffixes relevant-subs))
808 (b+i-markup (chord::bass-and-inversion->markup-banter bass-and-inversion)))
811 tonic-markup except-markup sep-markup
812 (make-normal-size-super-markup
813 (make-line-markup (list pref-markup suff-markup)))
816 (define (chord::name-jazz tonic exception-part unmatched-steps
817 bass-and-inversion steps)
818 (let ((additions (chord::additions-american unmatched-steps))
819 (subtractions (chord::subtractions unmatched-steps)))
820 (chord::inner-name-jazz tonic exception-part additions subtractions
821 bass-and-inversion steps)))
824 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
827 (define-public (new-chord->markup func ly-pitches bass inversion exceptions)
828 "Entry point for New_chord_name_engraver. See chord-name.scm for the
829 signature of FUNC. LY-PITCHES, BASS and INVERSION are lily
830 pitches. EXCEPTIONS is an alist (see scm file).
833 (let* ((pitches (map c++-pitch->scm ly-pitches))
835 (cons (c++-pitch->scm bass)
836 (c++-pitch->scm inversion)))
837 (diff (pitch::diff '(0 0 0) (car pitches)))
838 (steps (if (cdr pitches) (map (lambda (x)
839 (pitch::transpose x diff))
842 (lookup (dbg (chord::exceptions-lookup exceptions steps)))
843 (exception-part (dbg (car lookup)))
844 (unmatched-steps (cadr lookup))
845 (tonic (car pitches))
848 (func tonic exception-part unmatched-steps bass-and-inversion steps)
851 (define-public (chord->markup-jazz . args)
852 (apply new-chord->markup (cons chord::name-jazz args))
855 (define-public (chord->markup-american . args)
856 (apply new-chord->markup (cons chord::name-american args))
859 (define-public (chord->markup-banter . args)
860 (apply new-chord->markup (cons chord::name-banter args))
863 (define-public (new-chord-name-brew-molecule grob)
866 (ws (ly:get-grob-property grob 'word-space))
867 (markup (ly:get-grob-property grob 'text))
868 (molecule (interpret-markup grob
869 (cons '((word-space . 0.0))
870 (Font_interface::get_property_alist_chain grob))
875 ;; chord names aren't in staffs, so WS is in global staff space.
877 (ly:combine-molecule-at-edge
879 X RIGHT (ly:make-molecule "" (cons 0 ws) '(-1 . 1) )
884 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
886 (define-public (set-chord-name-style sym)
887 "Return music expressions that set the chord naming style. For
888 inline use in .ly file"
890 (define (chord-name-style-setter function exceptions)
892 (make-sequential-music
893 (list (make-property-set 'chordNameFunction function)
894 (make-property-set 'chordNameExceptions exceptions)))
902 (chord-name-style-setter chord->markup-jazz
903 chord::exception-alist-jazz))
905 (chord-name-style-setter chord->markup-banter
906 chord::exception-alist-banter))
908 (chord-name-style-setter chord->markup-american
909 chord::exception-alist-american))