3

I am in the process of engraving a sheet of piano music. I wrote a custom dynamic mark — the look of which I am very happy with, but the behavior, not totally. It is the following:

mff = \tweak DynamicText.self-alignment-X #LEFT
    #(make-dynamic-script 
    (markup 
        #:dynamic "mf"
        #:normal-text #:italic #:teeny "2ème fois"
        #:dynamic "f"))

When used, it looks like:

measure with "mf 2éme fois f" dynamic

When not used, it looks like:

same measure without dynamic, showing different spacing

I am happy with the mark beginning below the note to which it is attached (as opposed to centered below that note); but I would like that it doesn't postpone the next note until the mark is entirely written. Ideally, it would affect the bar width only if the line marking the end of the bar risks cutting-off the mark.

I can't find what I'm looking for in the documentation.

In case there is any need for it, here is my code for the music:

%% VERSION
\version "2.20.0"

\paper {
    #(include-special-characters)
}
    
mff = \tweak DynamicText.self-alignment-X #LEFT
    #(make-dynamic-script 
    (markup 
        #:dynamic "mf"
        #:normal-text #:italic #:teeny "2ème fois"
        #:dynamic "f"))

%% PIANO UP
pianoUpper = \relative c' {
    \override DynamicLineSpanner.staff-padding = #3
    \clef "treble"
    \key d \minor
    \time 4/4
        
    <\tweak font-size #-3 a f'>4 \f <\tweak font-size #-3 c g'> <f a> <d bes'> | 
    <f a>2 <e g> |
    f2. r4 \bar "||"
    <f a> \mf \< <f a> <f a> <f a>8 <a c> |
    <a c>4. <g bes>8 <f a>4 f \! |
        
    <f a> <f a>8 <e g> <f a>4 <f a>8 <a c> |
    <a c>4. \> <g bes>8 <f a>4 r \! |
    <f a> \p \< <f a> <f a> <f a>8 <a c> |
    <a c>4. <g bes>8 <f a>4 f \! |
    <f a> <f a>8 <e g> <f a>4 <f a>8 <a c> |
        
    <a c>4. \> <g bes>8 <f a>4 r \! |
    \repeat volta 2 {
        c'2\( d8 c bes a |
        bes2 c8 bes a g |
        a2 bes8 a g f |
        g4.\) g8 c,2 \> |
            
        <\tweak font-size #-3 a f'>4 \< <\tweak font-size #-3 c g'> <f a> <d bes'> |
    }
    \alternative { 
        {
            <f a>2 \> <e g>4 r \! | 
        }
        {
            <c a'>2\( <bes g'>\) |
            <a f'>2. r4 \bar "|."
        }
    }
}

%% PIANO LOW
pianoLower = \relative c {
    \clef "bass"
    \key d \minor
    
    f4 c f bes, |
    c2 <c, c'> |
    <f f'>4 c' f, r |
    f' <a c> f <a c> |
    c, <e bes' c> f <a c> | 

    f <a c> f <a c> |
    c, <e bes' c> <f a c> r |
    f <a c> f <a c> |
    c, <e bes' c> f <a c> | 
    f <a c> f <a c> |
        
    c, <e bes' c> <f a c> r |
    f <a c> d, <fis c'> |
    g, <g' bes d> c, <e bes' c> |
    f <a c> d, <f bes> |
    c <e bes c> c <e g> |
        
    f c f bes, |
    c2 c4 c |
    c2 <c, c'> |
    <f f'>4 c' f, r |
}

%% SCORE
\score {
    <<
        \new PianoStaff <<
            \new Staff = "upper" \pianoUpper
            \new Staff = "lower" \pianoLower
        >>
    >>
}
1
  • I think there's some commands to override the "self-alignment" and assign an absolute position. I know it's tough to find info in the LilyPond documentation but maybe someone will find that before I do. Commented Apr 29, 2020 at 15:25

4 Answers 4

4

You can explicitly set the dimension of your markup using \with-dimensions (or in this case, as we are already within the definition of a Scheme macro, #:with-dimensions. This macro takes two Scheme pairs that define the left and right as well as the bottom and top edge of the markup. The markup itself can be bigger than the box you define with these measures, and when typeset the bounding of this box will be used. (See the documentation for more information.)

Because \with-dimensions only accepts one argument, you need to additional wrap your markup in another \line macro. So, you could e.g. write your macro like this:

mff = \tweak DynamicText.self-alignment-X #LEFT
    #(make-dynamic-script 
    (markup #:with-dimensions '(0 . 5) '(-3 . 3) #:line 
       (#:dynamic "mf"
        #:normal-text #:italic #:teeny "2ème fois"
        #:dynamic "f")))

Result:

enter image description here

There are also several other ways of tweaking the dimensions and alignment of dynamics, some of which are explained in this snippet.

4

If you use this definition that looks just like a dynamic mark,

mff= _ \markup { \dynamic mf \italic \teeny "2ème fois" \dynamic f }

then the result is this:

enter image description here

2
  • "The interest of using make-dynamic-script instead of an ordinary markup is ensuring the vertical alignment of markup objects." is what I can read on the documentation : lilypond.org/doc/v2.18/Documentation/notation/… but your solution still seems to work in my specific case. Should I expect that sometimes it doesn't ? Like in other cases when I want a long custom dynamic mark and it might not vertically allign ? Commented Apr 29, 2020 at 21:43
  • After tests, I noticed that indeed, there are cases in which the vertical alignment is not maintained. I have already upvoted the answer, because it solved my issue in that case (even if only by luck). Commented Jun 16, 2020 at 21:54
2

I actually just created a function that would allow me to specify a dynamic and arbitrary text:

#(define-markup-command
  (staff-expr layout props text)
  (markup?)
  #:properties ((rel-fontsize 0))
  "Creates expression text for a staff.
   
   By default, staff expression text's font is reduced by 0.5
   and is italicized."
  (interpret-markup layout props
   (markup #:line
           (#:with-dimensions '(0 . 0) '(0 . 0)
            (#:fontsize rel-fontsize (#:italic text))))))

staffExpr =
#(define-scheme-function
  (text)
  (markup?)
  #{
    \markup \staff-expr #text
  #}
)

dynExpr = 
#(define-event-function
  (dyn expr) 
  (ly:event? markup?)
  #{
    \tweak DynamicText.self-alignment-X #LEFT
    #(make-dynamic-script
      #{
        \markup \concat {
          #(ly:music-property dyn 'text)
          \pad-x #.75
          \normal-text #expr
        }
      #}
    )
  #}
)

I probably could've done that more simply—as I'm seeing what was done by the OP, but I'm fairly new to Lilypond, myself.

In any event, here's the first two measures of Una Mattina by Ludovico Einaudi, where I used the functions above:

enter image description here

\version "2.22.2"

#(define-markup-command
  (staff-expr layout props text)
  (markup?)
  #:properties ((rel-fontsize 0))
  "Creates expression text for a staff.
   
   By default, staff expression text's font is reduced by 0.5
   and is italicized."
  (interpret-markup layout props
   (markup #:line
           (#:with-dimensions '(0 . 0) '(0 . 0)
            (#:fontsize rel-fontsize (#:italic text))))))

staffExpr =
#(define-scheme-function
  (text)
  (markup?)
  #{
    \markup \staff-expr #text
  #}
)

dynExpr = 
#(define-event-function
  (dyn expr) 
  (ly:event? markup?)
  #{
    \tweak DynamicText.self-alignment-X #LEFT
    #(make-dynamic-script
      #{
        \markup \concat {
          #(ly:music-property dyn 'text)
          \pad-x #.75
          \normal-text #expr
        }
      #}
    )
  #}
)

beamHeight =
#(define-music-function
  (startHeight endHeight)
  (number? number?)
  #{
    \override Beam.positions = #(cons startHeight endHeight)
  #}
)

Props = {
  \numericTimeSignature
  \time 4/4
  \key c \major
  \partial 16
}

RHVoiceOne = {
  \change Staff = "LH" a16~ |
  \stemUp \once \beamHeight #6.25 #6.25 a16 \stemDown \change Staff = "RH" e' a' \stemUp \change Staff = "LH" a \beamHeight #-6.25 #-6.25 \stemDown \change Staff = "RH" e' a' \stemUp \change Staff = "LH" a \stemDown \change Staff = "RH" e' a' \stemUp \change Staff = "LH" a \stemDown \change Staff = "RH" e' a' \once \beamHeight #6.5 #7.5 \stemUp \change Staff = "LH" a \stemDown \change Staff = "RH" e' b' e' |
  \stemUp \change Staff = "LH" \once \beamHeight #6.25 #6.25 a16 \stemDown \change Staff = "RH" e' a' \stemUp \change Staff = "LH" a \beamHeight #-6.25 #-6.25 \stemDown \change Staff = "RH" e' a' \stemUp \change Staff = "LH" a \stemDown \change Staff = "RH" e' \once \beamHeight #-5.75 #-6.25 a'8. \stemUp \change Staff = "LH" b16 \once \beamHeight #7.75 #8.75 c' \stemDown \change Staff = "RH" e' g' b' |
}

Dynamics = {
  \override DynamicText.X-offset = #0.59125 \override DynamicText.Y-offset = #1.75
  % Note the use of \dynExpr that takes a dynamic marking and some text
  s16 | s16 \dynExpr \p \staffExpr legato s16 s8 s4 * 3 | s1 |
}

Sustain = {
  s16 \sustainOn |
  s1 |
  s2 s8 s8\sustainOff s4 |
}

LHVoiceOne = {
  s16 | s1 | s1 |
}

\paper {
  system-system-spacing = #'((basic-distance . 18))
  %annotate-spacing = ##t
  first-page-number = 10
  evenHeaderMarkup = \markup \null
  oddHeaderMarkup = \markup \null
  evenFooterMarkup = \markup {
    \fill-line {
      \center-column {
        \on-the-fly \first-page
        \fromproperty #'header:copyright
        \vspace #1.807
        \null
        \italic
        \on-the-fly \print-page-number-check-first
        \fromproperty #'page:page-number-string
      }
    }
  }
  oddFooterMarkup = \evenFooterMarkup
}
\score {
  \new GrandStaff \with {
  } <<
    \new PianoStaff \with {
      \override StaffGrouper.staff-staff-spacing.basic-distance = #13.65
    } <<
      \new Staff = "RH" \with {
      } <<
        \new Voice = "1" { 
          \Props
          \RHVoiceOne
        }
      >>
      \new Dynamics {
        \Dynamics
      }
      \new Staff = "LH" \with {
      } {
        \clef bass << 
          \new Voice = "1" {
            \Props
            \LHVoiceOne
          }
        >>
      }
      \new Dynamics = "Sustain" \with {
        pedalSustainStyle = #'mixed
        \override PianoPedalBracket.thickness = #1.35
        \override SustainPedalLineSpanner.staff-affinity = #UP
        \override PianoPedalBracket.Y-offset = #-1.6
        \override SustainPedal.X-offset = #-0.75
        \override SustainPedal.Y-offset = #-1.75
      } {
        \Sustain
      }
    >>
  >>
  \layout {
  }
  \midi {
  }
}
3
  • In this case you might consider using the \whiteout command. Commented Nov 1, 2022 at 1:46
  • Actually, I specifically did not want \whiteout in this case--as the original score looked this way. Also, if I hadn't adjusted used the line (#:with-dimensions...), then the text would've "pushed" the barline over--but again, something I specifically was trying to avoid. But yes, had I not wanted the overlapping barlines (but keeping the measure dimensions the same), \whiteout would've done the trick! Commented Nov 2, 2022 at 1:56
  • 1
    Personally, I when I'm re-engraving a piece I take lots of liberties; "fixing" "mistakes" etc., I would probably move that dynamic mark to over the first note and use the \whiteout command to cross the barline—because that would make more sense, and be much easier to read (for me). However I can definitely understand why you'd prefer to make a more faithful copy. Commented Nov 3, 2022 at 12:45
1

I know nothing of the intricacies of LilyPond. But this is normally notated simply and sufficiently as mf-f. Would suggesting you notate it that way be considered a solution?

1
  • Good point. I like K.I.S.S. solutions. Commented Apr 30, 2020 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.