\version "2.20.0" #(define (split-music dir music ref) (let ((es (ly:music-property music 'elements)) (e (ly:music-property music 'element)) (p (ly:music-property music 'pitch))) (if (pair? es) (ly:music-set-property! music 'elements (map (lambda (x) (split-music dir x ref)) es))) (if (ly:music? e) (ly:music-set-property! music 'element (split-music dir e ref))) (if (ly:pitch? p) (if ((if (> dir 0) >= <) (ly:pitch-steps p) (ly:pitch-steps ref)) p (ly:music-set-property! music 'name 'SkipEvent) % works, but produces warnings )) music )) splitMusic = #(define-music-function (parser location dir ref music ) ((ly:dir? 1) (ly:pitch? (ly:make-pitch 0 0)) ly:music? ) (split-music dir music ref)) %%%%%%%%%%%%%%%%%%%%%%%%%%% %Examples someMusic = { c d e g c' d' c'' \chordmode{d:7/a} << {c' d' e' f'} \\ {c d e f}>> d'2. \relative c' {c1 b a g} << \chordmode { c4 d e f} \\ \transpose c c, \chordmode {c d e f}>> << {c' b e' f'} \\ {c, e, c2} \\ {g2 a4 b}>> } \markup "Some music" {\someMusic} \markup "\SplitMusic result on piano staff" \new PianoStaff << \new Staff {\splitMusic \someMusic} \new Staff { \clef bass \splitMusic #DOWN \someMusic } >> \markup "\SplitMusic result on SATB (with arbitrary split-points)" \new StaffGroup << \new Staff { \clef soprano \splitMusic #UP f' \someMusic } \new Staff { \clef alto \splitMusic #DOWN f' \splitMusic #UP a \someMusic } \new Staff { \clef tenor \splitMusic #DOWN a \splitMusic #UP d \someMusic } \new Staff { \clef baritone \splitMusic #DOWN d \someMusic } >>