lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Issue 442 workaround (with a Scheme-engraver?)


From: Valentin Villenave
Subject: Issue 442 workaround (with a Scheme-engraver?)
Date: Tue, 26 Jan 2010 14:21:52 +0100

Greetings everybody,

sorry for not being more available on -user these days... I hope some
skilled LilyPonders are better at multitasking than I am and that this
mail will be addressed though :)

(Quite) a while back, I had found a workaround issue 442, that allowed
me to keep both staves of a PianoStaff alive together (and remove them
together when there was no music on either one).

As you can see, the trick was to create an invisible "PseudoVoice"
mirroring what happens on the other staff. It /is/ quite hackish, and
generates a lot of warnings.

Han-Wen has recently implemented the ability to create engravers using
Scheme. Although I haven't taken the time to dive into this, I suspect
that my "pseudovoice" could actually be made of a "pseudo_engraver",
that would not generate all these annoying warnings.

Or (perhaps) there's even a way to tweak the Hara-Kiri engraver
itself, and force it to take other staves into account. But here I'm
out of my league.


\layout {
 \context { \RemoveEmptyStaffContext }
 \context {
   \name PseudoVoice
   \alias Voice
   \type Engraver_group
   \consists Note_heads_engraver
   \consists Pitch_squash_engraver
   squashedPosition = #0
   \override NoteHead #'stencil = #empty-stencil
 }
 \context {
   \Staff
   \accepts PseudoVoice
   \remove Time_signature_engraver
 }
}


#(define (remove music) ; throw everything into the Big Void...
 (context-spec-music music 'Devnull))

#(define (unpitch music)
 ; in addition to the PitchSquash thing, we need to make
 ; accidentals disappear (since these are engraved at a
 ; Staff level, and since we don't want to affect the
 ; real Voice).
 (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) (unpitch x)) es)))
   (if (ly:music? e)
       (ly:music-set-property!
        music 'element
        (unpitch e)))
   (if (ly:pitch? p)
         (ly:music-set-property! music 'pitch 0)))
  music)

#(define (event-filter event)
 (let ((n (ly:music-property event 'name)))
 (if (or
   (eq? n 'ContextSpeccedMusic) ; to avoid clefs and ottavas
   (eq? n 'ContextChange) ; cross-staff voices are supported
   (eq? n 'ArpeggioEvent)) ; arpeggios need to go too
   (music-map remove event))
 (if (eq? n 'SimultaneousMusic) ; we don't want a new Voice to be created
   (ly:music-set-property! event 'name 'NoteEvent))))

makeGhost =
#(define-music-function (parser location music) (ly:music?)
 (context-spec-music (music-filter event-filter (unpitch music)) 'PseudoVoice))

PianoFunction=
#(define-music-function (parser location right left) (ly:music? ly:music?)
#{
 \new PianoStaff <<
   \new Staff = "md"
   <<
    \new Voice { \clef treble $right }
    \new Voice { \makeGhost $left }
   >>
   \new Staff = "mg"
   <<
    \new Voice { \clef bass $left }
    \new Voice { \makeGhost $right }
   >>
 >>
#})

\PianoFunction
\relative { c1 \break c \break R \break R \break c }
\relative { c1 R R c c }

%%%%%%%%%%


I hope someone more skilled than me will have some ideas.

Regards,
Valentin




reply via email to

[Prev in Thread] Current Thread [Next in Thread]