lilypond-user
[Top][All Lists]
Advanced

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

Re: How to catch post-events inside chords in an event listener?


From: Lukas-Fabian Moser
Subject: Re: How to catch post-events inside chords in an event listener?
Date: Mon, 7 Feb 2022 20:17:55 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0

Hi Jean,

(CC'ing Harm because I'm using your code to demonstrate my ignorance.)

I'm just still confused as to the terminology of event "classes" vs. event 
"types" etc. But that's something for next week...
Allow me to take advance on next week by an hour, then (in Paris time, that is). The terms "music class" and "event class" are well-defined. But there is confusion because the 'types property of music objects holds music classes, and this is also what extract-typed-music uses. If you want to make an analogy with grobs, you would, on the contrary, use "type" for one music "definition" (that is the term the Internals Reference uses) and not a class grouping several of them. But in the context of grobs, a "class" is something else entirely, it refers to the four hardcoded grob classes Item, Spanner, Paper_column and System. What would most closely resemble music and event classes in the grob world is grob "interfaces". It's a holy mess ...
Wow. Thanks. (And luckily Paris and Salzburg share a time zone.)

So here's what made me stumble: In scm/scheme-engravers.scm, we find

(define-public (event-has-articulation? event-type stream-event)
  "Is @var{event-type} in the @code{articulations} list of @var{stream-event}?"
  (if (ly:stream-event? stream-event)
      (any
       (lambda (evt-type) (eq? evt-type event-type))
       (append-map
        (lambda (art) (ly:prob-property art 'types))
        (ly:prob-property
         (ly:prob-property stream-event 'music-cause)
         'articulations)))
      #f))

written by Harm.

I wondered why this is not written as, for example:

(define-public (event-has-articulation? event-type stream-event)
  "Is @var{event-type} in the @code{articulations} list of @var{stream-event}?"
  (if (ly:stream-event? stream-event)
      (any
       (lambda (art-ev)
         (memq event-type (ly:event-property art-ev 'class)))
       (ly:event-property stream-event 'articulations))
      #f))

Or to be more precise, I made two changes only the first of which I actually understood:

1) "append-map"'ping the types of all articulations and then checking if "any" is "eq?" can certainly be simplified to checking if "any" fulfills a "memq". (Of course, this causes a 'true' return value to not being identical to #t, but that should be ok.)

2) But I wondered why Harm's code goes stream-event -> music-cause -> articulations -> 'types property instead of stream-event -> articulations -> 'class property.

Am I right now in thinking that Harm's code reads the articulations from the music objects that caused a stream event, while "my" variant only sees those articulations that survive into the stream event itself? And the difference would be that those articulations from non-chord notes for which there is a dedicated listener are removed, as David explained? (See example code below that seems to confirm this.)

And do I understand you correctly that the difference between Harm asking for 'types and me asking for 'class is just that for whatever historical reasons, the event classes of articulations-as-music is stored in 'types, whereas they are stored in 'class for articulations-as-stream-events?

If all of this is more-or-less true, I think I'd like to add some comments explaining this (to me, quite subtle) difference in the code. And anyhow, reading lily/music-scheme.cc and lily/stream-event-scheme.cc, I seem to understand that ly:prob-property directly specialises to ly:music-property and ly:event-property for music and (stream) events, so probably one could/should use the more specialised functions in Harm's code?

Lukas

\version "2.22"

#
(define (HARMevent-has-articulation? event-type stream-event)
  "Is @var{event-type} in the @code{articulations} list of @var{stream-event}?"
  (if (ly:stream-event? stream-event)
      (any
       (lambda (evt-type) (eq? evt-type event-type))
       (append-map
        (lambda (art) (ly:prob-property art 'types))
        (ly:prob-property
         (ly:prob-property stream-event 'music-cause)
         'articulations)))
      #f))

#
(define (LFMevent-has-articulation? event-type stream-event)
  "Is @var{event-type} in the @code{articulations} list of @var{stream-event}?"
  (if (ly:stream-event? stream-event)
      (any
       (lambda (art-ev)
         (memq event-type (ly:event-property art-ev 'class)))
       (ly:event-property stream-event 'articulations))
      #f))

#(define (test_engraver ctx)
   (make-engraver
    (listeners
     ((note-event engraver event)
      (format #t "Note ~a encountered at ~a.\n"
              (ly:event-property event 'pitch)
              (ly:context-current-moment ctx))
      (format #t "Do I have tie (Harm): ~a\n"
              (HARMevent-has-articulation? 'tie-event event))
      (format #t "Do I have tie (lfm): ~a\n\n"
              (LFMevent-has-articulation? 'tie-event event))))))

\new Voice \with {
  \consists #test_engraver
} {
  a~ % Tie not seen in stream event
  <a~> % Tie is seen in stream event
}

\new Voice \with {
  \consists #test_engraver
  \remove Tie_engraver
} {
  c~ <c~> % All ties survive to stream event
}




reply via email to

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