Hello,
In general I don't suggest you use the dynamics centered between the staves for new scores. In my knowledge it is an obsolete engraving practice that has side effects.
<disclaimer> this is * not the truth * but it's * my * knowledge. Of course I can explain why this practice can be counterproductive, but in any case feel free to hear different opinions or to ignore my observation. </disclaimer>
This said, if you want to use it (for example because you are copying an old score) the approach in my opinion is the following
1) group the bars of the piano into blocks, so that you can read fragments of code that are not too long from left to right and then move on to the next line.
As it is convenient for all programming languages.
2) avoid explicitly writing a redundancy layer (---> many skips), so that the code is less verbose.
To do these things, AFAIK Lilypond does not provide native tools.
So I'll show you a possible idea of mine. It consists in extracting the dynamics automatically from the lower staff, and automatically creating a Dynamics layer with them.
However, my Scheme code is ugly, *strongly* incomplete and I don't want to expand it because otherwise it gets even worse. I don't even know if my idea works in general or has side effects, because I don't use the Dynamics layer, so I haven't examined the problem in detail.
Consequently, the opinion of the Scheme Gurus in this ML is needed for these things (there are several. For example Aaron and Harm)
In any case, here is the template. As you can see I removed the redundancy layer. The code must be written only in the part with the tag "WRITE MUSIC HERE"
HTH
P
LILYBIN:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
staffUp = \change Staff = "Staff_pfUpper"
staffDown = \change Staff = "Staff_pfLower"
removeDynamics = #(define-scheme-function (parser location mus) (ly:music?)
(map-some-music (lambda (y)
(let ((name (ly:music-property y 'name)))
(cond
((or (eq? name 'NoteEvent)(eq? name 'EventChord)(eq? name 'RestEvent)(eq? name 'SkipEvent))
(map-some-music (lambda (z)
(let ((name (ly:music-property z 'name)))
(cond
((eq? name 'AbsoluteDynamicEvent)
(set! z '())
z)
(else #f))))
y)
y)
(else #f))))
mus)
#{ $mus #})
createDynamicsLayerFromMus = #(define-scheme-function (parser location mus) (ly:music?)
(let ((newSkip '())
(newMus #{ #}))
(map-some-music (lambda (q)
(cond
((not (eq? (ly:music-property q 'context-id) '()))
(map-some-music (lambda (y)
(let ((name (ly:music-property y 'name))
(newSkip '())
(assocDyn '()))
(cond
((or (eq? name 'NoteEvent)(eq? name 'EventChord)(eq? name 'RestEvent)(eq? name 'SkipEvent))
(map-some-music (lambda (z)
(let ((name2 (ly:music-property z 'name)))
(cond
((eq? name2 'AbsoluteDynamicEvent)
(set! assocDyn z)
z)
(else #f))))
y)
(set! newSkip (make-music 'SkipEvent 'length (ly:music-length y) ))
(if (not (eq? assocDyn '()))
(ly:music-set-property! newSkip
'articulations (list (make-music 'AbsoluteDynamicEvent
'text (ly:music-property assocDyn 'text)))))
(set! newMus #{ #newMus #newSkip #})
y)
((eq? name 'ContextChange)
(set! y '())
y)
(else #f))
)) q)
q)
(else #f)
)
) mus)
#{ $newMus #}))
pianoBlock = #(define-scheme-function (parser location mus1 mus2) (ly:music? ly:music?)
#{ << { #mus1 } \\ \new Voice = "sotto" { \staffDown #mus2 } >> #})
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%% WRITE MUSIC HERE %%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
upper = {
\pianoBlock
{ c''4 c'' c'' c'' }
{ a\mf_"foobar" a\mp b b }
\pianoBlock
{ r1 r }
{ a\pp a }
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
lower = { }
\score {
\new PianoStaff = "PianoStaff_pf" <<
\new Staff = "Staff_pfUpper" << \removeDynamics \upper >>
\new Dynamics = "Dynamics_pf" << \createDynamicsLayerFromMus \upper >>
\new Staff = "Staff_pfLower" << \lower >>
>>
\layout { }
}