lilypond-devel
[Top][All Lists]
Advanced

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

Re: translators / engravers / performers


From: David Santamauro
Subject: Re: translators / engravers / performers
Date: Fri, 26 Nov 2010 09:48:01 -0500

Reinhold, thanks for the detailed explanation ...

On Fri, 26 Nov 2010 13:30:21 +0100
Reinhold Kainhofer <address@hidden> wrote:

> Am Freitag, 26. November 2010, um 12:26:08 schrieb David Santamauro:
> > Greetings,
> > 
> > After browsing the code for a couple weeks, I have a few questions.
> > First, though, if there is a skeleton Performer, commented
> > thoroughly, please disregard the rest of this email and point me to
> > it. Otherwise...
> 
> Well, first, you are talking particularly about Performers. In fact,
> Engravers and Performers are exactly the same thing (all
> translator-derived), just with different purpose (engravers create
> graphical objects, performers create MIDI objects). So everything
> general said about performers is also true for engravers and vice
> versa.

Yes, thanks, that I understand.

> >   // this was taken from piano-pedal-performer.cc
> >   // I'm assuming this is what this performer is
> >   // is interested in "listening" to but what is
> >   // is being listened to? I don't see where the
> >   // symbol 'sustain' is defined.
> >   // DECLARE_TRANSLATOR_LISTENER (sustain);
> 
> This listens to music events of type sustain-event (defined in
> scm/define- event-classes.scm as a music event called sustain-event,
> and used in scm/define-music-types.scm for the SustainEvent).
> In particular, the \sustainOn command is defined (in
> ly/spanners-init.ly) as: sustainOn = #(make-span-event 'SustainEvent
> START)
> 
> DECLARE_TRANSLATOR_LISTENER is a macro, so it does lots of things in
> the background, including creating derived names from the passed name.

This is very valuable. So assuming I had a brilliant idea that was a
derivative of a span-event, let's call it "span-modulation-event"
that creates midi modulation swells. I would

a) ... possibly? do something so that my new event-representing symbols
are recognized by the parser

b) add my new event to the list of span-event in
scm/define-event-classes.scm

c) add an event "ModulationEvent" in scm/define-music-types.scm as

(ModulationEvent
  . (( description . "Execute a MIDI modulation swell.")
     ( types . (general-music span-event modulation-event) )
    )
)

d) add a definition in ly/spanners-init.ly, e.g.,
modulationStop = #(make-span-event 'ModulationEvent STOP)
modulationStart = #(make-span-event 'ModulationEvent START)

e) write my class Modulation_Performer

> >   // .. and my own
> >   DECLARE_TRANSLATOR_LISTENER (mySymbol);
> >   // My best guess is that a command \mySymbol
> >   // is what is being listened to and acted upon
> 
> Nope, it listens to all music-events (defined in
> scm/define-music-types.scm) of type mySymbol-event (hierarchy of the
> music-event types defined in scm/define-event-classes.scm).

In my fictitious case above

DECLARE_TRANSLATOR_LISTENER (modulation)

> > So a few major questions:
> > 
> > 1) what are the real steps to register a performer? Does this
> > include possible initialization / registration in an .ly script or
> > is the class definition sufficient?
> 
> Of course, you need the class definition and the implementation in a
> C++ file in the lily/ directory. the build system will automatically
> include all performers/engravers in the build without the need to
> adjust the makefile.

good to know.

> This makes the engraver/performer available to lilypond, but it is
> only used in a particular context if you \consist it in that context.
> This is usually done in ly/engraver-init.ly and in
> ly/performer-init.ly ... Of course, you don't have to do it
> system-wise, you can also just add the engraver to a context in your
> own lilypond file.

Assuming I wanted it system-wide in the Voice context, something like
this should suffice:

\context {
  \type "Performer_group"
  \name Voice
  % the rest and then ...
  % my new performer
  \consists "Modulation_performer"
}

> > 2) what are the overridable methods and what is the order and
> > function of each in the grand concept of a performer (or engraver).
> 
> The most important are (I think they are typically called in that
> order): -) void initialize ();
>       Called at the begin of score (or to be exact, when the
> engraver's context is created) to initialize everything needed.

What would be done here that the class constructor can't handle.

> Then iteration starts and for each moment, the following calls happen:
> 
> -) void start_translation_timestep ();   // At the begin of a moment

I'll dig a bit into moment(s).

> -) All LISTENER callbacks are executed for the music events they are
>       registered for
> 
> -) void process_music ();   
>       All music events for the current time step (=moment) have been
> received, so you have a clear picture of what relevant events
> happened at that moment and you can create the appropriate grobs
> (which should be announced with announce_grob, so other engravers can
> notice them), etc.

I'll dig a bit more into events available and how to access them.

This has been invaluable ... thanks again for helping me understand.

David





reply via email to

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