Hi all,

yet another semi-feature request where I'm running out of knowledge...
I happily used LSR 888 (center lyrics without taking punctuation into account) for years and only now found out that the alignment is off under certain circumstances: The default algorithm seems to align lyrics on the center of the note*head* of the associated voice. Which seems the right thing to do. However, center-on-words aligns on the center of the *entire note* - in particular, this yields different results on quavers with stems up and "outward flags". At least, neither dots nor accidentals are taken into account...

Even more ugly, the alignment is totally off on chords with two adjacent notes (shifting one note). I know that this should be a forbidden situation for vocal music, but sometimes there is a reason for writing such chords instead of two separate voices (e.g., soprano and alto notated on a common staff in a homorhythmic piece, with one of the voices splitting for a cluster on just a few notes). In such a rare case, I do not like the default algorithm's choices either (and I'd prefer alignment on the center of the noteheads of the chord); but center-on-words does even /way/ worse.

I attach a "test case" (including a full copy of the core of http://lsr.di.unimi.it/LSR/Snippet?id=888), where one would expect center-on-words to do exactly nothing, but you can notice the slight offsets on the "nonius scale" of lyrics.

Anyone got an idea where to start to fix that? I think one would have to figure how to get the note-column-extent without flags; but I have no clue how to approach that.


Thanks in advance,
Alexander
\version "2.18.0"  %% and higher

%% http://lsr.di.unimi.it/LSR/Item?id=888
%% [...]

#(define space-set
  (list->char-set 
    (string->list "—.?-;,:“”‘’–— */()[]{}|<>!`~&…")))

#(define (width grob text)
  (let* ((X-extent 
           (ly:stencil-extent (grob-interpret-markup grob text) X)))
   (if (interval-empty? X-extent)
       0 
       (cdr X-extent))))

#(define (center-on-word grob)
  (let* ((text (ly:grob-property-data grob 'text))
         (syllable (markup->string text))
         (word-position
           (if (string-skip syllable space-set)
               (string-skip syllable space-set)
               0))
         (word-end
           (if (string-skip-right syllable space-set)
               (+ (string-skip-right syllable space-set) 1)
               (string-length syllable)))
         (preword (substring syllable 0 word-position))
         (word (substring syllable word-position word-end))
         (preword-width (width grob preword))
         (word-width (width grob (if (string-null? syllable) text word)))
         (note-column (ly:grob-parent grob X))
         (note-column-extent (ly:grob-extent note-column note-column X))
         (note-column-width (interval-length note-column-extent)))
         
  (- 
    (*
      (/ (- note-column-width word-width) 2)  
      (1+ (ly:grob-property-data grob 'self-alignment-X)))
    preword-width)))

melodies = \relative c'' {
  \autoBeamOff
  g8 a b c
  << { \voiceTwo c } \new Voice { \voiceOne d8 } >>
  << { \voiceOne c } \new Voice { \voiceTwo d8 } >>
  << { \voiceTwo c } \new Voice { \voiceOne e8 } >>
  << { \voiceOne c } \new Voice { \voiceTwo e8 } >>
  \oneVoice
  <c b> <b a> <a g> <g f> <f e>8.*2/3 <e d> <d c> <c c>
}

melody = \relative c'' {
  \autoBeamOff
  g8 a b c
  \voiceTwo c
  \voiceOne c
  \voiceTwo c
  \voiceOne c
  \oneVoice
  <c b> <b a> <a g> <g f> <f e>8.*2/3 <e d> <d c> <c c>
}

lyr = \lyricmode { \repeat unfold 16 "|" }

\score {
  <<
    \new Staff << \new Voice = "cows" \melodies >>
    \new Lyrics \with { \override LyricText.X-offset = #center-on-word } \lyricsto "cows" { \set stanza = "cow" \lyr }
    \new Staff << \new Voice = "ncows" \transpose c c' \melodies >>
    \new Lyrics \lyricsto "ncows" { \set stanza = "default" \lyr }
    \new Staff << \new Voice = "cow^8s" \transpose c c' \melodies >>
    \new Lyrics \with { \override LyricText.X-offset = #center-on-word } \lyricsto "cow^8s" { \set stanza = "cow" \lyr }
    \new Staff << \new Voice = "cow" \melody >>
    \new Lyrics \with { \override LyricText.X-offset = #center-on-word } \lyricsto "cow" { \set stanza = "cow" \lyr }
    \new Staff << \new Voice = "ncow" \transpose c c' \melody >>
    \new Lyrics \lyricsto "ncow" { \set stanza = "default" \lyr }
    \new Staff << \new Voice = "cow^8" \transpose c c' \melody >>
    \new Lyrics \with { \override LyricText.X-offset = #center-on-word } \lyricsto "cow^8" { \set stanza = "cow" \lyr }
  >>
  \layout {
    \context {
      \Score
      % just for easier comparison
      proportionalNotationDuration = #(ly:make-moment 1 16)
      \override SpacingSpanner.strict-note-spacing = ##t
    }
  }
}
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to