(I posted a substantially identical question to music.stackexchange, but I
have heard that this list is a better place to ask.)

I've been working with some music that requires a LOT of metric
modulations. So far I have janky functions to draw these:

--- begin code
\version "2.25.26"

#(define (ratio-width ratio)
  (+ (truncate (log10 (car ratio)))
     (truncate (log10 (cdr ratio)))
     2))

metricMod =
#(define-music-function (ratio bpm) (fraction? number?)
  (define shortening (* (ratio-width ratio) -1))
  #{
    \textMark \markup {
      \hspace #(- (* shortening 2) 1)
      \rhythm {
        \override TupletBracket.bracket-visibility = ##t
        \override TupletNumber.text = #tuplet-number::calc-fraction-text
        \override TupletBracket.shorten-pair = #(cons shortening shortening)
        \override TupletBracket.edge-height = #'(0 . 0.7)
        \tuplet #ratio { 4 }
      }
      \hspace #(+ shortening 1)
      =
      \rhythm { { 4 } }
      =
      #(number->string bpm)
    }
    \once \set Score.tempoHideNote = ##t
    \tempo 4 = #bpm
  #})

metricModTwo =
#(define-music-function (ratio1 ratio2 bpm) (fraction? fraction? number?)
  (define shortening (* (max (ratio-width ratio1) (ratio-width ratio2))
                        -1))
  #{
    \textMark \markup {
      \hspace #(- (* shortening 2) 1)
      \rhythm {
        \override TupletBracket.bracket-visibility = ##t
        \override TupletNumber.text = #tuplet-number::calc-fraction-text
        \override TupletBracket.shorten-pair = #(cons shortening shortening)
        \override TupletBracket.edge-height = #'(0 . 0.7)
        \tuplet #ratio1 { \tuplet #ratio2 { 4 } }
      }
      \hspace #(+ shortening 1)
      =
      \rhythm { { 4 } }
      =
      #(number->string bpm)
    }
    \once \set Score.tempoHideNote = ##t
    \tempo 4 = #bpm
  #})

\relative c'' {
  \tempo 4 = 60
  c2 c |
  c c |
  \metricMod 3/2 90
  c c |
  c c |
  \metricModTwo 2/3 5/4 75
  c c |
  c c |
}
--- end code

While this is generally good enough, there are a few pain points:

* I have a separate command for a nested tuplet, mainly because I don't
know the Scheme interface well enough to generate a tree of tuplets from a
list of ratios. (This is a skill issue and I can figure it out eventually.)
* The spacing is not great. I would prefer the first “=” to be centered
between the tuplet note and the normal note, and I want the normal note to
be in the same position as the usual “\tempo 4 = n” command would produce
(aligned with the left edge of the measure—here I just approximated it).
Because the spacing is hard-coded it doesn't scale with the markup (if I
decide to make these markings smaller, for example).
* The logic to unsquish the bracket is imperfect, sometimes looking OK and
sometimes ugly. Ideally the span of the bracket beyond the numbers remains
constant, and the whole bracket+numbers assembly would be moved to the left
if it takes up too much room, even if the number is no longer centered
above the note, but I couldn't figure out how to do that.
* If the marking appears at the beginning of a line, it protrudes into the
left margin. It seems the common practice is to keep the equation of notes
on the previous line, and leave the numeric metronome marking at the start
of the new line, but I don't know how to accomplish this in Lilypond.

How can I address these issues?

I have looked through the snippet repository but there is only one metric
modulation snippet at https://lsr.di.unimi.it/LSR/Item?id=1124, which is
entirely hardcoded (drawing a tuplet bracket using PostScript commands!) I
think \rhythm is a superior method, but tweaks are still required.

Thanks,
Asher

Reply via email to