3

I would like to create a function which would automate some tempo changes in my score (it would be hidden on the score with something like \override Score.MetronomeMark #'transparent = ##t, indeed the goal is to add a bit of expressiveness into the MIDI output).

I manage to add a tempo change on the score (with #(make-music 'TempoChangeEvent ...)), but it doesn't affect the MIDI output, like \tempo would do. But it is exactly what I would need though.

I tried to change the context property tempoWholesPerMinute, but it does nothing at all.

\version "2.18.2"
\language "english"

mytempo = #(define-music-function (music) (ly:music?)
  #{
    #(make-music 'TempoChangeEvent
      'metronome-count 180
      'tempo-unit (ly:make-duration 2))

    \applyContext #(lambda (context)
      (ly:context-set-property! context
        'tempoWholesPerMinute
        (ly:make-moment 180 3)))

    #music
  #})

\score {
  \new Staff \relative c' {
    \mytempo c
    d e f g
  }
  \layout {}
  \midi {}
}

How can I change the MIDI tempo by using a custom function?

1 Answer 1

4

The tempoWholesPerMinute property is interpreted by the Tempo_performer which lives in Score context, so changes in your current context are not visible to the performer. So you need

(ly:context-set-property (ly:context-find context 'Score) ...

or alternatively

\context Score \applyContext ...

In general, if you know what kind of LilyPond construct produces something you desire and you want to express it in Scheme without conveniently just writing #{ ... #}, it is easiest to just put \displayMusic before it in its LilyPond form and then read what appears in the console output.

Here \tempo 4 = 60 will produce

(make-music
  'SequentialMusic
  'elements
  (list (make-music
          'TempoChangeEvent
          'metronome-count
          60
          'tempo-unit
          (ly:make-duration 2)
          'text
          '())
        (make-music
          'ContextSpeccedMusic
          'context-type
          'Score
          'element
          (make-music
            'PropertySet
            'value
            (ly:make-moment 15)
            'symbol
            'tempoWholesPerMinute))))

which basically (in the second half) corresponds to

\set Score.tempoWholesPerMinute = 15

that is implemented by LilyPond as a case of

\context Score ...
1
  • Thank you very much, I didn't think about calling \displayMusic with \tempo:) It's working now, by adding (make-music 'ContextSpeccedMusic ...)
    – yolenoyer
    Sep 19, 2021 at 12:44

Your Answer

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

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