lilypond-devel
[Top][All Lists]
Advanced

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

Re: Scheme function to print out active Voice context during interpretat


From: Trevor Bača
Subject: Re: Scheme function to print out active Voice context during interpretation?
Date: Sun, 14 Dec 2008 20:18:31 -0600



2008/12/14 Carl D. Sorensen <address@hidden>



On 12/14/08 4:34 PM, "Trevor Bača" <address@hidden> wrote:


>
> I have a pretty big stockpile of tests and sometime in the next couple of days
> I'll find a way to organize them and send them over. But I'd like to start
> with the pair of examples that just seems absolutely pathological to me. Here
> it is:
>
>
> %%% VOICE-RESOLUTION EXAMPLE 1 %%%
>
> \version "2.11.57"
>
>    {
>       \override Voice.NoteHead #'color = #red
>       c'8
>       d'8
>       e'8
>       f'8
>       \new Voice = "foo" {
>          g'8
>          a'8
>          b'8
>          c''8
>       }
>       d''8
>       e''8
>       f''8
>       g''8
>    }
>
> %%% END EXAMPLE 1 %%%
>
> So far, so good. In example 1, LilyPond creates two voices with one nested
> inside the other. We see this because the outer eight notes are red while the
> inner four notes are black.
>
> But now look at this:
>
> %%% VOICE-RESOLUTION EXAMPLE 2 %%%
>
> \version "2.11.57"
>
>    {
>       \new Voice = "foo" {
>       \override Voice.NoteHead #'color = #red
>          g'8
>          a'8
>          b'8
>          c''8
>       }
>       d''8
>       e''8
>       f''8
>       g''8
>    }
>
>
> %%% END EX 2 %%%
>
> (Stop and think what you'd expect here before looking at the output.)
>
> Here LilyPond renders a single voice! We see this because all eight notes are
> red.
>
> Sprinkling the new \whichContext function before the first, fourth (and
> eighth) notes in each example (where possible) makes it clear that the "foo"
> context governs only the middle four notes in the first example while
> governing *all* eight notes in the second example.
>
> What on earth is going on here?
>
> What's so odd is that if you look at example 2 and think "OK, this is all just
> a single voice because the explicitly instantiated voice 'leaks' over into the
> following four notes" ... then you're in for a big surprise when you add just
> a single note to the beginning of the example:
>
> %%% EX 2 + 1 NOTE %%%
>
>    {
>    c'8
>       \new Voice = "foo" {
>       \override Voice.NoteHead #'color = #red
>          g'8
>          a'8
>          b'8
>          c''8
>       }
>       d''8
>       e''8
>       f''8
>       g''8
>    }
>
> %%% END EX 2 MOD %%%
>
> That single note at the beginning now breaks the example into two voices just
> like example 1!
>
> Can anyone explain what's going on here?

In examples 1 and 2+1 note, the first music occurs without a voice being
defined.  Therefore, LilyPond creates (instantiates) a voice.  Voice foo is
then created, and limited to the notes contained in the brackets.

In example 2, Voice foo is created before any voice is instantiated.  Then,
the music that comes after the voice foo definition is just applied to the
existing voice foo, since there is no explicit instantiation.

OK, this explanation is extremely helpful. But there's still something deeply wrong. Han-Wen from a bit earlier:

"Note that contexts do not 'nest' as you claim in a message below.
Voice contexts cannot contain any other context."

But check this out:

%%% VOICE-RESOLUTION EX 3 %%%

\version "2.11.65"
\include "english.ly"

\new Voice = "foo" {
   \override Voice.NoteHead #'color = #red
   \whichContext
   c'8
   cs'8
   \new Voice = "bar" {
      \override Voice.NoteHead #'color = #blue
      \whichContext
      d'8
      ef'8
      \new Voice = "blah" {
         \override Voice.NoteHead #'color = #green
         \whichContext
         e'8
         f'8
         fs'8
         g'8
      }
      \whichContext
      af'8
      a'8
   }
   \whichContext
   bf'8
   b'8
}

%%% END %%%

It appears as though the voice contexts are indeed nesting ... perfectly, in fact!

And, in fact, John's new \whichContext function emits the following during interpretation:

GNU LilyPond 2.11.65
Processing `0303.ly'
Parsing...
Interpreting music...
Current voice is foo

Current voice is bar

Current voice is blah

Current voice is bar

Current voice is foo

Preprocessing graphical objects...
Finding the ideal number of pages...
Fitting music on 1 page...
Drawing systems...
Layout output to `0303.ps'...
Converting to `./0303.pdf'...


This is nesting, isn't it? (How else to explain the stickiness of the grob overrides?) Or have I completely lost my mind?

(Han-Wen's suggestion about looking over the iterator code makes sense and I'll take a look right after I get in a quick jog ... because I think I might go mildly insane otherwise ...)


 


This kind of inconsistency shows up lots of times when you use automatic
instantiation of contexts.  In order to avoid these things, I've take to
explicitly instantiating all contexts.  (And if I used multiple books in a
score, I'd explicitly instantiate all of them as well).

Implicit instantiation is beginner-friendly but expert-unfriendly, IMO.  It
makes less for the user to type in building a simple song, but it hides the
structure of LilyPond, and makes it unnecessarily difficult to set complex
music. 


A while ago there was a post suggesting that we do away with all implicit
instantiation and require users to explicitly instantiate contexts.  That
went nowhere.  But I think there ought to be a statement somewhere that says
"for complex scores, it is best to explicitly instantiate all voices".  In
my experience, that avoids lots of confusion.




--
Trevor Bača
address@hidden

Attachment: example-3.png
Description: PNG image


reply via email to

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