[Top][All Lists]
[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