Pedal gradual release

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Pedal gradual release

Andrew Bernard

I use a wedge type symbol to indicate gradual release of a piano pedal. Since this is not built in to lilypond, I developed code like the following to do the job, using PostScript. I don’t mind using PostScript as I am fluent in it, but objectively, this is terribly special case code. Is there anybody willing to generalise this and make it more user friendly for other people who don’t necessarily want to fiddle with PostScript and Reverse Polish Notation when we are just trying to write piano music.

 

[I know the code is dreadful and woefully inelegant, but it does the job!]

 

Any assistance most appreciated.

 

Andrew

 

 

%======

 

\version "2.19.82"

treble = {
  \clef treble
  \time 4/4
  \repeat unfold 12 { c'' }
  \bar "|."
}

bass = {
  \clef bass
  \time 4/4
  \repeat unfold 12 { c }
}

sustainPedal = {
  s4\sustainOn
  ^\markup {
    \postscript #"0.15 setlinewidth [0.3] 0 setdash 0 setlinecap
        6 -1.3 moveto 10.2 0.15 2 div add 2 rlineto currentpoint stroke
        moveto 0.15 setlinewidth [] 0 setdash 0 -2.2 rlineto stroke"
  }
  s s s s s\sustainOff
}


\markup { "Pedal gradual release example" }

\score {
  \new PianoStaff
  <<
    \new Staff { \treble }
    \new Staff { \bass }
    \new Dynamics { \sustainPedal }
  >>

  \layout {
    \context {
      \Dynamics
      pedalSustainStyle = #'bracket
    }
  }
}

 

%======

 


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Pedal gradual release

Valentin Villenave-3
On 1/20/19, Andrew Bernard <[hidden email]> wrote:
> generalise this and make it more user friendly

I assume you know about this example:
http://lsr.di.unimi.it/LSR/Item?id=698

My instinct would be to print the sustainPedal brackets normally, and
then hack the Sostenuto pedal stencil (in bracket mode as well so that
no text would be printed) so as to create the dotted line (that way,
users could specify exactly when the foot has to start releasing the
pedal with \sostenutoOn, and make \sostenutoOff and \sustainOff
coincide so that the triangle is closed at the right time).

I’d need a bit more time to test it, though.

V.

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Pedal gradual release

Aaron Hill
In reply to this post by Andrew Bernard
On 2019-01-20 3:04 am, Andrew Bernard wrote:

> I use a wedge type symbol to indicate gradual release of a piano
> pedal. Since this is not built in to lilypond, I developed code like
> the following to do the job, using PostScript. I don't mind using
> PostScript as I am fluent in it, but objectively, this is terribly
> special case code. Is there anybody willing to generalise this and
> make it more user friendly for other people who don't necessarily want
> to fiddle with PostScript and Reverse Polish Notation when we are just
> trying to write piano music.
>
> [ . . . ]

One option would be to exploit a Hairpin:

%%%%
sustainGradualRelease =
   -\tweak shorten-pair #'(0 . 1.35)
   -\tweak height #1
   -\tweak style #'dashed-line
   -\tweak self-alignment-Y #DOWN
   -\tweak to-barline ##f
   -\tweak stencil #(elbowed-hairpin '((0 . 0) (1 . 1)) #f)
   \<

sustainPedal = {
   s4\sustainOn s s\sustainGradualRelease s s s\!\sustainOff
}
%%%%

This is far from ideal, as a hairpin by default will attempt to align to
the right extent of the musical column (unless the column has a rest,
and then it aligns to the left).  The piano bracket aligns to the left,
so setting shorten-pair is needed to have the hairpin meet the piano
bracket.

You would need to adjust the edge-height of the piano bracket if you
want the triangular section to be taller.

-- Aaron Hill

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Pedal gradual release

Andrew Bernard
Hi Aaron,

What we really want is a lovely curved bezier spline! I appreciate your suggestion, but I personally would rather code PostScript than hack hairpins to be pedal dynamics. I went through all that when I tried to do this by hijacking text spanners, and it was never satisfactory.

The desire for nice gradual release curves was what led to a PostScript concept.


Andrew



_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Pedal gradual release

Aaron Hill
In reply to this post by Aaron Hill
On 2019-01-20 4:28 am, Aaron Hill wrote:

> One option would be to exploit a Hairpin:
>
> %%%%
> sustainGradualRelease =
>   -\tweak shorten-pair #'(0 . 1.35)
>   -\tweak height #1
>   -\tweak style #'dashed-line
>   -\tweak self-alignment-Y #DOWN
>   -\tweak to-barline ##f
>   -\tweak stencil #(elbowed-hairpin '((0 . 0) (1 . 1)) #f)
>   \<
>
> sustainPedal = {
>   s4\sustainOn s s\sustainGradualRelease s s s\!\sustainOff
> }
> %%%%
>
> This is far from ideal, as a hairpin by default will attempt to align
> to the right extent of the musical column (unless the column has a
> rest, and then it aligns to the left).  The piano bracket aligns to
> the left, so setting shorten-pair is needed to have the hairpin meet
> the piano bracket.

This version calculates the correct width by pretending the hairpin is
actually a piano pedal bracket and then customizing the stencil.  It
also responds to the grow-direction of the hairpin so you can use it for
gradually pressing and releasing the sustain:

%%%%
sustainGradual =
   -\tweak edge-height #'(0 . 1)
   -\tweak self-alignment-Y #DOWN
   -\tweak style #'dashed-line
   -\tweak stencil #(lambda (grob)
     (let* ((sten (ly:piano-pedal-bracket::print grob))
            (xex (ly:stencil-extent sten X))
            (yex (ly:stencil-extent sten Y))
            (cresc? (eqv? (ly:grob-property grob 'grow-direction) LEFT)))
       (ly:line-interface::line grob
         (car xex) (if cresc? (car yex) (cdr yex))
         (cdr xex) (if cresc? (cdr yex) (car yex)))))
   \etc

sustainGradualOn = -\sustainGradual \<
sustainGradualOff = -\sustainGradual \>


sustainPedal = {
   s4\sustainOn s s\sustainGradualOff s s s\!\sustainOff
   s s\sustainOn\sustainGradualOn s s\! s s\sustainOff
}
%%%%

There is an annoying alignment issue with the end of the dashed line not
meeting the piano pedal bracket.  Still trying to track down the
culprit.  (I suspect the piano pedal bracket itself is the one that is
not correct.)

-- Aaron Hill

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Pedal gradual release

Aaron Hill
In reply to this post by Andrew Bernard
On 2019-01-20 5:16 am, Andrew Bernard wrote:

> Hi Aaron,
>
> What we really want is a lovely curved bezier spline! I appreciate your
> suggestion, but I personally would rather code PostScript than hack
> hairpins to be pedal dynamics. I went through all that when I tried to
> do
> this by hijacking text spanners, and it was never satisfactory.
>
> The desire for nice gradual release curves was what led to a PostScript
> concept.

Ah, well how about something like this:

%%%%
gradualSustain = #(define-event-function (coords) (list?) #{
   -\tweak stencil #(lambda (grob)
     (let* ((sten (ly:piano-pedal-bracket::print grob))
            (xex (ly:stencil-extent sten X))
            (lenx (interval-length xex))
            (yex (ly:stencil-extent sten Y))
            (leny (interval-length yex))
            (thick (layout-line-thickness grob))
            (eh (ly:grob-property grob 'edge-height)))
       (ly:stencil-translate (ly:stencil-add
           (make-connected-line (list
             (cons 0 (car eh)) (cons 0 0)
             (cons lenx 0) (cons lenx (cdr eh))) grob)
           (make-connected-path-stencil coords thick lenx leny #f #f))
         (cons (car xex) (car yex)))))
   \sustainOn #})

sustainPedal = {
   s4-\tweak edge-height #'(1 . 2)
     \gradualSustain #'((0.3 0)(0.5 1.5 0.8 -0.5 1 1))
   s s s s s\sustainOff
}
%%%%

This doesn't have the dashed line for the curve, but I presume that
would be possible by digging more into make-connected-path-stencil.  
Unfortunately, I am running out of time to look at this further.

-- Aaron Hill

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Pedal gradual release

Aaron Hill
In reply to this post by Andrew Bernard
On 2019-01-20 5:16 am, Andrew Bernard wrote:

> Hi Aaron,
>
> What we really want is a lovely curved bezier spline! I appreciate your
> suggestion, but I personally would rather code PostScript than hack
> hairpins to be pedal dynamics. I went through all that when I tried to
> do
> this by hijacking text spanners, and it was never satisfactory.
>
> The desire for nice gradual release curves was what led to a PostScript
> concept.
I have been meaning to find a non-trivial project to allow me to dig
into LilyPond and Scheme more than I usually do.  Your use case of
gradual piano pedaling seemed a good fit.  As such, do not feel
compelled at all to make use of this.  Certainly, it would be nice if it
were actually used; but this has been a good learning exercise all the
same.

And I should definitely note this is still a work-in-progress:

%%%%
\version "2.19.82"

#(define ((gradual-piano-pedal-bracket shape) grob)
   (define (make-dashed-curve-stencil thick left right knots step)
     (define (curve param)
       (let ((param (/ (- param left) (- right left)))
             (degree (- (length knots) 1))
             (points (list-copy knots)))
         (for-each (lambda (outer) (for-each (lambda (inner)
             (list-set! points inner (+ (* (- 1 param) (list-ref points
(- inner 1)))
                                        (* param (list-ref points
inner)))))
           (iota (+ (- degree outer) 1) degree -1))) (iota degree 1))
         (list-ref points degree)))
     (define (nearest-even num) (* 2 (inexact->exact (floor (/ num 2)))))
     (let* ((steps (nearest-even (/ (- right left) step)))
            (step (/ (- right left) (- steps 1)))
            (x (iota steps left step))
            (y (map curve x)))
       (apply ly:stencil-add (map (lambda (n)
         (make-line-stencil thick (list-ref x n) (list-ref y n)
           (list-ref x (+ 1 n)) (list-ref y (+ 1 n)))) (iota (/ steps 2)
0 2)))))
   (let* ((stencil (ly:piano-pedal-bracket::print grob))
          (width (interval-length (ly:stencil-extent stencil X)))
          (height (ly:grob-property grob 'edge-height '(1 . 1)))
          (layout (ly:grob-layout grob))
          (thick (ly:output-def-lookup layout 'line-thickness))
          (x-scale (- width thick))
          (shape-left (map (lambda (arg) (* (first arg) x-scale)) shape))
          (shape-right (append (drop shape-left 1) (list x-scale)))
          (shape-knots (map (lambda (arg) (drop arg 1)) shape)))
     (if (grob::is-live? grob) (ly:stencil-add stencil
       (apply ly:stencil-add
         (filter-map (lambda (left right knots)
             (and (< 0 (length knots))
                  (make-dashed-curve-stencil thick left right knots
0.25)))
           shape-left shape-right shape-knots)))
       '())))

#(define (number-list-list? arg) (and (list? arg) (every number-list?
arg)))
gradualSustain = #(define-event-function (shape) (number-list-list?)
   #{ -\tweak stencil #(gradual-piano-pedal-bracket shape) \sustainOn #})

<<
   \new PianoStaff
   <<
     \new Staff { \clef treble \repeat unfold 8 c''4 }
     \new Staff { \clef bass \repeat unfold 8 c4 }
   >>
   \new Dynamics
     \with {
       pedalSustainStyle = #'bracket
       \override PianoPedalBracket.edge-height = #'(2 . 3)
     }
     { s4 s4*6\gradualSustain #'((0 2 2 0)(0.3)(0.4 0 5 -3 3))
s4\sustainOff }
>>
%%%%

\gradualSustain replaces \sustainOn, although a \sustainOff is still
needed to terminate the bracket.  The parameter to \gradualSustain
indicates the desired shape as a list of curve segments.  The first
value in each segment indicates the left edge of the segment, specified
as a fraction of the total bracket width.  The right edge is determined
by the next segment in the list.

When included, the remaining values in each segment list indicate the
desired height of the curve along the segment using an appropriately
ordered Bezier.  There is no limit on the number values you can provide,
as the code above computes Beziers of arbitrary order.

Breaking down the example above we have first a quadratic Bezier going
from 0% to 30% along the horizontal that begins at two staff spaces
above the base and ends at the bracket base.  The second entry in the
list omits height values which is shorthand for no curve but it serves
to terminate the first curve.  Finally, the last curve starts at 40% and
continues to the end using a cubic Bezier.

----

There are still several improvements I plan on making:

- Broken pedal brackets are not supported, as it tries to apply the same
curve to both parts.

- Curve segments are not connected visually if there is a discontinuity.
  I presume a solid vertical line would be sufficient to join the broken
ends, similar to how the ends meet the base of the pedal bracket.  
However, it might make sense for the vertical to be dashed as well.

- The dash width is hard-coded, but ideally should inherit the
'dash-fraction and 'dash-period properties or otherwise mimic existing
behavior.  Also, I did not account for line thickness, so the gaps are
too short.

- The dashes are independently computed per segment, so there is
non-uniformity as the algorithm attempts to have a perfect number of
dashes.  I should probably average the ideal step sizes to ensure
consistency throughout the whole shape, although I suspect I will have
to fudge a little when curves meet.  In that situation, the end points
of the touching curves should probably only have each one half of a
dash, so the two halves will appear as one.

- The dashes are computed based only on horizontal distance, which means
vertical movement stretches the dashes.  The actual arc length should be
factored in when computed the number of steps to ensure consistency
through each arc.


-- Aaron Hill
_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

gradual-pedal.cropped.png (20K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Pedal gradual release

Andrew Bernard
Hi Aaron,

This would be great to go in the openlilylib library when ready, Thanks for your help. I am sure that once available, many people will use this. It can go alongside my pedal decoration code there (down with the help of several others). Pedals have been somewhat neglected in lilypond, being rather restricted to 19c practice, with that awful Ped. font from 1850 or so.

Andrew


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Pedal gradual release

Hwaen Ch'uqi
Greetings Aaron,

This is very exciting what you are doing! I have nothing to offer but
encouragement. As a professional pianist, I can tell you that the
technique is hardly new. As a composer who loves LilyPond, the ability
to at last achieve this pedal marking with a degree of flexibility is
sorely needed and thus priceless. Thank you so much for your
endeavors.

Hwaen Ch'uqi


On 1/22/19, Andrew Bernard <[hidden email]> wrote:

> Hi Aaron,
>
> This would be great to go in the openlilylib library when ready, Thanks for
> your help. I am sure that once available, many people will use this. It can
> go alongside my pedal decoration code there (down with the help of several
> others). Pedals have been somewhat neglected in lilypond, being rather
> restricted to 19c practice, with that awful Ped. font from 1850 or so.
>
> Andrew
>

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user