Detect slurred notes in callback function
Hi, is it possible to detect slurred notes in a callback function? I would like to use a callback function to modify properties of all slurred notes. Below is my unsuccessful attempt. The callback function receives NoteHead grob as argument. The grob itself doesn't seem to contain information about slur attached, so I get it's event-cause. I know that slurs are stored in the NoteEvent's "articulations" property, but this property either isn't accessible this way (the object returned by event-cause doesn't seem to be a regular NoteEvent; what is it actually?), or I fail to find the correct way to access it. --- #(define (in-slur? notehead) (begin (display "grob") (newline) (display-scheme-music notehead) (display "NoteEvent?") (newline) (display-scheme-music (event-cause notehead)) (display "try to dig slur") (newline) (display-scheme-music (ly:event-property (event-cause notehead) 'articulations)) #f)) \score { \relative c'' { \override NoteHead #'color = #(lambda (grob) (if (in-slur? grob) red blue)) a a a( a) a( a a) } } --- Thanks for any help, Jakub ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detect slurred notes in callback function
2016-02-07 14:30 GMT+01:00 Jakub Pavlík : > Hi, > > is it possible to detect slurred notes in a callback function? I would like > to use a callback function to modify properties of all slurred notes. > > Below is my unsuccessful attempt. > The callback function receives NoteHead grob as argument. The grob itself > doesn't seem to contain information about slur attached, so I get it's > event-cause. I know that slurs are stored in the NoteEvent's "articulations" > property, but this property either isn't accessible this way (the object > returned by event-cause doesn't seem to be a regular NoteEvent; what is it > actually?), or I fail to find the correct way to access it. > > --- > > #(define (in-slur? notehead) >(begin > (display "grob") > (newline) > (display-scheme-music notehead) > (display "NoteEvent?") > (newline) > (display-scheme-music (event-cause notehead)) > (display "try to dig slur") > (newline) > (display-scheme-music (ly:event-property (event-cause notehead) > 'articulations)) > #f)) > > \score { > \relative c'' { > \override NoteHead #'color = #(lambda (grob) > (if (in-slur? grob) > red > blue)) > > a a > a( a) > a( a a) > } > } > > --- > > Thanks for any help, > Jakub Hi Jakub, if you look at the terminal output of \displayMusic { a( a a) } then you'll notice that the middle note has no info whether it is under a slur or not. Only chance I see, is to get start and stop of the slur, and knowing this, get the NoteHeads between. Nevertheless, below a draft of improving your initial code, you'll see the midle note isn't catched. #(define (in-slur? notehead) (let ((tst (if (null? (map (lambda (m) (music-is-of-type? m 'slur-event)) (ly:music-property (ly:prob-property (event-cause notehead) 'music-cause) 'articulations))) #f #t))) (newline) (display-scheme-music tst) tst)) \score { \relative c'' { \override NoteHead #'color = #(lambda (grob) (if (in-slur? grob) red blue)) %\displayMusic { a( a a) } } } HTH a bit, Harm ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detect slurred notes in callback function
Hi Jakub, FWIW, here’s another approach that starts from slurs and goes to note heads. (Adapted from some code for tied notes where this works a little more cleanly since ties connect to note heads directly rather than to note columns…) Unfortunately, this one also doesn’t color notes in the middle of slurs, only those on the ends. And Harm’s code that deals with note heads directly is probably better for addressing that. Cheers, -Paul \version "2.19.36" #(define (color-slur-notes grob) (let* ((right-note-col (ly:spanner-bound grob RIGHT)) (left-note-col (ly:spanner-bound grob LEFT)) (right-notes (ly:grob-array->list (ly:grob-object right-note-col 'note-heads))) (left-notes (ly:grob-array->list (ly:grob-object left-note-col 'note-heads))) (color-notes (lambda (n) (ly:grob-set-property! n 'color red ; (display right-notes)(newline) (for-each color-notes right-notes) (for-each color-notes left-notes) )) \score { \relative c'' { \override Staff.Slur.before-line-breaking = #color-slur-notes a a a( a) a( a a) } } ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detect slurred notes in callback function
Thank you very much, now I know at least how to get from a grob to the corresponding music object. In order to "catch" the notes under a slur that aren't slur attach points ("middle notes") I tried to use a closure as the callback function and store information on the "slurred state" (in slur / not in slur) in a variable. Unfortunately the callback isn't executed for the notes in input order, but in a quasi-random fashion, so this technique isn't usable at all. It seems that a property callback function isn't a tool suitable for detecting and modifying all slurred notes. I hope that sooner or later I will find The Right Tool for the Job (TM). Jakub ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detect slurred notes in callback function
Hi Jakub, On Sun, Feb 7, 2016 at 12:45 PM, Jakub Pavlík wrote: > Thank you very much, now I know at least how to get from a grob to the > corresponding music object. > > In order to "catch" the notes under a slur that aren't slur attach points > ("middle notes") I tried to use a closure as the callback function and > store information on the "slurred state" (in slur / not in slur) in a > variable. Unfortunately the callback isn't executed for the notes in input > order, but in a quasi-random fashion, so this technique isn't usable at > all. It seems that a property callback function isn't a tool suitable for > detecting and modifying all slurred notes. > It would be interesting to see your code for this. This randomness was the topic of an earlier thread, and I wonder if your observation is related: http://www.mail-archive.com/lilypond-user%40gnu.org/msg106840.html > I hope that sooner or later I will find The Right Tool for the Job (TM). > > Slur grobs store a pointer to an array of NoteColumns they encompass. So, expanding on Paul's solution, you could do something like this: \version "2.19" #(define (color-slur-notes grob) (let* ((note-columns (ly:grob-array->list (ly:grob-object grob 'note-columns))) (note-heads (append-map (lambda (nc) (ly:grob-array->list (ly:grob-object nc 'note-heads))) note-columns)) (color-notes (lambda (n) (ly:grob-set-property! n 'color red (for-each color-notes note-heads))) \score { \relative c'' { \override Staff.Slur.before-line-breaking = #color-slur-notes a a a( a) a a( a ) } } HTH, David ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detect slurred notes in callback function
Hi David, thank you very much - actually this is just what I was looking for! It works great. > It would be interesting to see your code for this. This randomness was > the topic of an earlier thread, and I wonder if your observation is > related: > http://www.mail-archive.com/lilypond-user%40gnu.org/msg106840.html > I will try to reconstruct it (as I scraped it while trying other solutions) and post it here. Regards, Jakub ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detect slurred notes in callback function
> On Feb 7, 2016, at 5:42 PM, David Nalesnik wrote: > > Slur grobs store a pointer to an array of NoteColumns they encompass. So, > expanding on Paul's solution, you could do something like this: Very nice solution! Might be worth an LSR snippet as a good example of this kind of grob to grob access. Cheers, -Paul___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detect slurred notes in callback function
Hi David, as promised, here is my unsuccessful attempt based on a closure preserving state information between invocations. Regards, Jakub --- \version "2.19.32" #(define (contains-slur-event-with-direction? lst direction) (if (null-list? lst) #f (if (music-is-of-type? (car lst) 'slur-event) (eq? (ly:music-property (car lst) 'span-direction) direction) (contains-slur-event-with-direction? (cdr lst) direction #(define (notehead-articulations notehead) (let ((noteevent (ly:event-property (event-cause notehead) 'music-cause))) (ly:music-property noteevent 'articulations))) #(define (slur-opener? notehead) (contains-slur-event-with-direction? (notehead-articulations notehead) 1)) #(define (slur-closer? notehead) (contains-slur-event-with-direction? (notehead-articulations notehead) -1)) #(define (make-in-slur-callback inSlur notInSlur) (let ((slursOpen 0)) (display "+++ Factory executed") ; this closure will be executed for each NoteHead (lambda (grob) (begin (display "+++ Closure executed") ; to see the order of NoteHead the callback is called for (display-scheme-music (ly:event-property (event-cause grob) 'origin)) (cond ((slur-opener? grob) (set! slursOpen (+ slursOpen 1))) ((slur-closer? grob) (set! slursOpen (- slursOpen 1 (if (> slursOpen 0) (inSlur grob) (notInSlur grob))) ))) \score { \relative c' { \override NoteHead #'color = #(make-in-slur-callback (lambda (grob) red) (lambda (grob) black)) d e( f) g( a b c) } } ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user