lilypond-user
[Top][All Lists]
Advanced

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

Re: Note head as a custom image chosen according to note duration


From: Valentin Petzel
Subject: Re: Note head as a custom image chosen according to note duration
Date: Tue, 22 Nov 2022 00:13:29 +0100

Hello Jean,


the line


\once \override NoteHead.stencil = #ly:text-interface::print


tells Lilypond to derive the symbol it uses for the note head as if the note head was some sort of text object (changed the old syntax NoteHead #'stencil to the new prefered syntax NoteHead.stencil). Then


\once \override NoteHead.text =

\markup {

    \general-align #Y #CENTER {

    \epsfile #X #2 #"./custom.eps"

    }

}


tells Lilypond what sort of text this text object has, which in this case uses the markup-command


\epsfile axis size file


to include an eps file. As Jean already said these properties NoteHead.stencil and NoteHead.text may either be actual values, or they may be callbacks, that is functions with the graphical object (grob) itself as argument.


(lambda (vars ...) body)


creates an anonymous function, so #(lambda (grob) ...) simply creates a function suitable for such callbacks. This callback can then choose the appearance depending on the duration of the NoteHead.


The duration of the NoteHead is not in fact a property of the grob, but of the music event that leads to creation of the grob, accessible from the grob by the "cause"-property. Thus Jean uses


(ly:event-property (event-cause grob) 'duration)


to get the duration of the note head and then uses different markups for different values.


That being said, in my opinion the whole route of going eps -> stencil -> markup -> stencil is overly complicated, instead we can skip the whole text-interface step and directly use the stencil generated from the eps-file:


customHead =

\once \override NoteHead #'stencil = #(ly:stencil-aligned-to (eps-file->stencil X 2 "custom.eps") Y CENTER)


{ e'4 f' \customHead g'4 }


Or with Jeans callback:


\version "2.22"


customHead =

 \once \override NoteHead.stencil =

   #(lambda (grob)

      (ly:stencil-aligned-to

       (case (ly:duration-log (ly:event-property (event-cause grob) 'duration))

         ((0) (eps-file->stencil X 2 "custom1.eps"))

         ((1) (eps-file->stencil X 2 "custom2.eps"))

         ((2) (eps-file->stencil X 2 "custom4.eps"))

         ((3) (eps-file->stencil X 2 "custom8.eps"))

         (else empty-stencil))

       Y CENTER))


{

   \customHead c'1

   \customHead c'2

   \customHead c'4

   \customHead c'8

}



Cheers,

Valentin


Am Montag, 21. November 2022, 19:07:22 CET schrieb Jean Abou Samra:

> Le 21/11/2022 à 13:43, Jean Faure a écrit :

>

> > Hi. The code below is a copy&paste, I do not quite understand what it

> > does. Can I modify it so that an image is chosen according to the

> > following note's duration? Like custom4.eps, custom8.eps?

> >

> >

> >

> > customHead = {

> >  \once \override NoteHead  #'stencil = #ly:text-interface::print

> >  \once \override NoteHead #'text =

> >    \markup {

> >      \general-align #Y #CENTER {

> >        \epsfile #X #2 #"./custom.eps"

> >      }

> >    }

> >  }

> > { e'4 f' \customHead g'4 }

>

>

>

>

>

> Yes, use a callback for that:

>

>

> \version "2.22.2"

>

> customHead = {

>    \once \override NoteHead.stencil = #ly:text-interface::print

>    \once \override NoteHead.text =

>      #(lambda (grob)

>         #{

>            \markup \general-align #Y #CENTER

>                #(case (ly:duration-log (ly:event-property (event-cause

> grob) 'duration))

>                   ;; whole note:

>                   ((0) #{ \markup \epsfile #X #2 "custom1.eps" #})

>                   ;; half note:

>                   ((1) #{ \markup \epsfile #X #3 "custom2.eps" #})

>                   ;; quarter note:

>                   ((2) #{ \markup \epsfile #X #4 "custom4.eps" #})

>                   ;; eighth note:

>                   ((3) #{ \markup \epsfile #X #5 "custom8.eps" #})

>                   ;; Add more here if necessary (keeping the "else" line

> below).

>                   (else ""))

>         #})

> }

>

> {

>    \customHead c'1

>    \customHead c'2

>    \customHead c'4

>    \customHead c'8

> }

>

>

>

>

> Have a look at these pages:

>

> https://lilypond.org/doc/v2.22/Documentation/extending/callback-functions

> https://extending-lilypond.readthedocs.io/en/latest/backend.html#understandi

> ng-callbacks

 

> Best,

> Jean

>



Attachment: signature.asc
Description: This is a digitally signed message part.


reply via email to

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