0

Looking at Force note beams to be horizontal, I see how I can force beams to be horizontal. The accepted answer works only for stem-up notes. If there are also stem-down notes, there's a mess.

So I have this code that puts the stem-down beams where I want them, but stem-ups have their beams placed right where the stem-downs have their beams.

\score {
  \new Staff {
    \key d \major
    \time 2/4
    \override Beam.positions = #'(-4.5 . -4.5)
    \repeat volta 2 {
       \bar ".|:"
      \grg G8[\grd a] \wbirl a8. b16
      \thrwd d8. e16 \grg f4
      \dble e8 d \dblb b8[\thrwd d]
      \dblf f8 e \dblf f8 A

enter image description here

I'm also getting complaints about the stem-ups. I thought this was because the stem-ups are gracenotes. This corresponds to first four notes in the bar above.

filename.ly:57:16: warning: weird stem size, check for narrow beams
          \grg 
               f8 A \grg A4

But if I reverse the signs, using \override Beam.positions = #'(4.5 . 4.5), the gracenotes are rendered with their stems visible and beams in correct position. The other notes (stem down) are mangled. The stems on these stem-up notes look fine.

enter image description here

  1. How do I have one override of Beam.positions for stem-ups and a different one for stem-downs.
  2. How do I get rid of that
0

1 Answer 1

3

When doing \override Beam.positions you are explicitly telling Lilypond where to put the beam, and it is up to you to give positions that make sense. The positions are measured in staff-spaces from the middle line. So -4.5 is 2.5 staff spaces over the top line, 4.5 is 2.5 ss under the bottom line. This does not make sense when the stem goes in the wrong direction (or if the notes are way up or down).

This leads to this problem of the stem not being able to be drawn, as the beam is in the wrong direction:

{
  \override Beam.positions = #'(-4.5 . -4.5)
  c''8 d'' \appoggiatura { f''16 g'' f'' } e''8 f''
}

Of course you can always specify your own positions:

<<
  {
    \override Beam.positions = #'(4.5 . 4.5)
    c''8 d'' e''8 f''
  }
  \\
  {
    \override Beam.positions = #'(-4.5 . -4.5)
    c''8 b' a' g'
  }
>>

But if you read my answer to your linked question here you’ll see that it is in fact possible to tell Lilypond to only do horizontal Beams:

\layout {
  \context {
    \Voice
    \override Beam.damping = #+inf.0
  }
}

<<
  {
    c''8 d'' e''8 f''
  }
  \\
  {
    c''8 b' a' g'
  }
>>

{
  c''8 d'' \appoggiatura { f''16 g'' f'' } e''8 f''
}

Here Lilypond will place the Beams as it seems it, but only do horizontal positions.

If you to actually want the beam to be in a specific position you can use a callback to depend on the direction:

\layout {
  \context {
    \Voice
    \override Beam.positions =
    #(lambda (grob)
       (let ((d (ly:grob-property grob 'direction)))
         (cons (* d 4.5) (* d 4.5))))
  }
}

<<
  {
    c''8 d'' e''8 f''
  }
  \\
  {
    c''8 b' a' g'
  }
>>

{
  c''8 d'' \appoggiatura { f''16 g'' f'' } e''8 f''
}

But note that this does again imply that you know that these are good positions. See this comparison for what this means:

m = <<
  {
    c''8 d'' e''8 f''
  }
  \\
  {
    c''8 b' a' g'
  }
>>

\score {
  \layout {
    \context {
      \Voice
      \override Beam.positions =
      #(lambda (grob)
         (let ((d (ly:grob-property grob 'direction)))
           (cons (* d 4.5) (* d 4.5))))
    }
  }
  {
    #@(map
     (lambda (i) (transpose (ly:make-pitch 0 0) (ly:make-pitch 0 (- i)) (ly:music-deep-copy m)))
     (iota 10))
  }
}

\score {
  \layout {
    \context {
      \Voice
      \override Beam.damping = #+inf.0
    }
  }
  {
    #@(map
     (lambda (i) (transpose (ly:make-pitch 0 0) (ly:make-pitch 0 (- i)) (ly:music-deep-copy m)))
     (iota 10))
  }
}

EDIT: Also if you for example want only one direction to be fixed and the other one (such as grace notes) spaced regularly you can do stuff like this:

\layout {
  \context {
    \Voice
    \override Beam.positions =
    #(grob-transformer
      'positions
      (lambda (grob orig)
        (let ((d (ly:grob-property grob 'direction)))
          (if (= d UP)
              orig
              (cons (* d 4.5) (* d 4.5))))))
  }
}

<<
  {
    c''8 d'' e''8 f''
  }
  \\
  {
    c''8 b' a' g'
  }
>>

{
  c''8 d'' \appoggiatura { f''16 g'' f'' } e''8 f''
}
2
  • Thanks! The last example here is the most useful because it turns out that I also need the beam positions to be different depending on stem direction. After remembering how to think lispy, I found that replacing orig with a cons expression with a different distance, things work out, look good, and Lilypond prints no complaints. This will allow me to engrave bagpipe tunes for pipers who are used to the way Bagpipe Music Writer does it.
    – Frotz
    Dec 4, 2023 at 0:58
  • @Frotz Hm, but then you should rather use an approach like 4. grob-trasformer is a syntax candy function that creates a callback that evaluates the default property and calls a procedure that may make use of that. If you are not going to make use of it, rather use a simple (lambda (grob) ...) callback.
    – Lazy
    Dec 4, 2023 at 8:48

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.