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 (mydisplay x) (display x) x)
26 - Use lilypond Pitch objects -- SCM pitch objects lead to
27 duplication. LilyPond pitch objects force meaningful names
28 (i.e. (ly:pitch-octave PITCH) )
31 - Pitches are musical objects. The pitches -> markup step should
32 happen earlier (during interpreting), brew-molecule () should only
33 dump reinterpret the markup as a molecule.
39 ;; pitch = (octave notename alteration)
41 ;; note = (notename . alteration)
43 ;; text = scm markup text -- see font.scm and input/test/markup.ly
48 ;; Ugh : naming chord::... ; this is scheme not C++
50 ;; * easier tweakability:
51 ;; - split chord::names-alists up into logical bits,
52 ;; such as chord::exceptions-delta, exceptions-oslash
53 ;; - iso just the 'style parameter, use a list, eg:
54 ;; \property ChordNames.ChordName \set
55 ;; #'style = #'(jazz delta oslash german-tonic german-Bb)
59 ;; * clean split/merge of bass/banter/american stuff
63 (define-public chord::names-alist-banter '())
64 (set! chord::names-alist-banter
68 (((0 . 0)) . ,empty-markup)
70 (((0 . 0) (2 . 0)) . ,empty-markup)
72 (((0 . 0) (2 . -1)) . (,simple-markup "m"))
74 (((0 . 0) (1 . 0) (4 . 0)) . (,super-markup (,simple-markup "2 ")))
76 (((0 . 0) (3 . 0) (4 . 0)) . (,super-markup (,simple-markup "4 ")))
78 (((0 . 0) (2 . -1) (4 . -1)) . (,simple-markup "dim"))
79 ; URG: Simply C:m5-/maj7 iso Cdim maj7
80 (((0 . 0) (2 . -1) (4 . -1) (6 . 0)) . (,line-markup ((,simple-markup "m") (,super-markup (,simple-markup "5-/maj7 ")))))
81 ; URG: Simply C:m5-/7 iso Cdim7
82 (((0 . 0) (2 . -1) (4 . -1) (6 . -1)) . (,line-markup ((,simple-markup "m") (,super-markup (,simple-markup "5-/7 ")))))
84 (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . (,super-markup (,simple-markup "o ")))
86 (((0 . 0) (2 . -1) (4 . -1) (6 . -2) (1 . -1)) . (,line-markup ((,simple-markup "dim")
87 (,simple-markup "9 "))))
88 (((0 . 0) (2 . -1) (4 . -1) (6 . -2) (1 . -1) (3 . -1))
89 . (,line-markup ((,simple-markup "dim")
90 (,super-markup (,simple-markup "11 ")))))
93 chord::names-alist-banter))
97 (define (pitch->note-name pitch)
98 (cons (cadr pitch) (caddr pitch)))
100 (define (accidental-markup acc)
101 "ACC is an int, return a markup making an accidental."
104 `(,smaller-markup (,musicglyph-markup ,(string-append "accidentals-" (number->string acc))))
107 (define (pitch->markup pitch)
111 ,(make-string 1 (integer->char (+ (modulo (+ (cadr pitch) 2) 7) 65))))
112 (,normal-size-superscript-markup
113 ,(accidental-markup (caddr pitch))))))
115 ;;; Hooks to override chord names and note names,
116 ;;; see input/tricks/german-chords.ly
118 (define pitch->markup-banter pitch->markup)
120 ;; We need also steps, to allow for Cc name override,
121 ;; see input/test/Cc-chords.ly
122 (define (pitch->chord-name-markup-banter pitch steps)
123 (pitch->markup-banter pitch))
125 (define pitch->note-name-markup-banter pitch->markup-banter)
127 (define (step->markup pitch)
129 (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))
137 (define (step->markup-banter pitch)
139 (if (= (cadr pitch) 6)
146 (step->markup pitch))))
148 (define pitch::semitone-vec #(0 2 4 5 7 9 11))
150 (define (pitch::semitone pitch)
151 (+ (* (car pitch) 12)
152 (vector-ref pitch::semitone-vec (modulo (cadr pitch) 7))
155 (define (pitch::< l r)
156 (< (pitch::semitone l) (pitch::semitone r)))
158 (define (pitch::transpose pitch delta)
159 (let ((simple-octave (+ (car pitch) (car delta)))
160 (simple-notename (+ (cadr pitch) (cadr delta))))
161 (let ((octave (+ simple-octave (quotient simple-notename 7)))
162 (notename (modulo simple-notename 7)))
163 (let ((accidental (- (+ (pitch::semitone pitch) (pitch::semitone delta))
164 (pitch::semitone `(,octave ,notename 0)))))
165 `(,octave ,notename ,accidental)))))
167 (define (pitch::diff pitch tonic)
168 (let ((simple-octave (- (car pitch) (car tonic)))
169 (simple-notename (- (cadr pitch) (cadr tonic))))
170 (let ((octave (+ simple-octave (quotient simple-notename 7)
171 (if (< simple-notename 0) -1 0)))
172 (notename (modulo simple-notename 7)))
173 (let ((accidental (- (pitch::semitone pitch)
174 (pitch::semitone tonic)
175 (pitch::semitone `(,octave ,notename 0)))))
176 `(,octave ,notename ,accidental)))))
178 (define (pitch::note-pitch pitch)
179 (+ (* (car pitch) 7) (cadr pitch)))
181 ;; markup: list of word
182 ;; word: string + optional list of property
183 ;; property: axis, kern, font (?), size
185 (define chord::minor-major-vec (list->vector '(0 -1 -1 0 -1 -1 0)))
188 ;; compute the relative-to-tonic pitch that goes with 'step'
189 (define (chord::step-pitch tonic step)
190 ;; urg, we only do this for thirds
191 (if (= (modulo step 2) 0)
193 (let loop ((i 1) (pitch tonic))
197 pitch `(0 2 ,(vector-ref chord::minor-major-vec
198 ;; -1 (step=1 -> vector=0) + 7 = 6
199 (modulo (+ i 6) 7)))))))))
201 (define (chord::additions steps)
203 * any even step (2, 4, 6)
204 * any uneven step that is chromatically altered,
205 (where 7-- == -1, 7- == 0, 7 == +1)
208 ?and jazz needs also:
210 * TODO: any uneven step that's lower than an uneven step which is
211 chromatically altered
213 (let ((evens (filter-list (lambda (x) (!= 0 (modulo (cadr x) 2))) steps))
215 (filter-list (lambda (x)
216 (let ((n (cadr x)) (a (caddr x)))
217 (or (and (= 6 n) (!= -1 a))
222 (highest (let ((h (car (last-pair steps))))
223 (if (and (not (null? h))
228 ;; Hmm, what if we have a step twice, can we ignore that?
229 (uniq-list (sort (apply append evens altered-unevens highest)
233 ;; FIXME: unLOOP, see ::additions
234 ;; find the pitches that are missing from `normal' chord
235 (define (chord::subtractions chord-pitches)
236 (let ((tonic (car chord-pitches)))
237 (let loop ((step 1) (pitches chord-pitches) (subtractions '()))
239 (let* ((pitch (car pitches))
240 (p-step (+ (- (pitch::note-pitch pitch)
241 (pitch::note-pitch tonic))
243 ;; pitch is an subtraction if
244 ;; a step is missing or
246 (loop (+ step 2) pitches
247 (cons (chord::step-pitch tonic step) subtractions))
248 ;; there are no pitches left, but base thirds are not yet done and
250 (= (length pitches) 1))
251 ;; present pitch is not missing step
253 (loop (+ step 2) pitches subtractions)
254 (loop (+ step 2) pitches
255 (cons (chord::step-pitch tonic step) subtractions)))
257 (loop (+ step 2) (cdr pitches) subtractions)
258 (loop step (cdr pitches) subtractions)))))
259 (reverse subtractions)))))
261 (define (chord::additions->markup-banter additions subtractions)
262 (if (pair? additions)
265 (let ((step (step->markup-banter (car additions))))
266 (if (or (pair? (cdr additions))
267 (pair? subtractions))
269 (list step (list simple-markup "/")))
272 (chord::additions->markup-banter (cdr additions) subtractions)))
276 (define (chord::subtractions->markup-banter subtractions)
277 (if (pair? subtractions)
279 ((,simple-markup "no")
280 ,(let ((step (step->markup-jazz (car subtractions))))
281 (if (pair? (cdr subtractions))
282 `(,line-markup (,step (,simple-markup "/")))
284 ,(chord::subtractions->markup-banter (cdr subtractions))))
288 (define (chord::bass-and-inversion->markup-banter bass-and-inversion)
289 (if (and (pair? bass-and-inversion)
290 (or (car bass-and-inversion)
291 (cdr bass-and-inversion)))
295 ,(pitch->note-name-markup-banter
296 (if (car bass-and-inversion)
297 (car bass-and-inversion)
298 (cdr bass-and-inversion)))
303 ;; FIXME: merge this function with inner-name-jazz, -american
304 ;; iso using chord::bass-and-inversion->markup-banter,
305 ;; call (chord::restyle 'chord::bass-and-inversion->markup- style)
306 ;; See: chord::exceptions-lookup
307 (define (chord::inner-name-banter tonic exception-part additions subtractions
308 bass-and-inversion steps)
313 Combine tonic, exception-part of chord name,
314 additions, subtractions and bass or inversion into chord name
317 (let* ((tonic-markup (pitch->chord-name-markup-banter tonic steps))
321 (if exception-part exception-part `(,simple-markup "fixme")))
322 (sep-markup (list simple-markup
323 (if (and (string-match "super" (format "~s" except-markup))
324 (or (pair? additions)
325 (pair? subtractions)))
328 (adds-markup (chord::additions->markup-banter additions subtractions))
329 (subs-markup (chord::subtractions->markup-banter subtractions))
330 (b+i-markup (chord::bass-and-inversion->markup-banter bass-and-inversion)))
337 (,line-markup (,adds-markup ,subs-markup))
343 (define (c++-pitch->scm p)
345 (list (ly:pitch-octave p) (ly:pitch-notename p) (ly:pitch-alteration p))
348 (define-public (chord::name-banter tonic exception-part unmatched-steps
349 bass-and-inversion steps)
350 (let ((additions (chord::additions unmatched-steps))
351 (subtractions (chord::subtractions unmatched-steps)))
353 (chord::inner-name-banter tonic exception-part additions subtractions
354 bass-and-inversion steps)))
357 (define (chord::restyle name style)
358 (primitive-eval ;; "UGGHGUGHUGHG"
361 (string-append (symbol->string name)
362 (symbol->string style)))))
365 ;; this is unintelligible.
369 ; - what's a helper, and why isn't it inside another function?
371 ; what is going out, what is coming in, howcome it produces #f
375 (define (chord::exceptions-lookup-helper
376 exceptions-alist try-steps unmatched-steps exception-part)
379 check exceptions-alist for biggest matching part of try-steps
380 return (MATCHED-EXCEPTION . UNMATCHED-STEPS)
383 (if (pair? try-steps)
384 ;; FIXME: junk '(0 . 0) from exceptions lists?
385 ;; if so: how to handle first '((0 . 0) . #f) entry?
387 ;; FIXME: either format exceptions list as real pitches, ie,
388 ;; including octave '((0 2 -1) ..), or drop octave
389 ;; from rest of calculations,
391 (map (lambda (x) (pitch->note-name x))
392 (append '((0 0 0)) try-steps))
395 (chord::exceptions-lookup-helper
396 #f '() unmatched-steps (cdr entry))
397 (let ((r (reverse try-steps)))
398 (chord::exceptions-lookup-helper
401 (cons (car r) unmatched-steps) #f))))
402 (cons exception-part unmatched-steps)))
406 (define (chord::exceptions-lookup style steps)
408 return (MATCHED-EXCEPTION . BASE-CHORD-WITH-UNMATCHED-STEPS)
409 BASE-CHORD-WITH-UNMATCHED-STEPS always includes (tonic 3 5)
413 (let* ((result (chord::exceptions-lookup-helper
414 (chord::restyle 'chord::names-alist- style)
416 (exception-part (car result))
417 (unmatched-steps (cdr result))
418 (matched-steps (if (= (length unmatched-steps) 0)
420 (+ 1 (- (length steps)
421 (length unmatched-steps)))))
422 (unmatched-with-1-3-5
423 (append (do ((i matched-steps (- i 1))
424 (base '() (cons `(0 ,(* (- i 1) 2) 0) base)))
428 (list exception-part unmatched-with-1-3-5)))
431 (define (chord::name->markup style tonic steps bass-and-inversion)
432 (let* ((lookup (chord::exceptions-lookup style steps))
433 (exception-part (car lookup))
434 (unmatched-steps (cadr lookup))
435 (func (chord::restyle 'chord::name- style))
439 (func tonic exception-part unmatched-steps bass-and-inversion steps)))
443 ;; Check for each subset of chord, full chord first, if there's a
444 ;; user-override. Split the chord into user-overridden and to-be-done
445 ;; parts, complete the missing user-override matched part with normal
446 ;; chord to be name-calculated.
448 ;; CHORD: (pitches (bass . inversion))
449 (define-public (chord->markup style chord)
450 (let* ((pitches (map c++-pitch->scm (car chord)))
451 (modifiers (cdr chord))
452 (bass-and-inversion (if (pair? modifiers)
453 (cons (c++-pitch->scm (car modifiers))
454 (c++-pitch->scm (cdr modifiers)))
456 (diff (pitch::diff '(0 0 0) (car pitches)))
457 (steps (if (cdr pitches) (map (lambda (x)
458 (pitch::transpose x diff))
462 (chord::name->markup style (car pitches) steps bass-and-inversion)
470 ;; NOTE: Duplicates of chord names defined elsewhere occur in this list
471 ;; in order to prevent spurious superscripting of various chord names,
472 ;; such as maj7, maj9, etc.
474 ;; See input/test/american-chords.ly
476 ;; James Hammons, <jlhamm@pacificnet.net>
479 ;; DONT use non-ascii characters, even if ``it works'' in Windows
481 (define-public chord::names-alist-american '())
483 (set! chord::names-alist-american
486 (((0 . 0)) . ,empty-markup)
487 (((0 . 0) (2 . 0)) . ,empty-markup)
489 (((0 . 0) (4 . 0)) . (,simple-markup "5"))
491 (((0 . 0) (2 . -1)) . (,simple-markup "m"))
492 (((0 . 0) (3 . 0) (4 . 0)) . (,simple-markup "sus"))
493 (((0 . 0) (2 . -1) (4 . -1)) . (,simple-markup "dim"))
494 ;Alternate: (((0 . 0) (2 . -1) (4 . -1)) . ("" (super "o")))
495 (((0 . 0) (2 . 0) (4 . 1)) . (,simple-markup "aug"))
496 ;Alternate: (((0 . 0) (2 . 0) (4 . 1)) . ("+"))
497 (((0 . 0) (1 . 0) (4 . 0)) . (,simple-markup "2"))
498 ;; Common seventh chords
499 (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) .
501 ((,super-markup (,simple-markup "o"))
502 (,simple-markup " 7"))))
503 (((0 . 0) (2 . 0) (4 . 0) (6 . 0)) . (,simple-markup "maj7"))
504 ;; urg! should use (0 . 0 2 . -1) -> "m", and add "7" to that!!
505 (((0 . 0) (2 . -1) (4 . 0) (6 . -1)) . (,simple-markup "m7"))
506 (((0 . 0) (2 . 0) (4 . 0) (6 . -1)) . (,simple-markup "7"))
507 (((0 . 0) (2 . -1) (4 . 0) (6 . 0)) . (,simple-markup "m(maj7)"))
508 ;jazz: the delta, see jazz-chords.ly
509 ;;(((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . (super ((font-family . math) "N"))
511 (((0 . 0) (2 . -1) (4 . -1) (6 . -1)) .
514 (,combine-markup (,simple-markup "o")
515 (,simple-markup "/")))
516 (,simple-markup " 7"))))
517 (((0 . 0) (2 . 0) (4 . 1) (6 . -1)) . (,simple-markup "aug7"))
518 (((0 . 0) (2 . 0) (4 . -1) (6 . 0))
520 ((,simple-markup "maj7")
521 (,small-markup (,raise-markup 0.2 ,(accidental-markup -1)))
522 (,simple-markup "5"))))
523 (((0 . 0) (2 . 0) (4 . -1) (6 . -1)) .
525 ((,simple-markup "7")
526 (,small-markup (,raise-markup 0.2 ,(accidental-markup -1)))
527 (,simple-markup "5"))))
528 (((0 . 0) (3 . 0) (4 . 0) (6 . -1)) . (,simple-markup "7sus4"))
529 ;; Common ninth chords
530 (((0 . 0) (2 . 0) (4 . 0) (5 . 0) (1 . 0)) . (,simple-markup "6/9")) ;; we don't want the '/no7'
531 (((0 . 0) (2 . 0) (4 . 0) (5 . 0)) . (,simple-markup "6"))
532 (((0 . 0) (2 . -1) (4 . 0) (5 . 0)) . (,simple-markup "m6"))
533 (((0 . 0) (2 . 0) (4 . 0) (1 . 0)) . (,simple-markup "add9"))
534 (((0 . 0) (2 . 0) (4 . 0) (6 . 0) (1 . 0)) . (,simple-markup "maj9"))
535 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . 0)) . (,simple-markup "9"))
536 (((0 . 0) (2 . -1) (4 . 0) (6 . -1) (1 . 0)) . (,simple-markup "m9"))
539 chord::names-alist-american))
541 ;; American style chordnames use no "no",
542 ;; but otherwise very similar to banter for now
543 (define-public (chord::name-american tonic exception-part unmatched-steps
544 bass-and-inversion steps)
545 (let ((additions (chord::additions unmatched-steps))
547 (chord::inner-name-banter tonic exception-part additions subtractions
548 bass-and-inversion steps)))
556 ;; Jazz chords, by Atte Andr'e Jensen <atte@post.com>
557 ;; NBs: This uses the american list as a bass.
558 ;; Some defs take up more than one line,
559 ;; be carefull when messing with ;'s!!
564 ;; This is getting out-of hand? Only exceptional chord names that
565 ;; cannot be generated should be here.
566 ;; Maybe we should have inner-name-jazz and inner-name-american functions;
570 ;; DONT use non-ascii characters, even if ``it works'' in Windows
572 (define mathm-markup-object `(,override-markup (font-family . math) (,simple-markup "M")))
573 (define mraise-arg `(,line-markup
574 ((,simple-markup "m")
575 (,raise-markup 0.5 (,simple-markup arg)))))
577 (define (raise-some-for-jazz arg-list)
580 ("@" `(,raise-markup 0.3 ,(accidental-markup -1)))
581 ("#" `(,raise-markup 0.3 ,(accidental-markup 1)))
582 (else `(,raise-markup 0.8 ,x))))
584 `(line-markup ,(map do-one arg-list)))
586 (define-public chord::names-alist-jazz '())
587 (set! chord::names-alist-jazz
591 ; major sixth chord = 6
592 (((0 . 0) (2 . 0) (4 . 0) (5 . 0)) .
593 (,raise-markup 0.5 (,simple-markup "6")))
594 ; major seventh chord = triangle
595 ;; shouldn't this be a filled black triange, like this: ? --jcn
596 ;; (((0 . 0) (2 . 0) (4 . 0) (6 . 0)) . (((raise . 0.5)((font-family . math) "N"))))
597 (((0 . 0) (2 . 0) (4 . 0) (6 . 0)) .
603 ; major chord add nine = add9
604 (((0 . 0) (2 . 0) (4 . 0) (1 . 0)) . (,raise-markup 0.5 (,simple-markup "add9")))
605 ; major sixth chord with nine = 6/9
606 (((0 . 0) (2 . 0) (4 . 0) (5 . 0) (1 . 0)) . (,raise-markup 0.5 (,simple-markup "add9")))
609 ; minor sixth chord = m6
610 (((0 . 0) (2 . -1) (4 . 0) (5 . 0)) .
613 ;; minor major seventh chord = m triangle
614 ;; shouldn't this be a filled black triange, like this: ? --jcn
615 ;;(((0 . 0) (2 . -1) (4 . 0) (6 . 0)) . (columns ("m") ((raise . 0.5)((font-family . math) "N"))))
616 (((0 . 0) (2 . -1) (4 . 0) (6 . 0)) .
617 (,line-markup ((,simple-markup "m") ,mathm-markup-object)))
618 ; minor seventh chord = m7
619 (((0 . 0) (2 . -1) (4 . 0) (6 . -1)) . ,(mraise-arg "7"))
620 ; minor sixth nine chord = m6/9
621 (((0 . 0) (2 . -1) (4 . 0) (5 . 0) (1 . 0)) . ,(mraise-arg "6/9"))
623 ; minor with added nine chord = madd9
624 (((0 . 0) (2 . -1) (4 . 0) (1 . 0)) . ,(mraise-arg "madd9"))
626 ; minor ninth chord = m9
627 (((0 . 0) (2 . -1) (4 . 0) (6 . -1) (1 . 0)) . ,(mraise-arg "add9"))
630 ; dominant seventh = 7
631 (((0 . 0) (2 . 0) (4 . 0) (6 . -1)) . (,raise-markup 0.5 (,simple-markup "7")))
632 ; augmented dominant = +7
633 ;(((0 . 0) (2 . 0) (4 . +1) (6 . -1)) . (((raise . 0.5) "+7"))) ; +7 with both raised
634 (((0 . 0) (2 . 0) (4 . +1) (6 . -1)) .
635 (,line-markup ((,simple-markup "+")
636 (,raise-markup 0.5 (,simple-markup "7"))))) ; +7 with 7 raised
637 ;(((0 . 0) (2 . 0) (4 . +1) (6 . -1)) . (columns((raise . 0.5) "7(")
638 ; ((raise . 0.3)(music (named ("accidentals-1"))))
639 ; ((raise . 0.5) "5)"))); 7(#5)
640 ; dominant flat 5 = 7(b5)
642 (((0 . 0) (2 . 0) (4 . -1) (6 . -1)) . ,(raise-some-for-jazz '( "7(" "@" "5)" )))
645 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . 0)) .
646 ,(raise-some-for-jazz '("7(9)")))
647 ; dominant flat 9 = 7(b9)
648 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . -1)) .
649 ,(raise-some-for-jazz '("7(" "@" "9)")))
651 ; dominant sharp 9 = 7(#9)
652 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . +1)) .
653 ,(raise-some-for-jazz '("7(" "#" "9)")))
655 ; dominant 13 = 7(13)
656 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (5 . 0)) .
657 ,(raise-some-for-jazz "7(13)"))
658 ; dominant flat 13 = 7(b13)
659 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (5 . -1)) .
660 ,(raise-some-for-jazz '( "7(" "@" "13)")))
662 ; dominant 9, 13 = 7(9,13)
663 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . 0) (5 . 0)) .
664 ,(raise-some-for-jazz '("7(9, 13)")))
665 ; dominant flat 9, 13 = 7(b9,13)
666 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . -1) (5 . 0)) .
667 ,(raise-some-for-jazz '("7(" "@" "9, 13)")))
669 ; dominant sharp 9, 13 = 7(#9,13)
670 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . +1) (5 . 0)) .
671 ,(raise-some-for-jazz '("7(" "#" "9,13)")))
673 ; dominant 9, flat 13 = 7(9,b13)
674 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . 0) (5 . -1)) .
675 ,(raise-some-for-jazz "7(9, " "@" "13)"))
677 ; dominant flat 9, flat 13 = 7(b9,b13)
678 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . -1) (5 . -1)) .
679 ,(raise-some-for-jazz '("7(" "@" "9, " "@" "13)")))
681 ; dominant sharp 9, flat 13 = 7(#9,b13)
682 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . +1) (5 . -1)) .
683 ,(raise-some-for-jazz '("7(" "#" "9, " "@" "13)")))
685 ;; diminished chord(s)
686 ; diminished seventh chord = o
689 ;; DONT use non-ascii characters, even if ``it works'' in Windows
691 ;;(((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ((raise . 0.8) (size . -2) ("o")))
692 (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) .
693 (,super-markup (,simple-markup "o")))
695 ;; half diminshed chords
696 ;; half diminished seventh chord = slashed o
697 ;; (((0 . 0) (2 . -1) (4 . -1) (6 . -1)) . (((raise . 0.8) "/o")))
698 (((0 . 0) (2 . -1) (4 . -1) (6 . -1)) .
699 (,line-markup (,super-markup
700 (,combine-markup (,simple-markup "o") (,simple-markup "/")))
701 (,simple-markup " 7")))
702 ; half diminished seventh chord with major 9 = slashed o cancelation 9
703 (((0 . 0) (2 . -1) (4 . -1) (6 . -1) (1 . 0)) .
704 ,(raise-some-for-jazz '("/o(" "!" "9)")))
706 ;; Missing jazz chord definitions go here (note new syntax: see american for hints)
709 chord::names-alist-american))
711 (define (step->markup-alternate-jazz pitch)
713 (,(accidental-markup (caddr pitch))
714 (,simple-markup (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))))))
716 (define (step->markup-jazz pitch)
717 (if (= (cadr pitch) 6)
719 ;; sharp 7 only included for completeness?
722 (,(accidental-markup -1)
723 (,simple-markup "7"))
725 ((-1) `(,simple-markup "7"))
726 ((0) `(,simple-markup "maj7"))
728 (,(accidental-markup 1)
729 (,simple-markup "7"))))
731 (,(accidental-markup 1)
732 (,simple-markup "7"))))
734 (step->markup-alternate-jazz pitch)))
736 (define (xchord::additions->markup-jazz additions subtractions)
737 (if (pair? additions)
739 (let ((step (step->markup-jazz (car additions))))
740 (if (or (pair? (cdr additions))
741 (pair? subtractions))
742 (list step (list simple-markup "/"))
744 (chord::additions->markup-jazz (cdr additions) subtractions))
748 (define (chord::>5? x)
754 ;; Perhaps all logic like this should be done earlier,
755 ;; so that in this markup-construction printing phase
756 ;; we can just blindly create markup from all additions.
758 ;; This depends maybe on the fact of code sharing,
759 ;; in this layout, we can share the functions chord::additions
760 ;; and chord::subtractions with banter.
761 (define (chord::additions->markup-jazz additions subtractions)
765 ,(chord::additions<=5->markup-jazz (filter-out-list chord::>5? additions)
766 (filter-out-list chord::>5? subtractions))
767 ,(chord::additions>5->markup-jazz (filter-list chord::>5? additions)
768 (filter-list chord::>5? subtractions)))))
773 (define (chord::additions<=5->markup-jazz additions subtractions)
774 (let ((sus (chord::sus-four-jazz additions)))
776 `(,line-markup ((,simple-markup "sus")
777 ,(step->markup-jazz (car sus))))
782 (define (chord::additions>5->markup-jazz additions subtractions)
784 Compose markup of all additions
786 * if there's a subtraction:
788 - list all up to highest
789 * list all steps that are below an chromatically altered step
793 (,(if (not (null? subtractions))
794 `(,simple-markup "add")
798 `(,simple-markup "fixme")
799 ;; this is totally incomprehensible. Fix me, and docme.
801 ((radds (reverse additions)))
803 (reverse (chord::additions>5->markup-jazz-helper
806 (if (or (null? subtractions) (null? radds))
813 (define (chord::additions>5->markup-jazz-helper additions subtractions list-step)
815 Create markups for all additions
816 If list-step != #f, list all steps down to 5
817 If we encounter a chromatically altered step, turn on list-step
821 (if (not (member list-step subtractions))
822 (if (> 5 (cadr list-step))
823 (cons (step->markup-jazz list-step)
824 (chord::additions>5->markup-jazz-helper
827 (chord::get-create-step additions
828 (- (cadr list-step) 2))))
829 (step->markup-jazz list-step))
830 (chord::get-create-step additions (- (cadr list-step) 2)))
831 (if (pair? additions)
832 (let ((step (car additions)))
833 (cons (step->markup-jazz step)
834 (chord::additions>5->markup-jazz-helper
837 (if (or (and (!= 6 (cadr step)) (!= 0 (caddr step)))
838 (and (= 6 (cadr step)) (!= -1 (caddr step))))
839 (chord::get-create-step additions (- (cadr step) 2))
843 (define (chord::sus-four-jazz chord-pitches)
844 "List of pitches that are step 2 or step 4"
846 (filter-list (lambda (x)
848 (or (= 1 (cadr x)) (= 3 (cadr x))))) chord-pitches))
850 (define (chord::get-create-step steps n)
851 (let* ((i (if (< n 0) (+ n 7) n))
852 (found (filter-list (lambda (x) (= i (cadr x))) steps)))
859 (define (chord::subtractions->markup-jazz subtractions)
860 (if (pair? subtractions)
862 (,(if (= 5 (cadr (car subtractions)))
864 ((,simple-markup "omit")
867 ((step (step->markup-jazz (car subtractions))))
868 (if (pair? (cdr subtractions))
869 `(,line-markup ( step (,simple-markup "/")))
872 ,(chord::subtractions->markup-jazz (cdr subtractions))))
875 ;; TODO: maybe merge with inner-name-banter
876 ;; Combine tonic, exception-part of chord name,
877 ;; additions, subtractions and bass or inversion into chord name
878 (define (chord::inner-name-jazz tonic exception-part additions subtractions
879 bass-and-inversion steps)
882 ,(pitch->chord-name-markup-banter tonic steps)
884 ;; why does list->string not work, format seems only hope...
885 ,(if (and (string-match "super" (format "~s" exception-part))
886 (or (pair? additions)
887 (pair? subtractions)))
888 (list super-markup (list simple-markup "/"))
896 ,(chord::additions->markup-jazz additions subtractions)
897 ,(chord::subtractions->markup-jazz subtractions))))
899 ,(chord::bass-and-inversion->markup-banter bass-and-inversion))))
901 ;; Jazz style--basically similar to american with minor changes
903 ;; Consider Dm6. When we get here:
904 ;; tonic = '(0 1 0) (note d=2)
905 ;; steps = '((0 0 0) '(0 2 -1) (0 4 0) (0 5 0))
906 ;; steps are transposed for tonic c, octave 0,
907 ;; so (car steps) is always (0 0 0)
909 ;; assuming that the exceptions-alist has an entry
910 ;; '(((0 . 0) (2 . -1)) . ("m"))
911 ;; (and NOT the full chord, like std jazz list, ugh)
912 ;; unmatch = '((0 0 0) (0 2 0) (0 4 0) (0 5 0))
915 ;; You can look very easily what happens, if you add some write-me calls,
916 ;; and run lilypond on a simple file, eg, containing only the chord c:m6:
918 ;; (let ((additions (write-me "adds: "
919 ;; (chord::additions (write-me "unmatched:"
920 ;; unmatched-steps))))
922 ;; If you set subtract #f, the chord::inner-name-jazz does not see any
923 ;; subtractions, ever, so they don't turn up in the chord name.
925 (define-public (chord::name-jazz tonic exception-part unmatched-steps
926 bass-and-inversion steps)
927 (let ((additions (chord::additions unmatched-steps))
928 ;; get no 'omit' or 'no'
929 ;; (subtractions #f))
930 (subtractions (chord::subtractions unmatched-steps)))
932 (chord::inner-name-jazz tonic exception-part additions subtractions
933 bass-and-inversion steps)))
935 ;; wip (set! chord::names-alist-jazz
936 (define chord::names-alist-jazz
939 (((0 . 0) (2 . -1)) . (,simple-markup "m"))
941 ;; some fixups -- jcn
942 ; major seventh chord = triangle
943 (((0 . 0) (2 . 0) (4 . 0) (6 . 0)) .
944 (,raise-markup 0.5 ,mathm-markup-object))
946 ;; minor major seventh chord = m triangle
947 (((0 . 0) (2 . -1) (4 . 0) (6 . 0)) .
948 (,line-markup ((,simple-markup "m")
949 (,raise-markup 0.5 ,mathm-markup-object))))
950 ;; (((0 . 0) (2 . -1) (4 . 0) (6 . 0)) . (columns ("m") ((raise . 0.5)((font-family . math) "M"))))
954 chord::names-alist-american))
956 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
959 (define-public (new-chord-name-brew-molecule grob)
962 (style-prop (ly:get-grob-property grob 'style))
963 (style (if (symbol? style-prop) style-prop 'banter))
964 (chord (ly:get-grob-property grob 'chord))
965 (chordf (ly:get-grob-property grob 'chord-name-function))
966 (ws (ly:get-grob-property grob 'word-space))
967 (markup (chordf style chord))
968 (molecule (interpret-markup grob
969 (cons '((word-space . 0.0))
970 (Font_interface::get_property_alist_chain grob))
975 ;;; TODO: BUG : word-space is in local staff-space (?)
977 (ly:combine-molecule-at-edge molecule
978 X RIGHT (ly:make-molecule "" (cons 0 ws) '(-1 . 1) )