Impression de noms d’accords identiques à la basse différente par une oblique et nouvelle basse
Voici comment imprimer une suite d’accords nommés (objets
ChordNames) dont seule la basse diffère, indiquée par une oblique
et cette nouvelle basse, à l’aide du graveur Scheme ici défini. Son
comportement peut se gérer finement à l’aide de la propriété de contexte
chordChanges.
#(define Bass_changes_equal_root_engraver (lambda (ctx) "Drop root for follow-up chord names that differ only in bass. In other words, the chord name sequence 'D D/C D/B' gets actually printed as 'D /C /B'. Set the `chordChanges` context property to `#t` to activate this feature." (let ((chord-pitches '()) (last-chord-pitches '()) (bass-pitch #f)) (make-engraver ((initialize this-engraver) (let ((chord-note-namer (ly:context-property ctx 'chordNoteNamer))) ;; Set `chordNoteNamer`, respecting user setting if already ;; done. (ly:context-set-property! ctx 'chordNoteNamer (if (procedure? chord-note-namer) chord-note-namer (chord-name:markup #f))))) (listeners ((note-event this-engraver event) (let* ((pitch (ly:event-property event 'pitch)) (pitch-name (ly:pitch-notename pitch)) (pitch-alt (ly:pitch-alteration pitch)) (bass (ly:event-property event 'bass #f)) (inversion (ly:event-property event 'inversion #f))) ;; We look at the `bass` and `inversion` event properties ;; to decide how to handle the current note event. If ;; `inversion` is set we add the bass note to the chord as ;; an ordinary member so that we can compare inversed ;; chords; if `bass` is set the bass note is not added to ;; the chord. ;; ;; In the `chord-pitches` list we actually collect only ;; the notes' pitch names (which are integers) and pitch ;; alterations as pairs, ignoring the octave. (cond (bass (set! bass-pitch pitch)) (inversion (set! bass-pitch pitch) (set! chord-pitches (cons (cons pitch-name pitch-alt) chord-pitches))) (else (set! chord-pitches (cons (cons pitch-name pitch-alt) chord-pitches))))))) (acknowledgers ((chord-name-interface this-engraver grob source-engraver) (let ((chord-changes (ly:context-property ctx 'chordChanges #f))) ;; If subsequent chords are equal apart from their bass, ;; we change the `text` property to print only the slash ;; and the bass note (via the formatter stored in the ;; `chordNoteNamer` context property). ;; ;; Equality is tested by comparing the sorted lists of ;; this chord's elements and the previous chord. Sorting ;; is needed because inverted chords may have a different ;; order of pitches. Note that we only do a simplified ;; sorting using the pitch name, ignoring the alteration. (if (and bass-pitch chord-changes (equal? (sort chord-pitches car<) (sort last-chord-pitches car<))) (ly:grob-set-property! grob 'text (make-line-markup (list (ly:context-property ctx 'slashChordSeparator) ((ly:context-property ctx 'chordNoteNamer) bass-pitch (ly:context-property ctx 'chordNameLowercaseMinor)))))) (set! last-chord-pitches chord-pitches) (set! chord-pitches '()) (set! bass-pitch #f)))) ((finalize this-engraver) (set! last-chord-pitches '())))))) myChords = \chordmode { % \germanChords \set chordChanges = ##t d2:m d:m/cis d:m/c \set chordChanges = ##f d:m/b e1:7 \set chordChanges = ##t e \break \once \set chordChanges = ##f e1/f e2/gis e/+gis e e:m/f d:m d:m/cis d:m/c \set chordChanges = ##f d:m/b } << \new ChordNames \with { \consists #Bass_changes_equal_root_engraver } \myChords \new Staff \myChords >>