\version "2.20.0" #(define (make-autosplit-chord chord . ref-pitch) "Return a pair of lists, containing the pitches of @var{chord}, splitted at a reference pitch. The reference pitch is derived from @var{ref-pitch}. If @var{ref-pitch} is empty, @code{c'} is regarded as reference. " (define ref-pitch-steps (if (and (pair? ref-pitch) (car ref-pitch)) (ly:pitch-steps (car ref-pitch)) 0)) (call-with-values (lambda () (partition (lambda (note) (> (ly:pitch-steps (ly:music-property note 'pitch)) ref-pitch-steps)) (event-chord-notes chord))) (lambda (x y) (cons x y)))) autoSplitChord = #(define-music-function (stem-dir staff-names pitch chord) ((ly:dir? 0) (pair? '("up" . "down")) (ly:pitch?) ly:music?) (_i "Split @var{chord} at optional @var{pitch}. The default of @var{pitch} is @code{#f}, which is interpreted by the called procedure @code{make-autosplit-chord} as @code{c'}. The splitted chords are distributed to named staves, relying on optional @var{staff-names}. The optional @var{stem-dir}, determines the direction of the stems and whether the chords may be connected by a cross-staff stem. The default results in unconnected chords. If the @code{Span_stem_engraver} is consisted, the chords may be connected by a cross-staff stem.") (if (music-is-of-type? chord 'event-chord) (let* ((skip (make-duration-of-length (ly:music-length chord))) (devided-pitches (make-autosplit-chord chord pitch)) (upper-chord (if (pair? (car devided-pitches)) (make-event-chord (car devided-pitches)) (make-skip-music skip))) (lower-chord (if (pair? (cdr devided-pitches)) (make-event-chord (cdr devided-pitches)) (make-skip-music skip)))) #{ << \context Staff = #(car staff-names) \context Voice { $(if (negative? stem-dir) #{ \once \override Stem.cross-staff = #cross-staff-connect \once \override Flag.style = #'no-flag <>\noBeam #}) $(if (not (zero? stem-dir)) #{ \once \override Stem.direction = #stem-dir #}) #upper-chord } \context Staff = #(cdr staff-names) \context Voice { $(if (positive? stem-dir) #{ \once \override Stem.cross-staff = #cross-staff-connect \once \override Flag.style = #'no-flag <>\noBeam #}) $(if (not (zero? stem-dir)) #{ \once \override Stem.direction = #stem-dir #}) #lower-chord } >> #}) #{ \context Staff $chord #})) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% TESTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Pippo = 1 PippoDue = \chordmode {c1:/g} PippoTre = c1 PippoQuattro = {} \new PianoStaff \with { \consists #Span_stem_engraver } << \new Staff = "up" { \key c\major \autoSplitChord #UP 2 \autoSplitChord 4 \autoSplitChord #DOWN \autoSplitChord 1 \autoSplitChord \chordmode {c:/g} \autoSplitChord {} \autoSplitChord { } \autoSplitChord c \autoSplitChord \autoSplitChord <> \autoSplitChord <> \autoSplitChord <> \autoSplitChord << {c4 d e f} \\ {c' d' e' f'} >> \autoSplitChord \Pippo \autoSplitChord \PippoDue \autoSplitChord \PippoTre \autoSplitChord \PippoQuattro } \new Staff = "down" { \key c\major \clef bass s1 %bass staff appear only at the beginning, then reappears as another staff with treble clef } >> \new PianoStaff \with { \consists #Span_stem_engraver } << \new Staff = "up" { \key c\major \autoSplitChord #UP 2 \autoSplitChord 4 \autoSplitChord #DOWN \autoSplitChord 1 \autoSplitChord \chordmode {c:/g} \autoSplitChord {} \autoSplitChord { } \autoSplitChord c \autoSplitChord \autoSplitChord <> \autoSplitChord <> \autoSplitChord <> \autoSplitChord << {c4 d e f} \\ {c' d' e' f'} >> \autoSplitChord \Pippo \autoSplitChord \PippoDue \autoSplitChord \PippoTre \autoSplitChord \PippoQuattro } \new Staff = "down" { \key c\major \clef bass \repeat unfold 16 s1 %bass staff is shown correctly } >>