Detect slurred notes in callback function

2016-02-07 Thread 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
___
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 Thread Thomas Morley
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

2016-02-07 Thread Paul Morris
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

2016-02-07 Thread Jakub Pavlík
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

2016-02-07 Thread David Nalesnik
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

2016-02-11 Thread Jakub Pavlík
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

2016-02-11 Thread Paul Morris
> 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

2016-02-14 Thread Jakub Pavlík
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