lilypond-user
[Top][All Lists]
Advanced

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

Re: Time measurement


From: Lukas-Fabian Moser
Subject: Re: Time measurement
Date: Thu, 14 Mar 2024 22:54:28 +0100
User-agent: Mozilla Thunderbird

Hi,

Am 14.03.24 um 17:27 schrieb Kieren MacMillan:
Hi Matthew,

Is there any easy way to find out the time in seconds from the start of a
score to a specified point, corresponding to the timing of the MIDI
output?  I can count measures and do math on the tempo, but that's
less than ideal in the face of multiple tempo changes.  Another idea would
be to just cut the score at the desire point and then measure the length
of the MIDI output file.  I can already manually examine the MIDI output,
find the desired point in the music, and record its timing, but that's
a fair bit of work.

I only really need to do this for a few points, a few times, and I just
want to know the numbers, not necessarily typeset them.  But a more
automated method along the lines of a \midiTime markup that would actually
typeset the time to that point automatically, would be fun too.
“This sounds like a job for… Custom Engraver!!”  :)

It sure does.

\version "2.25.3"

#(set-object-property! 'physicalTime 'translation-type? real?)

Time_measuring_engraver =
#(lambda (context)
   (let
    ((previous-timestep #f)
     (now ZERO-MOMENT)
     (current-tempo #f)
     (elapsed-time 0.0))

    (make-engraver
     ((initialize engraver)
      (ly:context-set-property! context 'physicalTime elapsed-time))
     ((start-translation-timestep engraver)
      (set! now (ly:context-current-moment context))
      (let*
       ((current-delta (- now previous-timestep))
        (current-timespan (/ current-delta current-tempo)))
       (set! elapsed-time (+ elapsed-time (* 60 current-timespan))))
      (ly:context-set-property! context 'physicalTime elapsed-time))
     ((stop-translation-timestep engraver)
      (set! previous-timestep now)
      (set! current-tempo (ly:context-property context
'tempoWholesPerMinute))))))

\layout {
  \context {
    \Score
    \consists #Time_measuring_engraver
    tempoWholesPerMinute = \musicLength 1*15 % LilyPond's default
  }
}

displayPhysicalTime = \applyContext
#(lambda (context)
   (ly:message "Elapsed time: ~as" (ly:context-property context
'physicalTime)))

{
  \tempo 4 = 120
  \tuplet 3/2 { a4 \displayPhysicalTime a a } \displayPhysicalTime a2
  \displayPhysicalTime
  \tempo 4 = 80
  a1 \displayPhysicalTime
}

Look at LilyPond's log.

It would be absolutely possible to also let this number be typeset (e.g.
as a TextMark), but this needs a dedicated engraver again as far as I
can see: They form the link between time-dependent context information
and grobs. A general \midiTime markup can't work conceptually, I think,
as markups may live independently of any music.

Lukas

Lukas




reply via email to

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