6

I am using following structure to write music in lilypond:

\new StaffGroup <<
    \new Staff \with {
      instrumentName = "Vocal"
      shortInstrumentName = "Voc"
    } \relative {
        a b c d
    }
    
    \addlyrics {
      A B C D
    }

    \new Staff \with {
      instrumentName = "Strings"
      shortInstrumentName = "Str"
    } \relative {
        d e f g
    }
>>

This produces following:

But I want a different structure. I want to define a variable combining melody and lyrics:

melody = { 
  a b c d 
  \new Lyrics \lyricmode{A4 B4 C4 D4} 
}

And then use the variable like so:

\new StaffGroup <<
    \new Staff \with {
      instrumentName = "Vocal"
      shortInstrumentName = "Voc"
    } \new Voice \relative {
        \melody
    }   

    %\addlyrics {
      %A B C D
    %}  

    \new Staff \with {
      instrumentName = "Strings"
      shortInstrumentName = "Str"
    } \relative {
        d e f g 
    }   
>>

Unfortunately this produces the following:

The lyrics are printed below the second staff and not aligned. How can I fix this?

Edit: It is better to use tags to achieve this functionality. Please refer to comments under @Lazy's answer

2

2 Answers 2

6

Lilypond uses so called contexts for Staves and Lyrics. While Lyrics might print unter Staves they are still separate contexts. So when you do blocks like

<<
  { ... }
  \new Lyrics ...
>>

you get separate Lyrics contexts for each block. These will then be spaced separately. Instead you want to switch to the already existing context using \context Lyrics = ... ..., as demonstrated here:

melody =
<<
  { a4. b8 c4. d8 }
  \context Lyrics = "lyrics" \lyricsto "voice" { A4 B C D }
>>

\new StaffGroup <<
    \new Staff \with {
      instrumentName = "Vocal"
      shortInstrumentName = "Voc"
    } \new Voice = "voice" \relative {
        \melody \melody
    }   

    \new Staff \with {
      instrumentName = "Strings"
      shortInstrumentName = "Str"
    } \relative {
        d e f g 
    }   
>>
7
  • This is weird - if I write: r4 \melody \melody the lyrics again move below second staff. Same thing happens if I set a midi instrument before \melody. What is happening? Using lilypond 2.24.0 on Mac
    – kargirwar
    Mar 6, 2023 at 11:02
  • 1
    @kargirwar That happens because the Lyrics context does not yet exists when the system is started, but it is created only when the first \melody is used. In this case place a \new Lyrics = "lyrics" { s1 } (adjust the skip to have the context alive whenever you need it) between the \new Staffs.
    – Lazy
    Mar 6, 2023 at 11:28
  • That seems to work. I am using different staffgroups for different parts of the song.Potentially same variable could be used in multiple staffgroups. Will this scheme work there ?
    – kargirwar
    Mar 6, 2023 at 11:40
  • @kargirwar No, but you could wrap melody in a music function that specifies the name of the correct lyrics context and the name of the corresponding voice as argument. For this wrap the whole << ... >> thing in #(define-music-function (lname vname) (string? string?) #{ ... #}) and replace "lyrics" and "voice" by #lname and #vname.
    – Lazy
    Mar 6, 2023 at 14:03
  • 1
    @kargirwar But maybe your whole concept is not the best way to do it. You could use tags to extract notes and lyrics from a single variable for example: melody = << \tag #'notes { c4. d8 e4. f8 } \tag #'lyrics \lyricmode { a b c d } >> and then for example staffA = { \melody \melody } and << \new Staff \new Voice = "voice" \keepWithTag #'notes \staffA \new Lyrics \lyricsto "voice" { \keepWithTag #'lyrics \staffA } >>
    – Lazy
    Mar 6, 2023 at 21:48
4

It’s unfortunately a common confusion among LilyPond users to think braces do something different than what they actually do. Especially for people used to LaTeX, where braces just “group stuff”. Granted, this is not eased by LilyPond having some places like \score { … } where the braces are indeed there just to group stuff. But the bulk of braces you see do more than that. Your melody variable doesn’t just contain notes and lyrics, it has them in sequence, i.e., one bar of notes then one bar of lyrics. Instead you want

melody =
<<
  { a4 b c d }
  \new Lyrics \lyricmode { A4 B C D }
>>

The << >> construct puts the notes and lyrics in parallel, and the inner braces on the notes make sure they are combined as one sequential expression (if you don’t put them, all the notes are in parallel as well, since they’re right inside the << >>).

2
  • If I use the melody variable twice, the lyrics of second one are again printed next to second staff. What is wrong now?
    – kargirwar
    Mar 6, 2023 at 8:29
  • See @Lazy’s answer. Mar 6, 2023 at 13:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.