Re: An overview of the system

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: An overview of the system

Don Blaheta
I'm going to continue thinking out loud here, because it's really
helping me understand the internals (and, hopefully, will also help
any documentation folks in seeing where misunderstandings lie).  I've
moved it to the devel list because there's some moderately technical
stuff mixed in, and I might be getting it wrong to boot. ;)

Quoth Erik Sandberg:

> On Sunday 11 December 2005 07.33, Don Blaheta wrote:
> > A context is an environment into which you enter your music; it can be
> > created anonymously (\new) or named (\context).  If you create a new
> > context, either anonymously or with a new name, it puts that context
> > right where you are in the enclosing context, and effectively puts your
> > cursor at the beginning of that brand-new context.  If on the other hand
> > you open a context that has the same name as a previously created
> > context, you are not creating a new context, but rather sending your
> > cursor back to insert at the end of that existing, named context.
> > * Voice claims it can't contain other contexts; but it can contain other
> >   Voice contexts.
>
> no. You can write
> \context Voice=A { c d \context Voice=B {e f} g}
>
> but this will make B a sibling of voice A.
>
> The behaviour is made more clear with this example:
>
> \context Staff=A \context Voice=V {c d \context Staff=B {e f } g}

Oh! I see.  Time synching really has nothing to do with contexts, I now
see.  Your example also showed me something new about the use of
braces---I had thought they were syntagmatic.  Trying again:


When you type something that produces a bit of music, that musical thing
is normally placed immediately after the thing you typed previously, and
immediately before the thing you type next.  Time keeps going, unless
you explicitly say that two things happen simultaneously---and that
applies both to small-scale things like notes, and large-scale things
like whole instrument parts.

That means if you cause lilypond to "start entering on the next staff",
lilypond will do that *but timewise it will do so right where the old
staff left off*, which is probably not what you want.  The takeaway
message here is that the things you do to control *when* things happen
in the music are independent from the things you do to control *how*
they're realised, both visually and aurally.  (Even if the two are
textually interspersed in the input file.)

The "how" is controlled via contexts.  There are four layers of
contexts, and at least three are present in every document, possibly
implicitly.  At the outermost level is the Score; there is one Score per
document, and it is implicitly created for whatever you type inside
\score.  At the innermost level are the "bottom" contexts, voices, that
actually contain a single line of the music---the default one is Voice,
but others include DrumVoice, ChordNames, and so on.  Each voice has to
be laid out onto a background line or five, and that background is a
staff (Staff, DrumStaff, etc).  Sometimes a staff will only have one
voice, sometimes (e.g. in cases of polyphony) more than one.  If you
omit explicitly creating either a staff or a voice, one is implicitly
created for you.  The fourth kind of context is a staff group, such as
GrandStaff or PianoStaff, which gives control over any brackets drawn to
the left of a system and bar lines that may or may not connect between
staves.  Staves can be contained either by a staff group, or directly by
the Score.
* Can staff groups contain other staff groups?

A somewhat special sort of context is the Lyrics context, which is like
a staff in terms of this hierarchy (it can be contained by staff groups
or by the Score), but it is a bottom context.  More about Lyrics some
other time.

Any context can be created anonymously (\new) or named (\context).  
When you create a new context, it is contained by the innermost open
context that is able to contain it---e.g. if the Score, a Staff, and a
Voice are open, and you create a new Voice, that new voice will be
contained by the Staff, not the Voice.  This means that the textual
nesting (what you see when you look at pairs of {}, <<>>, <>) may *not*
reflect the logical nesting.  If you open a named context, and a context
with that name is not already defined, you switch into the existing one.
(Remember, though, that this switch is totally independent of sequence/
simultaneity management---so you may or may not be overlapping whatever
was already entered in that context.)


* Side note: when trying to figure out whether Lyric contexts were
actually contained by Staffs or became siblings, I typed the following:
  \score {<<
    \new Staff {
      %\set Staff.fontSize = #3
      <<
        \new Voice { c }
        \new Lyrics \lyricmode { x }
        \new Lyrics \lyricmode { y }
      >>
    }
    \new Voice { f }
  >>}
and when the \set is uncommented, suddenly the lyrics move below the
second staff line.  Why is that?  (It certainly answered my question,
though not quite the way I expected.)  It doesn't seem to matter what I
\set there.


* Bug?: When I was playing with staff groups, I found a whole bunch of
  examples involving nested staff groups that give no lilypond errors
  but cause gv to have kittens over, I'm guessing, something in the left
  bracket.  It's baffling, though; the following example works fine
  until you uncomment the fourth line.
    \score { <<
      \new GrandStaff {<<
        \new Staff { \new Voice { f } }
        %\new Staff { \new Voice { a } }
        \new ChoirStaff {<<
          \new Staff { \new Voice { d } }
          \new Staff { \new Voice { e } }
        >> }
      >> }
    >> }



> "Everything is Music". Events is a special case of Music (those that don't
> happen to have child expressions). The most useful way to describe it is as a
> tree. Each Music is a tree, which often consists of several subtrees, which
> also are Music. Music is also called "music expression"

This is more or less what I guessed, but it's not very clear from the
docs.

> In 2.7+, everything is Music (the class Event has been removed).

Just renamed, or is this a more fundamental change?  There are
presumably still leaf nodes....

> > * what is the difference between SkipEvent (e.g. s4) and SkipMusic (e.g.
> >   \skip 4)?
>
> try this:
> \new StaffGroup<<
> {s2 \new Staff {c4}}
> {\skip 2 \new Staff {c4} }
> >>
> s2 creates a new staff, \skip doesn't.

I'd ask why, but I think I see this heading towards lyrics, which I want
to put off for a little bit yet.

> > * No SYNTAX for a lot of events e.g. FingerEvent, BarCheck
> > * Could we see the subclasses of each music expression type?
> there is only one class in 2.7, Music.

Maybe not "subclass" then, but I wanted to see the hierarchy; for
example I can find out that a BeamEvent can be a general-music, event,
beam-event, or span-event, but not that an Event is related to a
BeamEvent, at least, not from the page on Event.  Even if you rearrange
and rename the internals, I assume there will be some sort of hierarchy
in there....

> > * In Music properties, no indication *which* types of expr each property
> >   can belong to
> Any property can belong to any music type, it's just that they may be
> ignored.

Ok, true but not helpful.  s/can belong to/will matter for/.

> Iterators and translators decide that. If you need to know more, you can
> either copy what others already did, or you can read the source code for
> hints (usually, only gurus tweak Music properties, and most gurus know how to
> read source code)
>
> In general, i'd advice you to look directly in the .scm files (scm/* wherever
> lilypond's data files are), rather than the online docs. The .scm files
> sometimes contain additional hints.

So you're arguing against documenting the system?

> Note also that Engraver is a subclass of Translator; engravers are used for
> graphical output. Performers are used for midi output, they are a different
> subclass of Translaotr.

I kind of inferred that, but it wasn't at all clear from the docs (where
this section of the reference is even labelled "Engravers", presumably
for historical reasons).

> > Each context has a variety of properties that keep track of where the
> > engraving process is---what measure it's in, whether it's in the middle
> > of a triplet, etc.---as well as some general properties of the context,
> > like the stanza number or whether to beam.  
>
> BTW, the time keeping properties are usually stored centrally in the Score
> context; the other contexts "inherit" those property settings. (You can also
> tweak this to be set per staff, look for Timing_translator in regression
> tests)

Well, sure, but that *is* the sort of thing that contexts keep track of,
right?

> > * What happens to events that are "inside" the musics?
> Only events are sent to translators. There are some exceptions, but they will
> be eliminated soon so please ignore them.

So music expressions that aren't events aren't sent to translators?  How
does this mesh with the pending disappearance of events?

> > * In what order are the contexts visited---inside out?
> Bottom up. Events are sent to Voice context, which forwards the events to
> Staff if they can't be swallowed.

If they *can't* be swallowed?  I thought expressions were sent to more
than one engraver.

> > * When a 'direction property is labelled "Up or down, left or right?",
> >   and its value is a number, this is confusing.
> -1 generally means down/left iirc (think time and octave)

Thanks for the answer; still confusing in the docs.

> > * Again, not always clear which properties go with which grobs
> >
> > Once all the grobs are created, actually *printing* the engraved music
> > is a trivial walk of the grobs, since they have all their relative size
> > and shape and position information.
>
> no, that's where the actual typesetting happens. It's the *really* difficult
> part. Grobs are translated into Stencils, and I think the Stencil->graphics
> conversion is the easy part.

Ooh.  Ok, more to learn, although at least this part I think can be
safely ignored by the medium-casual user.

--
-=-Don Blaheta-=-=-[hidden email]-=-=-=-<http://www.blahedo.org/>-=-
Exercises for the Republican reader #4:
Compare the GNP with the rate of taxation over the last fifty
years---e.g. the boom years of the '50s with their 90% marginal tax
rate---and practice explaining that high tax rates discourage investment
until you can do it with a straight face. --Mark Rosenfelder


_______________________________________________
lilypond-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/lilypond-devel
Reply | Threaded
Open this post in threaded view
|

Re: An overview of the system

Han-Wen Nienhuys
Don Blaheta wrote:
> When you type something that produces a bit of music, that musical thing
> is normally placed immediately after the thing you typed previously, and

only for sequential music. Try

  \score { << a b c d e >> }



> Any context can be created anonymously (\new) or named (\context).  
> When you create a new context, it is contained by the innermost open
> context that is able to contain it---e.g. if the Score, a Staff, and a
> Voice are open, and you create a new Voice, that new voice will be
> contained by the Staff, not the Voice.  This means that the textual
> nesting (what you see when you look at pairs of {}, <<>>, <>) may *not*
> reflect the logical nesting.  If you open a named context, and a context

Textual nesting as such doesn't really exist, internally. << >> and { }
  reflect time-wise relations between Music. Nothing more.

> * Side note: when trying to figure out whether Lyric contexts were
> actually contained by Staffs or became siblings, I typed the following:
>   \score {<<
>     \new Staff {
>       %\set Staff.fontSize = #3
>       <<
>         \new Voice { c }
>         \new Lyrics \lyricmode { x }
>         \new Lyrics \lyricmode { y }
>       >>
>     }
>     \new Voice { f }
>   >>}
> and when the \set is uncommented, suddenly the lyrics move below the
> second staff line.  Why is that?  (It certainly answered my question,
> though not quite the way I expected.)  It doesn't seem to matter what I
> \set there.

The order in which contexts appear on paper is the order in which they
are created. By putting \set in a sequence, you force everying following
it ( the << >> ) to be done after "opening" the outermost \new Staff .


> Just renamed, or is this a more fundamental change?  There are
> presumably still leaf nodes....

it's an internal change. The C++ class Event has disappeared, but of
course, there are still events. The definition of those has moved
entirely to the Scheme side.

> Maybe not "subclass" then, but I wanted to see the hierarchy; for
> example I can find out that a BeamEvent can be a general-music, event,
> beam-event, or span-event, but not that an Event is related to a
> BeamEvent, at least, not from the page on Event.  Even if you rearrange
> and rename the internals, I assume there will be some sort of hierarchy
> in there....

They are related through their 'types property. See
scm/define-music-types.scm for more information. Strictly speaking,
there is no hierarchy.

>>Iterators and translators decide that. If you need to know more, you can
>>either copy what others already did, or you can read the source code for
>>hints (usually, only gurus tweak Music properties, and most gurus know how to
>>read source code)
>>
>>In general, i'd advice you to look directly in the .scm files (scm/* wherever
>>lilypond's data files are), rather than the online docs. The .scm files
>>sometimes contain additional hints.
>
>
> So you're arguing against documenting the system?

No, against inferring who things work from the docs,  I guess.

--
  Han-Wen Nienhuys - [hidden email] - http://www.xs4all.nl/~hanwen


_______________________________________________
lilypond-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/lilypond-devel
Reply | Threaded
Open this post in threaded view
|

Re: An overview of the system

Han-Wen Nienhuys
In reply to this post by Don Blaheta
Don Blaheta wrote:
> When you type something that produces a bit of music, that musical thing
> is normally placed immediately after the thing you typed previously, and

only for sequential music. Try

  \score { << a b c d e >> }



> Any context can be created anonymously (\new) or named (\context).  
> When you create a new context, it is contained by the innermost open
> context that is able to contain it---e.g. if the Score, a Staff, and a
> Voice are open, and you create a new Voice, that new voice will be
> contained by the Staff, not the Voice.  This means that the textual
> nesting (what you see when you look at pairs of {}, <<>>, <>) may *not*
> reflect the logical nesting.  If you open a named context, and a context

Textual nesting as such doesn't really exist, internally. << >> and { }
  reflect time-wise relations between Music. Nothing more.

> * Side note: when trying to figure out whether Lyric contexts were
> actually contained by Staffs or became siblings, I typed the following:
>   \score {<<
>     \new Staff {
>       %\set Staff.fontSize = #3
>       <<
>         \new Voice { c }
>         \new Lyrics \lyricmode { x }
>         \new Lyrics \lyricmode { y }
>       >>
>     }
>     \new Voice { f }
>   >>}
> and when the \set is uncommented, suddenly the lyrics move below the
> second staff line.  Why is that?  (It certainly answered my question,
> though not quite the way I expected.)  It doesn't seem to matter what I
> \set there.

The order in which contexts appear on paper is the order in which they
are created. By putting \set in a sequence, you force everying following
it ( the << >> ) to be done after "opening" the outermost \new Staff .


> Just renamed, or is this a more fundamental change?  There are
> presumably still leaf nodes....

it's an internal change. The C++ class Event has disappeared, but of
course, there are still events. The definition of those has moved
entirely to the Scheme side.

> Maybe not "subclass" then, but I wanted to see the hierarchy; for
> example I can find out that a BeamEvent can be a general-music, event,
> beam-event, or span-event, but not that an Event is related to a
> BeamEvent, at least, not from the page on Event.  Even if you rearrange
> and rename the internals, I assume there will be some sort of hierarchy
> in there....

They are related through their 'types property. See
scm/define-music-types.scm for more information. Strictly speaking,
there is no hierarchy.

>>Iterators and translators decide that. If you need to know more, you can
>>either copy what others already did, or you can read the source code for
>>hints (usually, only gurus tweak Music properties, and most gurus know how to
>>read source code)
>>
>>In general, i'd advice you to look directly in the .scm files (scm/* wherever
>>lilypond's data files are), rather than the online docs. The .scm files
>>sometimes contain additional hints.
>
>
> So you're arguing against documenting the system?

No, against inferring how things work from the docs,  I guess.

--
  Han-Wen Nienhuys - [hidden email] - http://www.xs4all.nl/~hanwen


_______________________________________________
lilypond-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/lilypond-devel
Reply | Threaded
Open this post in threaded view
|

Re: An overview of the system

Don Blaheta
In reply to this post by Han-Wen Nienhuys
Quoth Han-Wen Nienhuys:
> Don Blaheta wrote:
> > When you type something that produces a bit of music, that musical thing
> > is normally placed immediately after the thing you typed previously, and
>
> only for sequential music. Try
>
>   \score { << a b c d e >> }

As I pointed out later in that paragraph, "unless you explicitly say
that two things happen simultaneously".  The reason this is important
to say is that it was not at *all* clear to me until this second round
of summary that timing and contexts had nothing to do with each other,
and *only* the simultaneity constructs (just <<>> and <> I think,
they're certainly the main ones) make things happen at the same time
(or, stack vertically, if you're thinking in graphical terms).

> > [...] This means that the textual nesting (what you see when you
> > look at pairs of {}, <<>>, <>) may *not* reflect the logical
> > nesting.  If you open a named context, and a context
>
> Textual nesting as such doesn't really exist, internally. << >> and { }
> reflect time-wise relations between Music. Nothing more.

I believe it, but again, it's important to say that, because a lot of
users (well, me at least, but I think it's more general) will see the
textual nesting and assume it's more significant than it is.

> > * Side note: when trying to figure out whether Lyric contexts were
> > actually contained by Staffs or became siblings, I typed the following:
> >   \score {<<
> >     \new Staff {
> >       %\set Staff.fontSize = #3
> >       <<
> >         \new Voice { c }
> >         \new Lyrics \lyricmode { x }
> >         \new Lyrics \lyricmode { y }
> >       >>
> >     }
> >     \new Voice { f }
> >   >>}
> > and when the \set is uncommented, suddenly the lyrics move below the
> > second staff line.  Why is that?  (It certainly answered my question,
> > though not quite the way I expected.)  It doesn't seem to matter what I
> > \set there.
>
> The order in which contexts appear on paper is the order in which they
> are created.

This part is well established, and I understood it;

> By putting \set in a sequence, you force everying following it ( the
> << >> ) to be done after "opening" the outermost \new Staff .

but this is the nonobvious part.  The key observation is that despite
the name \new, the context isn't actually constructed right away, not
until the first musical expression is seen.  An important secondary
observation is that \set and \override count for the purpose.  Neither
is obvious.

> > Maybe not "subclass" then, but I wanted to see the hierarchy; for
> > example I can find out that a BeamEvent can be a general-music, event,
> > beam-event, or span-event, but not that an Event is related to a
> > BeamEvent, at least, not from the page on Event.  Even if you rearrange
> > and rename the internals, I assume there will be some sort of hierarchy
> > in there....
>
> They are related through their 'types property. See
> scm/define-music-types.scm for more information. Strictly speaking,
> there is no hierarchy.

But there's an implicit hierarchy, and it's relevant, and it would be
useful to be able to find it in the docs.

--
-=-Don Blaheta-=-=-[hidden email]-=-=-=-<http://www.blahedo.org/>-=-
The reason computer chips are so small is computers don't eat much.


_______________________________________________
lilypond-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/lilypond-devel
Reply | Threaded
Open this post in threaded view
|

Re: An overview of the system

Erik Sandberg
In reply to this post by Don Blaheta
On Monday 12 December 2005 05.25, Don Blaheta wrote:
> > In general, i'd advice you to look directly in the .scm files (scm/*
> > wherever lilypond's data files are), rather than the online docs. The
> > .scm files sometimes contain additional hints.
>
> So you're arguing against documenting the system?

no, I'm just saying that the documentation currently isn't perfect, so in its
current state, it is sometimes better to read source code.

Currently nobody is working on this part of documentation, but we would
welcome anyone who did. See also the Implementation Documenter link on this
page (hint hint):
http://lilypond.org/web/devel/participating/call-for-help
.. and aprevious (cancelled) attempt:
http://mail-archive.com/lilypond-devel@.../msg06619.html

> > > Each context has a variety of properties that keep track of where the
> > > engraving process is---what measure it's in, whether it's in the middle
> > > of a triplet, etc.---as well as some general properties of the context,
> > > like the stanza number or whether to beam.
> >
> > BTW, the time keeping properties are usually stored centrally in the
> > Score context; the other contexts "inherit" those property settings. (You
> > can also tweak this to be set per staff, look for Timing_translator in
> > regression tests)
>
> Well, sure, but that *is* the sort of thing that contexts keep track of,
> right?

Contexts is a rather difficult subject. Things like those properties are
typically stored in contexts. Usually, some other datastructures _keep track_
of them, though (e.g., Timing_translator keeps track of some context
properties related to timing, IIRC.) But then again, translators "belong" to
contexts, so one could argue that contexts keep track of their translators,
which keep track of the context properties.

The context tree is basically a skeleton, which binds translators together,
and which holds context properties. It is important to understand that the
context tree just is a snapshot of this skeleton; the skeleton can change
over time.

> > > * In what order are the contexts visited---inside out?
> >
> > Bottom up. Events are sent to Voice context, which forwards the events to
> > Staff if they can't be swallowed.
>
> If they *can't* be swallowed?  I thought expressions were sent to more
> than one engraver.

Each event is *swallowed* by exactly one engraver. This means that the
engraver takes care of all remaining processing of that event.

The event is sometimes _sent_ to many engravers, but only one of them will
swallow it. (so if you add two Note_heads_engravers to the same context, only
the first of them will swallow notes). This detail is however rather
insignificant, and will probably change in v2.9+.

--
Erik


_______________________________________________
lilypond-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/lilypond-devel