lilypond-user
[Top][All Lists]
Advanced

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

Re: multiple voices inside CueVoice


From: Jean Abou Samra
Subject: Re: multiple voices inside CueVoice
Date: Sat, 11 Jun 2022 23:29:38 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.9.1



Le 11/06/2022 à 22:24, Kieren MacMillan a écrit :
Hi Jean,

Yeah, that's a bit unfortunate. Basically, the default
child of Staff is Voice, and there isn't a way for
a command issued in CueVoice to "know" that it's in
CueVoice and let other CueVoices be created instead.
Exactly.

You could use this hack though:
Oh! Nice! Thanks for that.

If you have a moment, please elaborate:

1. Why do you call it a “hack”? What’s “improper” about it?

2. Can you anticipate any problems using this “hack” in a production 
environment?



Conceptually, it is elegant I think, but the devil's in the
details, and there's a big bad one here: \alias Staff. Let's
rewind the causation chain a bit. Observe this:


<<
  \context Bottom = "1" { c' }
  \context Bottom = "2" { c' }
>>


Two staves get created for the two bottom Voice contexts.
(I'm not knowledgeable about the details of why this is so.)
The above is the outline of what \voices generates. To avoid
the situation that \voices would implicitly create several
staves like this, which would be a little confusing for
this construct, \voices actually wraps the whole thing:


\context Staff <<
  \context Bottom = "1" { c' }
  \context Bottom = "2" { c' }
>>


If you want to see it in action, you can play with

\displayLilyMusic \voices 1,2 << { c' } \\ { c } >>

This \context Staff ensure that the voices remain in a single
Staff. Now, try

\version "2.22.1"

\layout {
  \context {
    \Staff
    \accepts CueGroup
  }
  \context {
    \name CueGroup
    \type Engraver_group
    \accepts CueVoice
  }
}

\new CueGroup {
  c'4 4 4 4
  \voices 1,2 << { d'4 4 4 4 } \\ { b2 2 } >>
  c'4 4 4 4
}


This is just my snippet without \alias Staff in CueGroup.
It doesn't work, and the reason is that the \context Staff
generated by \voices jumps out of CueGroup, which defeats the
whole thing. Therefore, I added \alias Staff so that
\context Staff will only jump to CueGroup. The problem is that
this makes commands that try to go to Staff ineffective. For
example, this won't work:

\version "2.22.1"

\layout {
  \context {
    \Staff
    \accepts CueGroup
  }
  \context {
    \name CueGroup
    \type Engraver_group
    \accepts CueVoice
    \alias Staff
  }
}

\new CueGroup {
  c'4 4 4 4
  \voices 1,2 <<
    {
      d'4 4
      \once \override Staff.KeySignature.color = "red"
      \key d \minor
      4 4
    } \\ {
      b2 2
  } >>
  c'4 4 4 4
}


The \override Staff.etc searches an enclosing context of type
or alias Staff, and finds CueGroup, which is not where the
KeySignature is being created. To do an override on the level
of the true Staff, you would need


\version "2.22.1"

\layout {
  \context {
    \Staff
    \accepts CueGroup
    \alias RealStaff
  }
  \context {
    \name CueGroup
    \type Engraver_group
    \accepts CueVoice
    \alias Staff
  }
}

\new CueGroup {
  c'4 4 4 4
  \voices 1,2 <<
    {
      d'4 4
      \once \override RealStaff.KeySignature.color = "red"
      \key d \minor
      4 4
    } \\ {
      b2 2
  } >>
  c'4 4 4 4
}


which is not necessarily obvious to find :-)

I'm not sure how one could prevent that. Maybe we need
a variant of \context that only descends to the context
but never walks up to find it (this would have to be coded
in C++)? I don't know. Context creation is a tricky thing ...

Best,
Jean




reply via email to

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