lilypond-devel
[Top][All Lists]
Advanced

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

Re: Help on handling both rests and notes in one engraver


From: Neil Puttock
Subject: Re: Help on handling both rests and notes in one engraver
Date: Sat, 9 May 2009 20:58:24 +0100

2009/5/9 Carl D. Sorensen <address@hidden>:
> Over the past few months, several people have asked for a "N.C." notation to
> be part of the ChordNames context.
>
> It occurred to me that using r to generate a "N.C." would be logically
> consistent -- the music gets a rest, the chord name gets a "N.C.".  And if a
> user wants to put space in without generating a "N.C." chordname, a spacer
> rest would work.  Of course, there would also be a property to disable the
> N.C. notation.

If you have a property (like chordNameSeparator) which returns a
markup, you won't need another property to disable the `N.C.: you can
simply return without creating a ChordName if the property isn't set.

> With this in mind, I decided to modify the chord_name_engraver to accept
> both rests and notes.  Searching through the internals reference, I found
> only one engraver that handles both rests and notes -- the
> bass_figure_engraver.
>
> Using the bass_figure_engraver as a pattern, I decided to add some code to
> lily/chord_name_engraver.cc.
>
> I put the following code in:
>
> IMPLEMENT_TRANSLATOR_LISTENER (Chord_name_engraver, rest);
> void
> Chord_name_engraver::listen_rest (Stream_event *ev)
> {
>  new_event_found_ = true;
>  rest_event_ = ev;
> }
>
> I think this makes the context accept a rest event.
>

This should probably be set once using the macro ASSIGN_EVENT_ONCE (),
though I can't envisage many situations with chord names where
somebody might have polyphonic rests. :)

> In bass_figure_engraver.cc, there is a start_translation_timestep that sets
> rest_event_ = 0.
>
> In chord_name_engraver.cc, there is no start_translation_timestep.
>
> Question 1: What do start_translation_timestep and stop_translation_timestep
> do?  When are they called?  Why do some engravers have
> start_translation_timestep and some don't?

I'd also like to know this.

I get the impression that stop_translation_timestep () is called after
music has been processed at each timestep, whereas
start_translation_timestep () will be called right at the beginning,
even if there's no music to process, then at the start of each
timestep.

It appears that the engravers which use both tend to make typesetting
decisions based on start and stop moments rather than just
acknowledging grobs or listening to events.

In the case of the Chord_name_engraver, there's no need to have
start_translation_timestep, since it waits for note events to come
along at each timestep, then creates a ChordName grob if it's gathered
any. Once it's done the processing work, stop_translation_timestep ()
ensures that everything's clear before the next set of notes arrives.

> My thought was that in Chord_name_engraver::process_music, I would first
> check to see if rest_event_ was != 0.  If so, I'd make the markup be "N.C.",
> set last_chord_ to some unique value (perhaps a scheme identifier 'no-chord,
> although I'm not sure yet how to do that, but I can find it in the Guile
> reference docs), set rest_event_=0, create a ChordName item and set its text
> property to the "N.C." markup, and return.

Are you proposing that the chordNameFunction would return the markup?

It would be simpler to have a property read by the engraver, e.g.
noChordMarkup, which would be read instead of calling the markup
procedure when a rest is found.  Then you can rely on the default
consing of the values for last_chord_ instead of having to set a
symbol identifying it as "no-chord".

Regards,
Neil




reply via email to

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