lilypond-user
[Top][All Lists]
Advanced

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

Re: Metronome marking with non-integer value


From: Valentin Petzel
Subject: Re: Metronome marking with non-integer value
Date: Sun, 25 Jun 2023 13:12:15 +0200

Hello Lib,

this is a limitation of the Lilypond parser which implements the syntax

\tempo [text] [duration = ...]

Here it assumes that ... is an unsigned integer. This I think is not 
unreasonable, if you tell a musician to play something in MM 72.4 he will 
probably be a bit confused.

Anyway, the solution to the problem would be to simply not use this parser 
feature. \tempo is only a parser feature and not a music function as a music 
functions do not allow the 4 = 120 syntax and does not allow having two 
arguments both of which can be optional but one being mandatory.

But in the end \tempo ... still evaluates to a music event, as you can see if 
you do

\displayMusic \tempo "some text" 4 = 120

This creates two music events:

(make-music
  'TempoChangeEvent
  'metronome-count
  120
  'tempo-unit
  (ly:make-duration 2)
  'text
  "some text")

is the event that is responsible for creating the tempo mark and

(make-music
  'ContextSpeccedMusic
  'context-type
  'Score
  'element
  (make-music
    'PropertySet
    'value
    (ly:make-moment 30)
    'symbol
    'tempoWholesPerMinute))

is what makes midi tempo work (it basically sets Score.tempoWholesPerMinute to 
a moment of duration metronome marking * metronome base length, so in our case 
120 * 1/4 = 30.

So what you need to do to get non integral is to manually create the first 
thing:

{
  #(make-music
    'TempoChangeEvent
    'metronome-count
    72.4
    'tempo-unit
    (ly:make-duration 2)
    'text
    "Weird tempo")
  c
}

To get midi to work you’ll also need to do

\score {
  {
    #(make-music
      'TempoChangeEvent
      'metronome-count
      72.4
      'tempo-unit
      (ly:make-duration 2)
      'text
      "Weird tempo")
    \set Score.tempoWholesPerMinute = #(ly:make-moment (* 724/10 1/4))
    c
  }
  \layout { }
  \midi { }
}

If you do not what to do the conversion to rationals 72.4 → 724/10 yourself 
you can use (inexact->exact ...), but keep in mind that this will include 
rounding errors:

(inexact->exact 72.4) -> 2547348539231437/35184372088832

which is the representation of 72.4 with binary digits with machine precision 
(the denominator is 2^45).

Cheers,
Valentin

Am Sonntag, 25. Juni 2023, 11:44:59 CEST schrieb Lib Lists:
> Hello,
> 
> I realised that Lilypond doesn't like it if the metronome value is a
> non-integer. In the example below, assigning 7 to the voiceAmount
> variable triggers a 'error: not an unsigned integer'. I tried to
> construct the metronome number marking as a markup, but without
> success.
> 
> Any suggestions? The idea is to have the metronome markings values
> automatically generated, starting from 4 = 120 in the upper staff.
> Below both a M(non-)WE and the complete example
> 
> Thank you in advance for any help!
> 
> Cheers,
> Lib
> 
> %%% MWE %%%
> \version "2.25.5"
> \score {
>   \new Staff {
>     \tempo 4 = #(* 1 (/ 120 7 ))
>     { c' }
>   }
> }
> %%%
> 
> 
> %%% COMPLETE EXAMPLE %%%
> \version "2.25.5"
> 
> voiceAmount = 7
> 
> \score {
>   \new StaffGroup  <<
>     #@(map (lambda (i)
>     #{
>       \new Staff {
>         \scaleDurations #(cons voiceAmount i) {
>           \tempo 4 = #(* i (/ 120 voiceAmount ))
>           \relative c'' \repeat unfold #i {{c c c c }} \bar "||"
>         }
>       }
>       #})
>     (iota voiceAmount voiceAmount -1))
> 
> 
>   \layout {
>     \context {
>       \Score
>       \remove Metronome_mark_engraver
>       \cadenzaOn
>     }
>     \context {
>       \Staff
>       \remove Time_signature_engraver
>       \consists Metronome_mark_engraver
>     }
>   }
> }
> %%%

Attachment: signature.asc
Description: This is a digitally signed message part.


reply via email to

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