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 (write-me x) (write x) (newline) x)
20 (define (write-me 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) )
30 - Pitches are musical objects. The pitches -> markup step should
31 happen earlier (during interpreting), brew-molecule () should only
32 dump reinterpret the markup as a molecule. " ; "
35 ;; pitch = (octave notename alteration)
37 ;; note = (notename . alteration)
39 ;; text = scm markup text -- see font.scm and input/test/markup.ly
44 ;; Ugh : naming chord::... ; this is scheme not C++
46 ;; * easier tweakability:
47 ;; - split chord::names-alists up into logical bits,
48 ;; such as chord::exceptions-delta, exceptions-oslash
49 ;; - iso just the 'style parameter, use a list, eg:
50 ;; \property ChordNames.ChordName \set
51 ;; #'style = #'(jazz delta oslash german-tonic german-Bb)
55 ;; * clean split/merge of bass/banter/american stuff
59 (define chord::names-alist-banter
62 (((0 . 0)) . ,empty-markup)
64 (((0 . 0) (2 . 0)) . ,empty-markup)
66 (((0 . 0) (2 . -1)) . (,simple-markup "m"))
68 (((0 . 0) (1 . 0) (4 . 0)) . (,super-markup (,simple-markup "2 ")))
70 (((0 . 0) (3 . 0) (4 . 0)) . (,super-markup (,simple-markup "4 ")))
72 (((0 . 0) (2 . -1) (4 . -1)) . (,simple-markup "dim"))
73 ; URG: Simply C:m5-/maj7 iso Cdim maj7
74 (((0 . 0) (2 . -1) (4 . -1) (6 . 0)) . (,line-markup ((,simple-markup "m") (,super-markup (,simple-markup "5-/maj7 ")))))
75 ; URG: Simply C:m5-/7 iso Cdim7
76 (((0 . 0) (2 . -1) (4 . -1) (6 . -1)) . (,line-markup ((,simple-markup "m") (,super-markup (,simple-markup "5-/7 ")))))
78 (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . (,super-markup (,simple-markup "o ")))
80 (((0 . 0) (2 . -1) (4 . -1) (6 . -2) (1 . -1)) . (,line-markup ((,simple-markup "dim")
81 (,simple-markup "9 "))))
82 (((0 . 0) (2 . -1) (4 . -1) (6 . -2) (1 . -1) (3 . -1))
83 . (,line-markup ((,simple-markup "dim")
84 (,super-markup (,simple-markup "11 ")))))
90 (define (pitch->note-name pitch)
91 (cons (cadr pitch) (caddr pitch)))
93 (define (accidental-markup acc)
94 "ACC is an int, return a markup making an accidental."
96 `(,line-markup (,empty-markup))
97 `(,smaller-markup (,musicglyph-markup
98 ,(string-append "accidentals-"
99 (number->string acc))))))
101 (define (pitch->markup pitch)
105 ,(make-string 1 (integer->char (+ (modulo (+ (cadr pitch) 2) 7) 65))))
106 (,normal-size-superscript-markup
107 ,(accidental-markup (caddr pitch))))))
109 ;;; Hooks to override chord names and note names,
110 ;;; see input/tricks/german-chords.ly
112 (define pitch->markup-banter pitch->markup)
114 ;; We need also steps, to allow for Cc name override,
115 ;; see input/test/Cc-chords.ly
116 (define (pitch->chord-name-markup-banter pitch steps)
117 (pitch->markup-banter pitch))
119 (define pitch->note-name-markup-banter pitch->markup-banter)
121 (define (step->markup pitch)
123 (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))
131 (define (step->markup-banter pitch)
133 (if (= (cadr pitch) 6)
140 (step->markup pitch))))
142 (define pitch::semitone-vec #(0 2 4 5 7 9 11))
144 (define (pitch::semitone pitch)
145 (+ (* (car pitch) 12)
146 (vector-ref pitch::semitone-vec (modulo (cadr pitch) 7))
149 (define (pitch::< l r)
150 (< (pitch::semitone l) (pitch::semitone r)))
152 (define (pitch::transpose pitch delta)
153 (let ((simple-octave (+ (car pitch) (car delta)))
154 (simple-notename (+ (cadr pitch) (cadr delta))))
155 (let ((octave (+ simple-octave (quotient simple-notename 7)))
156 (notename (modulo simple-notename 7)))
157 (let ((accidental (- (+ (pitch::semitone pitch) (pitch::semitone delta))
158 (pitch::semitone `(,octave ,notename 0)))))
159 `(,octave ,notename ,accidental)))))
161 (define (pitch::diff pitch tonic)
162 (let ((simple-octave (- (car pitch) (car tonic)))
163 (simple-notename (- (cadr pitch) (cadr tonic))))
164 (let ((octave (+ simple-octave (quotient simple-notename 7)
165 (if (< simple-notename 0) -1 0)))
166 (notename (modulo simple-notename 7)))
167 (let ((accidental (- (pitch::semitone pitch)
168 (pitch::semitone tonic)
169 (pitch::semitone `(,octave ,notename 0)))))
170 `(,octave ,notename ,accidental)))))
172 (define (pitch::note-pitch pitch)
173 (+ (* (car pitch) 7) (cadr pitch)))
175 ;; markup: list of word
176 ;; word: string + optional list of property
177 ;; property: axis, kern, font (?), size
179 (define chord::minor-major-vec (list->vector '(0 -1 -1 0 -1 -1 0)))
182 ;; compute the relative-to-tonic pitch that goes with 'step'
183 (define (chord::step-pitch tonic step)
184 ;; urg, we only do this for thirds
185 (if (= (modulo step 2) 0)
187 (let loop ((i 1) (pitch tonic))
191 pitch `(0 2 ,(vector-ref chord::minor-major-vec
192 ;; -1 (step=1 -> vector=0) + 7 = 6
193 (modulo (+ i 6) 7)))))))))
195 (define (chord::additions steps)
197 * any even step (2, 4, 6)
198 * any uneven step that is chromatically altered,
199 (where 7-- == -1, 7- == 0, 7 == +1)
202 ?and jazz needs also:
204 * TODO: any uneven step that's lower than an uneven step which is
205 chromatically altered
207 (let ((evens (filter-list (lambda (x) (!= 0 (modulo (cadr x) 2))) steps))
209 (filter-list (lambda (x)
210 (let ((n (cadr x)) (a (caddr x)))
211 (or (and (= 6 n) (!= -1 a))
216 (highest (let ((h (car (last-pair steps))))
217 (if (and (not (null? h))
222 ;; Hmm, what if we have a step twice, can we ignore that?
223 (uniq-list (sort (apply append evens altered-unevens highest)
227 ;; FIXME: unLOOP, see ::additions
228 ;; find the pitches that are missing from `normal' chord
229 (define (chord::subtractions chord-pitches)
230 (let ((tonic (car chord-pitches)))
231 (let loop ((step 1) (pitches chord-pitches) (subtractions '()))
233 (let* ((pitch (car pitches))
234 (p-step (+ (- (pitch::note-pitch pitch)
235 (pitch::note-pitch tonic))
237 ;; pitch is an subtraction if
238 ;; a step is missing or
240 (loop (+ step 2) pitches
241 (cons (chord::step-pitch tonic step) subtractions))
242 ;; there are no pitches left, but base thirds are not yet done and
244 (= (length pitches) 1))
245 ;; present pitch is not missing step
247 (loop (+ step 2) pitches subtractions)
248 (loop (+ step 2) pitches
249 (cons (chord::step-pitch tonic step) subtractions)))
251 (loop (+ step 2) (cdr pitches) subtractions)
252 (loop step (cdr pitches) subtractions)))))
253 (reverse subtractions)))))
255 (define (chord::additions->markup-banter additions subtractions)
256 (if (pair? additions)
259 (let ((step (step->markup-banter (car additions))))
260 (if (or (pair? (cdr additions))
261 (pair? subtractions))
263 (list step (list simple-markup "/")))
266 (chord::additions->markup-banter (cdr additions) subtractions)))
270 (define (chord::subtractions->markup-banter subtractions)
271 (if (pair? subtractions)
273 ((,simple-markup "no")
274 ,(let ((step (step->markup-jazz (car subtractions))))
275 (if (pair? (cdr subtractions))
276 `(,line-markup (,step (,simple-markup "/")))
278 ,(chord::subtractions->markup-banter (cdr subtractions))))
282 (define (chord::bass-and-inversion->markup-banter bass-and-inversion)
283 (if (and (pair? bass-and-inversion)
284 (or (car bass-and-inversion)
285 (cdr bass-and-inversion)))
289 ,(pitch->note-name-markup-banter
290 (if (car bass-and-inversion)
291 (car bass-and-inversion)
292 (cdr bass-and-inversion)))
297 ;; FIXME: merge this function with inner-name-jazz, -american
298 ;; iso using chord::bass-and-inversion->markup-banter,
299 ;; call (chord::restyle 'chord::bass-and-inversion->markup- style)
300 ;; See: chord::exceptions-lookup
301 (define (chord::inner-name-banter tonic exception-part additions subtractions
302 bass-and-inversion steps)
307 Combine tonic, exception-part of chord name,
308 additions, subtractions and bass or inversion into chord name
311 (let* ((tonic-markup (pitch->chord-name-markup-banter tonic steps))
314 (if exception-part exception-part empty-markup)) ;;`(,simple-markup "")))
315 (sep-markup (list simple-markup
316 (if (and (string-match "super"
317 (format "~s" except-markup))
318 (or (pair? additions)
319 (pair? subtractions)))
321 (adds-markup (chord::additions->markup-banter additions subtractions))
322 (subs-markup (chord::subtractions->markup-banter subtractions))
323 (b+i-markup (chord::bass-and-inversion->markup-banter
324 bass-and-inversion)))
331 (,line-markup (,adds-markup ,subs-markup))
337 (define (c++-pitch->scm p)
339 (list (ly:pitch-octave p) (ly:pitch-notename p) (ly:pitch-alteration p))
342 (define (chord::name-banter tonic exception-part unmatched-steps
343 bass-and-inversion steps)
344 (let ((additions (chord::additions unmatched-steps))
345 (subtractions (chord::subtractions unmatched-steps)))
347 (chord::inner-name-banter tonic exception-part additions subtractions
348 bass-and-inversion steps)))
351 (define chord-module (current-module))
352 (define (chord::restyle name style)
356 (string-append (symbol->string name)
357 (symbol->string style)))
362 ;; this is unintelligible.
366 ; - what's a helper, and why isn't it inside another function?
368 ; what is going out, what is coming in, howcome it produces #f
372 (define (chord::exceptions-lookup-helper
373 exceptions-alist try-steps unmatched-steps exception-part)
376 check exceptions-alist for biggest matching part of try-steps
377 return (MATCHED-EXCEPTION . UNMATCHED-STEPS)
380 (if (pair? try-steps)
381 ;; FIXME: junk '(0 . 0) from exceptions lists?
382 ;; if so: how to handle first '((0 . 0) . #f) entry?
384 ;; FIXME: either format exceptions list as real pitches, ie,
385 ;; including octave '((0 2 -1) ..), or drop octave
386 ;; from rest of calculations,
388 (map (lambda (x) (pitch->note-name x))
389 (append '((0 0 0)) try-steps))
392 (chord::exceptions-lookup-helper
393 #f '() unmatched-steps (cdr entry))
394 (let ((r (reverse try-steps)))
395 (chord::exceptions-lookup-helper
398 (cons (car r) unmatched-steps) #f))))
399 (cons exception-part unmatched-steps)))
403 (define (chord::exceptions-lookup style steps)
405 return (MATCHED-EXCEPTION . BASE-CHORD-WITH-UNMATCHED-STEPS)
406 BASE-CHORD-WITH-UNMATCHED-STEPS always includes (tonic 3 5)
410 (let* ((result (chord::exceptions-lookup-helper
411 (chord::restyle 'chord::names-alist- style)
413 (exception-part (car result))
414 (unmatched-steps (cdr result))
415 (matched-steps (if (= (length unmatched-steps) 0)
417 (+ 1 (- (length steps)
418 (length unmatched-steps)))))
419 (unmatched-with-1-3-5
420 (append (do ((i matched-steps (- i 1))
421 (base '() (cons `(0 ,(* (- i 1) 2) 0) base)))
425 (list exception-part unmatched-with-1-3-5)))
428 (define (chord::name->markup style tonic steps bass-and-inversion)
431 (let* ((lookup (write-me (chord::exceptions-lookup style steps)))
432 (exception-part (write-me (car lookup)))
433 (unmatched-steps (cadr lookup))
434 (func (chord::restyle 'chord::name- style))
438 (func tonic exception-part unmatched-steps bass-and-inversion steps)))
442 ;; Check for each subset of chord, full chord first, if there's a
443 ;; user-override. Split the chord into user-overridden and to-be-done
444 ;; parts, complete the missing user-override matched part with normal
445 ;; chord to be name-calculated.
447 ;; CHORD: (pitches (bass . inversion))
448 (define-public (chord->markup style chord)
449 (let* ((pitches (map c++-pitch->scm (car chord)))
450 (modifiers (cdr chord))
451 (bass-and-inversion (if (pair? modifiers)
452 (cons (c++-pitch->scm (car modifiers))
453 (c++-pitch->scm (cdr modifiers)))
455 (diff (pitch::diff '(0 0 0) (car pitches)))
456 (steps (if (cdr pitches) (map (lambda (x)
457 (pitch::transpose x diff))
461 (chord::name->markup style (car pitches) steps bass-and-inversion)
469 ;; NOTE: Duplicates of chord names defined elsewhere occur in this list
470 ;; in order to prevent spurious superscripting of various chord names,
471 ;; such as maj7, maj9, etc.
473 ;; See input/test/american-chords.ly
475 ;; James Hammons, <jlhamm@pacificnet.net>
478 ;; DONT use non-ascii characters, even if ``it works'' in Windows
481 (define chord::names-alist-american
484 (((0 . 0)) . ,empty-markup)
485 (((0 . 0) (2 . 0)) . ,empty-markup)
487 (((0 . 0) (4 . 0)) . (,simple-markup "5"))
489 (((0 . 0) (2 . -1)) . (,simple-markup "m"))
490 (((0 . 0) (3 . 0) (4 . 0)) . (,simple-markup "sus"))
491 (((0 . 0) (2 . -1) (4 . -1)) . (,simple-markup "dim"))
492 ;Alternate: (((0 . 0) (2 . -1) (4 . -1)) . ("" (super "o")))
493 (((0 . 0) (2 . 0) (4 . 1)) . (,simple-markup "aug"))
494 ;Alternate: (((0 . 0) (2 . 0) (4 . 1)) . ("+"))
495 (((0 . 0) (1 . 0) (4 . 0)) . (,simple-markup "2"))
496 ;; Common seventh chords
497 (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) .
499 ((,super-markup (,simple-markup "o"))
500 (,simple-markup " 7"))))
501 (((0 . 0) (2 . 0) (4 . 0) (6 . 0)) . (,simple-markup "maj7"))
502 ;; urg! should use (0 . 0 2 . -1) -> "m", and add "7" to that!!
503 (((0 . 0) (2 . -1) (4 . 0) (6 . -1)) . (,simple-markup "m7"))
504 (((0 . 0) (2 . 0) (4 . 0) (6 . -1)) . (,simple-markup "7"))
505 (((0 . 0) (2 . -1) (4 . 0) (6 . 0)) . (,simple-markup "m(maj7)"))
506 ;jazz: the delta, see jazz-chords.ly
507 ;;(((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . (super ((font-family . math) "N"))
509 (((0 . 0) (2 . -1) (4 . -1) (6 . -1)) .
512 (,combine-markup (,simple-markup "o")
513 (,simple-markup "/")))
514 (,simple-markup " 7"))))
515 (((0 . 0) (2 . 0) (4 . 1) (6 . -1)) . (,simple-markup "aug7"))
516 (((0 . 0) (2 . 0) (4 . -1) (6 . 0))
518 ((,simple-markup "maj7")
519 (,small-markup (,raise-markup 0.2 ,(accidental-markup -1)))
520 (,simple-markup "5"))))
521 (((0 . 0) (2 . 0) (4 . -1) (6 . -1)) .
523 ((,simple-markup "7")
524 (,small-markup (,raise-markup 0.2 ,(accidental-markup -1)))
525 (,simple-markup "5"))))
526 (((0 . 0) (3 . 0) (4 . 0) (6 . -1)) . (,simple-markup "7sus4"))
527 ;; Common ninth chords
528 (((0 . 0) (2 . 0) (4 . 0) (5 . 0) (1 . 0)) . (,simple-markup "6/9")) ;; we don't want the '/no7'
529 (((0 . 0) (2 . 0) (4 . 0) (5 . 0)) . (,simple-markup "6"))
530 (((0 . 0) (2 . -1) (4 . 0) (5 . 0)) . (,simple-markup "m6"))
531 (((0 . 0) (2 . 0) (4 . 0) (1 . 0)) . (,simple-markup "add9"))
532 (((0 . 0) (2 . 0) (4 . 0) (6 . 0) (1 . 0)) . (,simple-markup "maj9"))
533 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . 0)) . (,simple-markup "9"))
534 (((0 . 0) (2 . -1) (4 . 0) (6 . -1) (1 . 0)) . (,simple-markup "m9"))
538 ;; American style chordnames use no "no",
539 ;; but otherwise very similar to banter for now
540 (define-public (chord::name-american tonic exception-part unmatched-steps
541 bass-and-inversion steps)
542 (let ((additions (chord::additions unmatched-steps))
544 (chord::inner-name-banter tonic exception-part additions subtractions
545 bass-and-inversion steps)))
553 ;; Jazz chords, by Atte Andr'e Jensen <atte@post.com>
554 ;; NBs: This uses the american list as a bass.
555 ;; Some defs take up more than one line,
556 ;; be carefull when messing with ;'s!!
561 ;; This is getting out-of hand? Only exceptional chord names that
562 ;; cannot be generated should be here.
563 ;; Maybe we should have inner-name-jazz and inner-name-american functions;
567 ;; DONT use non-ascii characters, even if ``it works'' in Windows
569 (define mathm-markup-object `(,override-markup (font-family . math) (,simple-markup "M")))
570 (define mraise-arg `(,line-markup
571 ((,simple-markup "m")
572 (,raise-markup 0.5 (,simple-markup arg)))))
574 (define (raise-some-for-jazz arg-list)
577 ("@" `(,raise-markup 0.3 ,(accidental-markup -1)))
578 ("#" `(,raise-markup 0.3 ,(accidental-markup 1)))
579 (else `(,raise-markup 0.8 ,x))))
581 `(line-markup ,(map do-one arg-list)))
583 (define chord::names-alist-jazz
587 ; major sixth chord = 6
588 (((0 . 0) (2 . 0) (4 . 0) (5 . 0)) .
589 (,raise-markup 0.5 (,simple-markup "6")))
590 ; major seventh chord = triangle
591 ;; shouldn't this be a filled black triange, like this: ? --jcn
592 ;; (((0 . 0) (2 . 0) (4 . 0) (6 . 0)) . (((raise . 0.5)((font-family . math) "N"))))
593 (((0 . 0) (2 . 0) (4 . 0) (6 . 0)) .
599 ; major chord add nine = add9
600 (((0 . 0) (2 . 0) (4 . 0) (1 . 0)) . (,raise-markup 0.5 (,simple-markup "add9")))
601 ; major sixth chord with nine = 6/9
602 (((0 . 0) (2 . 0) (4 . 0) (5 . 0) (1 . 0)) . (,raise-markup 0.5 (,simple-markup "add9")))
605 ; minor sixth chord = m6
606 (((0 . 0) (2 . -1) (4 . 0) (5 . 0)) .
609 ;; minor major seventh chord = m triangle
610 ;; shouldn't this be a filled black triange, like this: ? --jcn
611 ;;(((0 . 0) (2 . -1) (4 . 0) (6 . 0)) . (columns ("m") ((raise . 0.5)((font-family . math) "N"))))
612 (((0 . 0) (2 . -1) (4 . 0) (6 . 0)) .
613 (,line-markup ((,simple-markup "m") ,mathm-markup-object)))
614 ; minor seventh chord = m7
615 (((0 . 0) (2 . -1) (4 . 0) (6 . -1)) . ,(mraise-arg "7"))
616 ; minor sixth nine chord = m6/9
617 (((0 . 0) (2 . -1) (4 . 0) (5 . 0) (1 . 0)) . ,(mraise-arg "6/9"))
619 ; minor with added nine chord = madd9
620 (((0 . 0) (2 . -1) (4 . 0) (1 . 0)) . ,(mraise-arg "madd9"))
622 ; minor ninth chord = m9
623 (((0 . 0) (2 . -1) (4 . 0) (6 . -1) (1 . 0)) . ,(mraise-arg "add9"))
626 ; dominant seventh = 7
627 (((0 . 0) (2 . 0) (4 . 0) (6 . -1)) . (,raise-markup 0.5 (,simple-markup "7")))
628 ; augmented dominant = +7
629 ;(((0 . 0) (2 . 0) (4 . +1) (6 . -1)) . (((raise . 0.5) "+7"))) ; +7 with both raised
630 (((0 . 0) (2 . 0) (4 . +1) (6 . -1)) .
631 (,line-markup ((,simple-markup "+")
632 (,raise-markup 0.5 (,simple-markup "7"))))) ; +7 with 7 raised
633 ;(((0 . 0) (2 . 0) (4 . +1) (6 . -1)) . (columns((raise . 0.5) "7(")
634 ; ((raise . 0.3)(music (named ("accidentals-1"))))
635 ; ((raise . 0.5) "5)"))); 7(#5)
636 ; dominant flat 5 = 7(b5)
638 (((0 . 0) (2 . 0) (4 . -1) (6 . -1)) . ,(raise-some-for-jazz '( "7(" "@" "5)" )))
641 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . 0)) .
642 ,(raise-some-for-jazz '("7(9)")))
643 ; dominant flat 9 = 7(b9)
644 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . -1)) .
645 ,(raise-some-for-jazz '("7(" "@" "9)")))
647 ; dominant sharp 9 = 7(#9)
648 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . +1)) .
649 ,(raise-some-for-jazz '("7(" "#" "9)")))
651 ; dominant 13 = 7(13)
652 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (5 . 0)) .
653 ,(raise-some-for-jazz "7(13)"))
654 ; dominant flat 13 = 7(b13)
655 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (5 . -1)) .
656 ,(raise-some-for-jazz '( "7(" "@" "13)")))
658 ; dominant 9, 13 = 7(9,13)
659 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . 0) (5 . 0)) .
660 ,(raise-some-for-jazz '("7(9, 13)")))
661 ; dominant flat 9, 13 = 7(b9,13)
662 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . -1) (5 . 0)) .
663 ,(raise-some-for-jazz '("7(" "@" "9, 13)")))
665 ; dominant sharp 9, 13 = 7(#9,13)
666 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . +1) (5 . 0)) .
667 ,(raise-some-for-jazz '("7(" "#" "9,13)")))
669 ; dominant 9, flat 13 = 7(9,b13)
670 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . 0) (5 . -1)) .
671 ,(raise-some-for-jazz "7(9, " "@" "13)"))
673 ; dominant flat 9, flat 13 = 7(b9,b13)
674 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . -1) (5 . -1)) .
675 ,(raise-some-for-jazz '("7(" "@" "9, " "@" "13)")))
677 ; dominant sharp 9, flat 13 = 7(#9,b13)
678 (((0 . 0) (2 . 0) (4 . 0) (6 . -1) (1 . +1) (5 . -1)) .
679 ,(raise-some-for-jazz '("7(" "#" "9, " "@" "13)")))
681 ;; diminished chord(s)
682 ; diminished seventh chord = o
685 ;; DONT use non-ascii characters, even if ``it works'' in Windows
687 ;;(((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ((raise . 0.8) (size . -2) ("o")))
688 (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) .
689 (,super-markup (,simple-markup "o")))
691 ;; half diminshed chords
692 ;; half diminished seventh chord = slashed o
693 ;; (((0 . 0) (2 . -1) (4 . -1) (6 . -1)) . (((raise . 0.8) "/o")))
694 (((0 . 0) (2 . -1) (4 . -1) (6 . -1)) .
695 (,line-markup (,super-markup
696 (,combine-markup (,simple-markup "o") (,simple-markup "/")))
697 (,simple-markup " 7")))
698 ; half diminished seventh chord with major 9 = slashed o cancelation 9
699 (((0 . 0) (2 . -1) (4 . -1) (6 . -1) (1 . 0)) .
700 ,(raise-some-for-jazz '("/o(" "!" "9)")))
702 ;; Missing jazz chord definitions go here (note new syntax: see american for hints)
705 chord::names-alist-american))
707 (define (step->markup-alternate-jazz pitch)
709 (,(accidental-markup (caddr pitch))
710 (,simple-markup ,(number->string (+ (cadr pitch)
711 (if (= (car pitch) 0) 1 8)))))))
713 (define (step->markup-jazz pitch)
714 (if (= (cadr pitch) 6)
716 ;; sharp 7 only included for completeness?
719 (,(accidental-markup -1)
720 (,simple-markup "7"))
722 ((-1) `(,simple-markup "7"))
723 ;;;((0) `(,simple-markup "maj7"))
724 ((0) `(,line-markup (,simple-markup "maj7")))
726 (,(accidental-markup 1)
727 (,simple-markup "7"))))
729 (,(accidental-markup 1)
730 (,simple-markup "7"))))
732 (step->markup-alternate-jazz pitch)))
734 (define (xchord::additions->markup-jazz additions subtractions)
735 (if (pair? additions)
737 (let ((step (step->markup-jazz (car additions))))
738 (if (or (pair? (cdr additions))
739 (pair? subtractions))
740 (list step (list simple-markup "/"))
742 (chord::additions->markup-jazz (cdr additions) subtractions))
746 (define (chord::>5? x)
752 ;; Perhaps all logic like this should be done earlier,
753 ;; so that in this markup-construction printing phase
754 ;; we can just blindly create markup from all additions.
756 ;; This depends maybe on the fact of code sharing,
757 ;; in this layout, we can share the functions chord::additions
758 ;; and chord::subtractions with banter.
759 (define (chord::additions->markup-jazz additions subtractions)
763 ,(chord::additions<=5->markup-jazz (filter-out-list chord::>5? additions)
764 (filter-out-list chord::>5? subtractions))
765 ,(chord::additions>5->markup-jazz (filter-list chord::>5? additions)
766 (filter-list chord::>5? subtractions)))))
771 (define (chord::additions<=5->markup-jazz additions subtractions)
772 (let ((sus (chord::sus-four-jazz additions)))
774 `(,line-markup ((,simple-markup "sus")
775 ,(step->markup-jazz (car sus))))
780 (define (chord::additions>5->markup-jazz additions subtractions)
782 Compose markup of all additions
784 * if there's a subtraction:
786 - list all up to highest
787 * list all steps that are below an chromatically altered step
791 (,(if (not (null? subtractions))
792 `(,simple-markup "add")
794 ;; this is totally incomprehensible. Fix me, and docme.
795 ,(let* ((radds (reverse additions))
796 (rmarkups (chord::additions>5->markup-jazz-helper
799 (if (or (null? subtractions) (null? radds))
801 (if (null? rmarkups) empty-markup
802 (car (reverse rmarkups)))))))
804 (define (chord::additions>5->markup-jazz-helper additions subtractions list-step)
806 Create markups for all additions
807 If list-step != #f, list all steps down to 5
808 If we encounter a chromatically altered step, turn on list-step
812 (if (not (member list-step subtractions))
813 (if (> 5 (cadr list-step))
814 (cons (step->markup-jazz list-step)
815 (chord::additions>5->markup-jazz-helper
818 (chord::get-create-step additions
819 (- (cadr list-step) 2))))
820 (step->markup-jazz list-step))
821 (chord::get-create-step additions (- (cadr list-step) 2)))
822 (if (pair? additions)
823 (let ((step (car additions)))
824 (cons (step->markup-jazz step)
825 (chord::additions>5->markup-jazz-helper
828 (if (or (and (!= 6 (cadr step)) (!= 0 (caddr step)))
829 (and (= 6 (cadr step)) (!= -1 (caddr step))))
830 (chord::get-create-step additions (- (cadr step) 2))
834 (define (chord::sus-four-jazz chord-pitches)
835 "List of pitches that are step 2 or step 4"
837 (filter-list (lambda (x)
839 (or (= 1 (cadr x)) (= 3 (cadr x))))) chord-pitches))
841 (define (chord::get-create-step steps n)
842 (let* ((i (if (< n 0) (+ n 7) n))
843 (found (filter-list (lambda (x) (= i (cadr x))) steps)))
850 (define (chord::subtractions->markup-jazz subtractions)
851 (if (pair? subtractions)
853 (,(if (= 5 (cadr (car subtractions)))
855 ((,simple-markup "omit")
858 ((step (step->markup-jazz (car subtractions))))
859 (if (pair? (cdr subtractions))
860 `(,line-markup ( step (,simple-markup "/")))
863 ,(chord::subtractions->markup-jazz (cdr subtractions))))
866 ;; TODO: maybe merge with inner-name-banter
867 ;; Combine tonic, exception-part of chord name,
868 ;; additions, subtractions and bass or inversion into chord name
869 (define (chord::inner-name-jazz tonic exception-part additions subtractions
870 bass-and-inversion steps)
873 ,(pitch->chord-name-markup-banter tonic steps)
875 ;; why does list->string not work, format seems only hope...
876 ,(if (and (string-match "super" (format "~s" exception-part))
877 (or (pair? additions)
878 (pair? subtractions)))
879 (list super-markup (list simple-markup "/"))
887 ,(chord::additions->markup-jazz additions subtractions)
888 ,(chord::subtractions->markup-jazz subtractions))))
890 ,(chord::bass-and-inversion->markup-banter bass-and-inversion))))
892 ;; Jazz style--basically similar to american with minor changes
894 ;; Consider Dm6. When we get here:
895 ;; tonic = '(0 1 0) (note d=2)
896 ;; steps = '((0 0 0) '(0 2 -1) (0 4 0) (0 5 0))
897 ;; steps are transposed for tonic c, octave 0,
898 ;; so (car steps) is always (0 0 0)
900 ;; assuming that the exceptions-alist has an entry
901 ;; '(((0 . 0) (2 . -1)) . ("m"))
902 ;; (and NOT the full chord, like std jazz list, ugh)
903 ;; unmatch = '((0 0 0) (0 2 0) (0 4 0) (0 5 0))
906 ;; You can look very easily what happens, if you add some write-me calls,
907 ;; and run lilypond on a simple file, eg, containing only the chord c:m6:
909 ;; (let ((additions (write-me "adds: "
910 ;; (chord::additions (write-me "unmatched:"
911 ;; unmatched-steps))))
913 ;; If you set subtract #f, the chord::inner-name-jazz does not see any
914 ;; subtractions, ever, so they don't turn up in the chord name.
916 (define-public (chord::name-jazz tonic exception-part unmatched-steps
917 bass-and-inversion steps)
918 (let ((additions (chord::additions unmatched-steps))
919 ;; get no 'omit' or 'no'
920 ;; (subtractions #f))
921 (subtractions (chord::subtractions unmatched-steps)))
923 (chord::inner-name-jazz tonic exception-part additions subtractions
924 bass-and-inversion steps)))
926 ;; wip (set! chord::names-alist-jazz
927 (define chord::names-alist-jazz
930 (((0 . 0) (2 . -1)) . (,simple-markup "m"))
932 ;; some fixups -- jcn
933 ; major seventh chord = triangle
934 (((0 . 0) (2 . 0) (4 . 0) (6 . 0)) .
935 (,raise-markup 0.5 ,mathm-markup-object))
937 ;; minor major seventh chord = m triangle
938 (((0 . 0) (2 . -1) (4 . 0) (6 . 0)) .
939 (,line-markup ((,simple-markup "m")
940 (,raise-markup 0.5 ,mathm-markup-object))))
941 ;; (((0 . 0) (2 . -1) (4 . 0) (6 . 0)) . (columns ("m") ((raise . 0.5)((font-family . math) "M"))))
945 chord::names-alist-american))
947 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
950 (define-public (new-chord-name-brew-molecule grob)
953 (style-prop (ly:get-grob-property grob 'style))
954 (style (if (symbol? style-prop) style-prop 'banter))
955 (chord (ly:get-grob-property grob 'chord))
956 (chordf (ly:get-grob-property grob 'chord-name-function))
957 (ws (ly:get-grob-property grob 'word-space))
958 (markup (chordf style chord))
959 (molecule (interpret-markup grob
960 (cons '((word-space . 0.0))
961 (Font_interface::get_property_alist_chain grob))
966 ;;; TODO: BUG : word-space is in local staff-space (?)
968 (ly:combine-molecule-at-edge molecule
969 X RIGHT (ly:make-molecule "" (cons 0 ws) '(-1 . 1) )