lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: slash-only chords


From: jerome talkington
Subject: Re: slash-only chords
Date: Tue, 4 Jan 2022 11:51:44 -0800

Harm,

Thanks so much for sharing and tightening up this code for hiding redundant bass notes in successive slash chords, and thanks Elaine Alt for initiating the thread. It's a really useful feature to have in a leadsheet, and one I had been hoping was possible in Lilypond without too much trouble. Much appreciated!

LT

Am So., 2. Jan. 2022 um 09:06 Uhr schrieb Flaming Hakama by Elaine
<ela...@flaminghakama.com>:
>
> On Fri, Dec 31, 2021 at 8:07 AM Thomas Morley <thomasmorle...@gmail.com> 
> wrote:

>> How about:
[...]

> Yes, thanks, this works well if the initial chord is a minor chord.
>
> What would it take to have it work when the initial chord has a 7th?
>
> For other chord types, it seems to hide the root, but print the rest of the 
> chord symbol.

Thanks spotting this, it means the whole approach changing
chordRootNamer is insufficient.

> Perhaps, in this block it would be possible to set additional properties 
> related to other parts of the chord symbol to ""?

Regrettable: no.

> I wasn't able to guess what those might be.
> Are they listed somewhere?

Well, all context-properties are listed in IR.
You can observe the default settings their as well (alphabetical
listed, see context Score)
In /ly/engraver-init.ly they are thematical ordered.
But none of them will help here, afaict.

Instead please try the attached file - recreating the chords text, if
conditions are matched.

Cheers,
  Harm
\version "2.23.5"

#(define Bass_changes_equal_root_engraver
  (lambda (ctx)
  "For sequential ChordNames with same root, but different bass, the root markup
is dropped: D D/C D/B  -> D /C /B
The behaviour may be controlled by setting the chordChanges context-property."
    (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, respect user setting if already done
            (ly:context-set-property! ctx 'chordNoteNamer
              (if (procedure? chord-note-namer)
                  chord-note-namer
                  note-name->markup))))
        (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)))
            ;; Collect notes of the chord
            ;;  - to compare inversed chords we need to collect the bass note
            ;;    as usual member of the chord, whereas an added bass must be
            ;;    treated separate from the usual chord-notes
            ;;  - notes are stored as pairs containing their
            ;;    pitch-name (an integer), i.e. disregarding their octave and
            ;;    their alteration
            (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,
              ;; reset the 'text-property.
              ;; Equality is done 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.
              ;; `chord-changes' needs to be true
              (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
>>

myChords = \chordmode {
  %\germanChords
  %\set chordNameLowercaseMinor = ##t
  \set chordChanges = ##t
  des2 des/cis
  d2:m d:m/cis

  d2:m7 d:m7/c

  d d/cis

  d:maj7 d:maj7/cis \break

  d:7 d:7/c

  d:m7.5- d:m7.5-/c

  d:aug d:aug/c

  d:aug7 d:aug7/c \break


  \set chordChanges = ##f
  d:m/b e:7
  \set chordChanges = ##t
  e1
  \break
  \once \set chordChanges = ##f
  e2/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
>>

reply via email to

[Prev in Thread] Current Thread [Next in Thread]