Engraver not getting an event

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

Engraver not getting an event

Aaron Hill
NOTE: I know that \bendAfter currently does not support all of the
usages below; this all is coming from my investigation into how to
enable such support.  My plan is to create a patched version of the
engraver in Scheme as a proof-of-concept; and if it works, I can port
the results back to C++ and submit a patch to the project.  But I have
hit an unexpected stumbling block...

Please consider the following:

%%%%
\version "2.19.82"

debug_bend_engraver = #(make-engraver
   (listeners
     ((bend-after-event engraver event)
       (format (current-error-port)
         "\ndebug_bend_engraver: bend-after-event during ~a at ~a"
         (ly:context-current-moment (ly:translator-context engraver))
         (ly:prob-property (ly:event-property event 'music-cause)
'origin)))))

\layout {
   \context {
     \Voice
     \consists \debug_bend_engraver
   }
}

\fixed g' {
   g \bendAfter #-4 d2.
   <g b>4 \bendAfter #-4 d2.
   <g \bendAfter #-4 b>4 d2.
   << { g4 \bendAfter #-4 } { b4 } >> d2.
}
%%%%

I would expect the above to print out a debug line per each
bend-after-event.  But oddly the third--the one attached to a note
within a chord--seems to go missing.

Adding in a \displayMusic doesn't really show anything different about
the third usage of \bendAfter.  Just like the first and fourth
occurrences, the bend-after-event is part of the articulations for the
corresponding note-events.  (The second instance is unique in that the
event is simply stored at the end of the chord's elements.)

It is my understanding that the event-chord-iterator handles
broadcasting all of the chord's elements, and then the
rhythmic-music-iterator will take care of broadcasting the articulations
for the note-events.  But that does not seem to be happening.

Where have I gone wrong in my thinking?


-- Aaron Hill

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

Re: Engraver not getting an event

David Kastrup
Aaron Hill <[hidden email]> writes:

> NOTE: I know that \bendAfter currently does not support all of the
> usages below; this all is coming from my investigation into how to
> enable such support.  My plan is to create a patched version of the
> engraver in Scheme as a proof-of-concept; and if it works, I can port
> the results back to C++ and submit a patch to the project.  But I have
> hit an unexpected stumbling block...
>
> Please consider the following:
>
> %%%%
> \version "2.19.82"
>
> debug_bend_engraver = #(make-engraver
>   (listeners
>     ((bend-after-event engraver event)
>       (format (current-error-port)
>         "\ndebug_bend_engraver: bend-after-event during ~a at ~a"
>         (ly:context-current-moment (ly:translator-context engraver))
>         (ly:prob-property (ly:event-property event 'music-cause)
> 'origin)))))
>
> \layout {
>   \context {
>     \Voice
>     \consists \debug_bend_engraver
>   }
> }
>
> \fixed g' {
>   g \bendAfter #-4 d2.
>   <g b>4 \bendAfter #-4 d2.
>   <g \bendAfter #-4 b>4 d2.
>   << { g4 \bendAfter #-4 } { b4 } >> d2.
> }
> %%%%
>
> I would expect the above to print out a debug line per each
> bend-after-event.  But oddly the third--the one attached to a note
> within a chord--seems to go missing.
>
> Adding in a \displayMusic doesn't really show anything different about
> the third usage of \bendAfter.  Just like the first and fourth
> occurrences, the bend-after-event is part of the articulations for the
> corresponding note-events.  (The second instance is unique in that the
> event is simply stored at the end of the chord's elements.)
>
> It is my understanding that the event-chord-iterator handles
> broadcasting all of the chord's elements, and then the
> rhythmic-music-iterator will take care of broadcasting the
> articulations for the note-events.  But that does not seem to be
> happening.
>
> Where have I gone wrong in my thinking?

_Either_ the Event_chord_iterator _or_ the Rhythmic_music_iterator are
doing the broadcasting of note events, depending on whether the notes
are within a chord or not.  _Only_ the Rhythmic_music_iterator
broadcasts articulations, so they are _only_ removed and broadcast for
non-chord notes, and actually only if there is a listener for them,
otherwise they are kept on the rhythmic event like articulations on
chord notes _always_ are.

If you want to do anything with chord note articulations, you have to
listen for the chord notes and look at their articulations property.

--
David Kastrup

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

Re: Engraver not getting an event

Aaron Hill
On 2019-04-02 4:26 am, David Kastrup wrote:

> Aaron Hill <[hidden email]> writes:
>> Where have I gone wrong in my thinking?
>
> _Either_ the Event_chord_iterator _or_ the Rhythmic_music_iterator are
> doing the broadcasting of note events, depending on whether the notes
> are within a chord or not.  _Only_ the Rhythmic_music_iterator
> broadcasts articulations, so they are _only_ removed and broadcast for
> non-chord notes, and actually only if there is a listener for them,
> otherwise they are kept on the rhythmic event like articulations on
> chord notes _always_ are.

Huh, I was so sure I saw recursion in the broadcasting of events.  I
need more coffee and/or sleep.  :/

Out of curiosity, how does Lilypond decide which iterator-ctor to
consult and instanciate?  Is it something like the outer container of
EventChord trumping the contained NoteEvents?  But then why does the
same not apply to SimultaneousMusic or SequentialMusic?

> If you want to do anything with chord note articulations, you have to
> listen for the chord notes and look at their articulations property.

Is there a best practice between listening for events vs. acknowledging
grobs?  I noticed that New_fingering_engraver--which needs to handle
articulations within chords--opts to acknowledge rather than listen.

Also, it does seem that special care would need to be taken to unify the
results of handling events that are broadcast vs. the ones that need to
be wrestled from the clutches of chords.  Or, would it be more
appropriate (read: sane) to never listen directly to such post-events
and instead just listen for the rhythmic-events, querying their
articulations as appropriate?  (The latter seems like it could be
inefficient.)


-- Aaron Hill

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

Re: Engraver not getting an event

David Kastrup
Aaron Hill <[hidden email]> writes:

> On 2019-04-02 4:26 am, David Kastrup wrote:
>> Aaron Hill <[hidden email]> writes:
>>> Where have I gone wrong in my thinking?
>>
>> _Either_ the Event_chord_iterator _or_ the Rhythmic_music_iterator are
>> doing the broadcasting of note events, depending on whether the notes
>> are within a chord or not.  _Only_ the Rhythmic_music_iterator
>> broadcasts articulations, so they are _only_ removed and broadcast for
>> non-chord notes, and actually only if there is a listener for them,
>> otherwise they are kept on the rhythmic event like articulations on
>> chord notes _always_ are.
>
> Huh, I was so sure I saw recursion in the broadcasting of events.  I
> need more coffee and/or sleep.  :/
>
> Out of curiosity, how does Lilypond decide which iterator-ctor to
> consult and instanciate?

scm/define-music-types.scm defines the iterator-ctor to use if not the
default.  And the default is

Music_iterator::get_static_get_iterator (Music *m)
{
  Music_iterator *p = 0;

  SCM ctor = m->get_property ("iterator-ctor");
  SCM iter = SCM_EOL;
  if (ly_is_procedure (ctor))
    {
      iter = scm_call_0 (ctor);
      p = unsmob<Music_iterator> (iter);
    }
  else
    {
      if (dynamic_cast<Music_wrapper *> (m))
        p = new Music_wrapper_iterator;
      else if (m->is_mus_type ("event"))
        p = new Event_iterator;
      else
        p = new Simple_music_iterator;

      iter = p->self_scm ();
      p->unprotect ();
    }

  p->music_ = m;
  assert (m);
  p->music_length_ = m->get_length ();
  p->start_mom_ = m->start_mom ();

  return iter;
}

> Is it something like the outer container of EventChord trumping the
> contained NoteEvents?

It's not a matter of "trumping".  Only the outermost music expression is
iterated.  Its own iterator may decide to do iteration of some contents.

> But then why does the same not apply to SimultaneousMusic or
> SequentialMusic?

It does.  Those are pretty complex iterators exactly because they need
to coordinate when to create/call iterators for their contained
expressions.

>> If you want to do anything with chord note articulations, you have to
>> listen for the chord notes and look at their articulations property.
>
> Is there a best practice between listening for events
> vs. acknowledging grobs?  I noticed that New_fingering_engraver--which
> needs to handle articulations within chords--opts to acknowledge
> rather than listen.

Well, it may need information regarding the respective grob placements
in order to place the articulations in relation to them.

> Also, it does seem that special care would need to be taken to unify
> the results of handling events that are broadcast vs. the ones that
> need to be wrestled from the clutches of chords.  Or, would it be more
> appropriate (read: sane) to never listen directly to such post-events
> and instead just listen for the rhythmic-events, querying their
> articulations as appropriate?  (The latter seems like it could be
> inefficient.)

It depends on what you want to achieve.  The string number engraver does
just that.  Historically (before the advent of the
Rhythmic_event_iterator) that implied that only in-chord notes could get
string numbers.

--
David Kastrup

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