Invert notes in a chord
A set of functions to:
- drop notes in a chord (like jazz drop2),
- rise notes in a chord
- invert chords
\version "2.24.0"
#(define-public (move-chord-note n direction)
(_i "Transpose a note (numbered as @var{n}) by one octave in
@var{direction}.")
(lambda (music)
(let* ((elts (ly:music-property music 'elements))
(l (length elts))
;; if direction is up, count from the bottom note upward,
;; if direction is down, count from the top note downward.
(count-from (cond ((= direction UP) (- n 1))
((= direction DOWN) (- l n))))
;; Notes may not have been entered from bottom to top;
;; extract the pitches and their possible octavation.
(pitches (map
(lambda (x)
(let ((oct (ly:music-property x 'octavation))
(p (ly:music-property x 'pitch)))
(if (null? oct) p
(ly:pitch-transpose p
(ly:make-pitch oct 0 0)))))
(filter
(lambda (y)
(music-is-of-type? y 'note-event))
elts))))
(if (and (music-is-of-type? music 'event-chord)
(not (zero? n)) (>= l n))
(begin
;; Sort the actual notes, depending on their pitch.
(set! elts
(sort elts
(lambda (a b)
(ly:pitch<?
(ly:music-property a 'pitch)
(ly:music-property b 'pitch)))))
;; then transpose the note up or
;; down, depending on direction.
(let* ((note (list-ref elts count-from))
(oct (ly:music-property note 'octavation)))
(list-set! elts count-from
(ly:music-transpose note
(ly:make-pitch
(cond
((= direction UP) +1)
((= direction DOWN) -1))
0)))
(ly:music-set-property! note 'octavation
(+ (cond
((= direction UP) 1)
((= direction DOWN) -1))
(if (null? oct) 0 oct))))))
music)))
%% drop a note of a chord, in num position from above
dropNote =
#(define-music-function (num music) (integer? ly:music?)
(_i "Drop a note of any chords in @var{music}, in @var{num} position from
above.")
(music-map (move-chord-note num down) music))
%% rise a note of a chord, in num position from below
riseNote =
#(define-music-function (num music) (integer? ly:music?)
(_i "Rise a note of any chords in @var{music}, in @var{num} position from
below.")
(music-map (move-chord-note num up) music))
%% invert chords
invertChords =
#(define-music-function (num music) (integer? ly:music?)
(_i "Invert any chords in @var{music} into their @var{num}-th position.
(Chord inversions may be directed downwards using negative integers.)")
(let loop ((num num) (music music))
(cond ((zero? num) music)
((negative? num)
(loop
(1+ num)
((ly:music-function-extract dropNote) 1 music)))
(else
(loop
(1- num)
((ly:music-function-extract riseNote) 1 music))))))
ac = \relative c' {
<c es g bes>2
<d as' f c'>
\chordmode {c:maj es:6} %work also with chordmode
}
{
<>^\markup "chords"
\ac
\bar "||"
<>^\markup "drop 2"
\dropNote 2 \ac
\bar "||"
<>^\markup "drop 4"
\dropNote 4 \ac
\bar "||"
<>^\markup "drop 2 and 4"
\dropNote 2 \dropNote 4 \ac
\bar "||"
<>^\markup "rise 1"
\riseNote 1 \ac
\bar "||"
<>^\markup "rise 3"
\riseNote 3 \ac
\bar "||"
<>^\markup "2nd inversion"
\invertChords 2 \ac
\bar "||"
<>^\markup "\"down\" inversion"
\invertChords -1 \ac
\bar "||"
}