Hi all, Follow up question: is there a way to know the "parent" of the voices as they are defined in the code? In the following example, I would like to determine that voice "two" splits off from voice "one" without relying on the context-id. (ly:context-parent ctx) gives me the staff, not the "parent voice"...
\score { \new Staff { \time 2/2 << \new Voice = "one" { \relative c'' { \voiceOne g8 e } << \new Voice = "two" { \voiceOne \relative c'' { a8. g16 f8 e16 f g f e d } } \new Voice = "three" { \voiceTwo \relative c' { c8 a d8. c16 b8 a16 b } } >> } \new Voice = bottom { \voiceTwo \relative c' { g1 } } >> } } Thanks in advance! cheers Maurits > Van: Aaron Hill <lilyp...@hillvisions.com> > Onderwerp: Antw.: detecting the start and end of a polyphonic passage from > scheme > Datum: 25 juni 2020 17:12:13 CEST > Aan: lilypond-user@gnu.org > > > On 2020-06-25 7:01 am, Maurits Lamers wrote: >> Hi all, >> I am trying to build a system based on the listener system which can >> identify voices in a piece of music. >> I use a listener to the Voice context to give me the note events. >> In the following passage I can use (ly:context-id >> (ly:translator-context engraver) to get the id, which is empty for c4, >> "1" for the first voice, "2" for the second voice, and empty again for >> d4 at the end. >> time 4/4 \relative c' { c4 << { c8 d e4 } \\ { c8 b c4 } >> d4 | } >> However in the following passage the context-id cannot be used because >> it is not set. >> \relative c' { >> \new Voice { >> c4 >> << >> \new Voice { >> c8 d e4 >> } >> \new Voice { >> c8 b c4 >> } >> >> >> d4 >> } >> } >> I am currently using object properties to follow these voices by >> setting a unique value for that voice context object, but that doesn't >> help me >> to detect properly the start and end of the polyphonic passage. The >> main voice gets 1, the first nested voice will be 2, the second nested >> voice will be 3. >> For transcription purposes it would be very helpful to detect the >> start and end of the polyphonic passage. Is this possible? > > The initialize and finalize procedures of an engraver will run when the > context in which it is \consisted begins and ends. Consider: > > %%%% > \version "2.20.0" > > #(define custom-uid > (let ((custom-uid-prop (make-object-property)) > (last-uid 0)) > (lambda (obj) > (or (custom-uid-prop obj) > (begin > (set! last-uid (1+ last-uid)) > (set! (custom-uid-prop obj) last-uid) > last-uid))))) > > handle-init-and-final = > #(lambda (context) > (make-engraver > ((initialize engraver) > (let* ((ctxt (ly:translator-context engraver)) > (id (ly:context-id ctxt)) > (uid (custom-uid ctxt)) > (now (ly:context-now ctxt))) > (format #t "\ninitialize: ~s, id=~s, uid=~s, now=~s" > ctxt id uid now))) > ((finalize engraver) > (let* ((ctxt (ly:translator-context engraver)) > (id (ly:context-id ctxt)) > (uid (custom-uid ctxt)) > (now (ly:context-now ctxt))) > (format #t "\nfinalize: ~s, id=~s, uid=~s, now=~s" > ctxt id uid now))))) > > \layout { \context { \Voice \consists \handle-init-and-final } } > > { \relative c' { \new Voice { c4 > << \new Voice = foo { \voiceOne c8 d e4 } > \new Voice { \voiceTwo c8 b c4 } >> d4 } } } > %%%% > > ==== > . . . > Parsing... > Interpreting music... > initialize: #<Context Voice () >, id="", uid=1, now=#<Mom -infinity> > initialize: #<Context Voice=foo () >, id="foo", uid=2, now=#<Mom 1/4> > initialize: #<Context Voice () >, id="", uid=3, now=#<Mom 1/4> > finalize: #<Context Voice=foo () >, id="foo", uid=2, now=#<Mom 3/4> > finalize: #<Context Voice () >, id="", uid=3, now=#<Mom 3/4> > finalize: #<Context Voice () >, id="", uid=1, now=#<Mom 1> > Preprocessing graphical objects... > . . . > ==== > > NOTE: I am using Scheme object properties to attach a custom unique > identifier to the contexts as they are seen, so it is possible to discern > which context is which even when they are not named. > > > -- Aaron Hill > > > > > _______________________________________________ > lilypond-user mailing list > lilypond-user@gnu.org > https://lists.gnu.org/mailman/listinfo/lilypond-user