lilypond-user
[Top][All Lists]
Advanced

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

Re: Changing slur behavior


From: Aaron Hill
Subject: Re: Changing slur behavior
Date: Thu, 26 Mar 2020 06:54:51 -0700
User-agent: Roundcube Webmail/1.4.2

On 2020-03-26 2:24 am, Kevin Barry wrote:
I think the right way to do what you are trying is to write an
engraver that listens for slur events and alters the spacing of the
music. (I would write one if I could, but I'm not at that level yet.)

Firstly, know that slurs are not the only way to define melismata. You can instruct LilyPond to have a single lyric syllable span multiple notes using \melisma and \melismaEnd:

%%%%
\version "2.20.0"

\fixed c' { b4( g a2) | b4\melisma g a2\melismaEnd }
\addlyrics { one two }
%%%%

This does not solve the spacing aspect of the original post, but it shows how you can avoid messing about with slurs.

Assuming you really want to use slurs to adjust spacing, here might be one way to do it:

%%%%
\version "2.20.0"

Slur_spacing_engraver =
#(lambda (context)
  (let ((slur-event-dir #f))
    (define (change-spacing dir)
      (ly:broadcast
        (ly:context-event-source context)
        (ly:make-stream-event
          (ly:make-event-class 'spacing-section-event)
          '(())))
      (let ((score-context (ly:context-find context 'Score)))
        (for-each
          (lambda (args)
            (apply ly:context-pushpop-property
              score-context 'SpacingSpanner
              (if (< 0 dir) (drop-right args 1) args)))
          `((base-shortest-duration ,(ly:make-moment 8))
            (shortest-duration-space 1)
            (spacing-increment 1)))))
    (make-engraver
      ((start-translation-timestep engraver)
        (set! slur-event-dir #f))
      (listeners
        ((slur-event engraver event)
          (let ((dir (ly:event-property event 'span-direction #f)))
            (set! slur-event-dir dir))))
      ((process-music engraver)
        (if (ly:dir? slur-event-dir)
          (change-spacing slur-event-dir))))))

<< \context Voice = "melody" \with {
     \consists "Melody_engraver"
     \override Stem.neutral-direction = #'()
     \consists \Slur_spacing_engraver
     \omit Slur
   } \fixed c' {
     | b4 f8 g16 c' a2
     | b4( f8 g16 c' a2)
     | b4 f8 g16 c' a2
   }
   \context Lyrics \lyricsto "melody" {
     | "normal spacing" _ _ _ _
     | "tightly-spaced"
     | "normal spacing" _ _ _ _
   } >>
%%%%

The engraver listens for slur-events, injecting a spacing-section-event and adjusting some context properties as needed. The logic is very simple, and there are no safety checks. Be warned this likely could fail with more complicated music.


-- Aaron Hill

Attachment: slur-spacing.cropped.png
Description: PNG image


reply via email to

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