Jump to content

Splitting chords: Difference between revisions

From LilyPond wiki
mNo edit summary
m Formatting, improved docstring
Line 1: Line 1:
This snippet is a 2009 contribution by Gilles Thibault in [https://lists.gnu.org/archive/html/lilypond-user/2009-01/msg00685.html lilypond-user]. It splits a chord sequence into two separated voices: the first one built on the first note (usually the lowest) of every chord and the other on the remaining notes. It works well in 2.24.4 and even in 2.25.35. I find it very useful. It also preserves articulations and slurs. The only drawback: it doesn't work if you use «q» to repeat last chord.  
This snippet is a 2009 contribution by Gilles Thibault in [https://lists.gnu.org/archive/html/lilypond-user/2009-01/msg00685.html lilypond-user]. It provides two functions to split a chord sequence into two separate voices, also preserving articulations and slurs: <code>\keepOnlyFirstNode</code> extracts the first note (as given in the input; this is usually the lowest one) of every chord, and <code>\deleteFirstNote</code> collects the remaining notes.
 
Note that these function don't support <samp>q</samp> to repeat the last chord.


<lilypond version="2.24">
<lilypond version="2.24">
#(define (has-duration? music)
  (ly:duration? (ly:music-property music 'duration)))


#(define (has-duration? music)
#(define (not-has-duration? music)
(ly:duration? (ly:music-property music 'duration)))
  (not (has-duration? music)))
 
#(define (not-has-duration? music)
keepOnlyFirstNote =
(not (has-duration? music)))
#(define-music-function (parser location music) (ly:music?)
  (music-map
keepsOnlyFirstNote = #(define-music-function (parser location music) (ly:music?)
    (lambda (evt)
(music-map
      (when (eq? 'EventChord (ly:music-property evt 'name))
  (lambda (evt)
(let ((elts (ly:music-property evt 'elements)))
  (if (eq? 'EventChord (ly:music-property evt 'name))
  (when (has-duration? (car elts))
      (let ((elts (ly:music-property evt 'elements)))
    (ly:music-set-property!
      (if (has-duration? (car elts))
    evt 'elements
            (ly:music-set-property! evt 'elements (cons
    (cons (car elts)
                (car elts)
  (filter not-has-duration? (cdr elts)))))))
                (filter not-has-duration? (cdr elts)))))))
      evt)
  evt)
    music))
music))
 
deleteFirstNote =
deleteFirstNote = #(define-music-function (parser location music) (ly:music?)
#(define-music-function (parser location music) (ly:music?)
(music-map
  (music-map
  (lambda (evt)
    (lambda (evt)
  (if (eq? 'EventChord (ly:music-property evt 'name))
      (when (eq? 'EventChord (ly:music-property evt 'name))
      (let ((elts (ly:music-property evt 'elements)))
(let ((elts (ly:music-property evt 'elements)))
          (if (has-duration? (car elts))
          (when (has-duration? (car elts))
                (ly:music-set-property! evt 'elements  (cdr elts)))))
            (ly:music-set-property! evt 'elements  (cdr elts)))))
  evt)
      evt)
music))
    music))
 
 
music =\relative c' {
music = \relative c' {
<c e>4-> <d f>( <b g'>) <c e>-. g2 c2
  <c e>4-> <d f>( <b g'>) <c e>-. g2 c2
}
}
 
\markup { Music with chords }
 
\new Staff \music
\markup { Music with chords }
\markup { Music splitted in 2 staffs }
\new Staff \music
<<
 
  \new Staff \deleteFirstNote \music
\markup { Music split into two staffs }
  \new Staff \keepsOnlyFirstNote \music
<<
>>
  \new Staff \deleteFirstNote \music
  \new Staff \keepOnlyFirstNote \music
>>
</lilypond>
</lilypond>


[[category:Chords]]
[[category:Chords]]
[[category:Scheme]]
[[category:Scheme]]
[[category:Really cool]]
[[category:Really cool]]

Revision as of 09:09, 5 April 2026

This snippet is a 2009 contribution by Gilles Thibault in lilypond-user. It provides two functions to split a chord sequence into two separate voices, also preserving articulations and slurs: \keepOnlyFirstNode extracts the first note (as given in the input; this is usually the lowest one) of every chord, and \deleteFirstNote collects the remaining notes.

Note that these function don't support q to repeat the last chord.

\version "2.24"

#(define (has-duration? music)
   (ly:duration? (ly:music-property music 'duration)))

#(define (not-has-duration? music)
   (not (has-duration? music)))

keepOnlyFirstNote =
#(define-music-function (parser location music) (ly:music?)
   (music-map
    (lambda (evt)
      (when (eq? 'EventChord (ly:music-property evt 'name))
	(let ((elts (ly:music-property evt 'elements)))
	  (when (has-duration? (car elts))
	    (ly:music-set-property!
	     evt 'elements
	     (cons (car elts)
		   (filter not-has-duration? (cdr elts)))))))
      evt)
    music))

deleteFirstNote =
#(define-music-function (parser location music) (ly:music?)
   (music-map
    (lambda (evt)
      (when (eq? 'EventChord (ly:music-property evt 'name))
	(let ((elts (ly:music-property evt 'elements)))
          (when (has-duration? (car elts))
            (ly:music-set-property! evt 'elements  (cdr elts)))))
      evt)
    music))


music = \relative c' {
  <c e>4-> <d f>( <b g'>) <c e>-. g2 c2
}


\markup { Music with chords }
\new Staff \music

\markup { Music split into two staffs }
<<
  \new Staff \deleteFirstNote \music
  \new Staff \keepOnlyFirstNote \music
>>