Hi Marc,

you already received some solutions, but I stumbled across this thread and just want to quickly show my engraver - perhaps it also helps.

It doesn't read repeats right now, but this may be solved with \unfoldRepeats and the engraver placed in the midi-block. The duration-markup-command relies on a global variable and a delayed stencil - this will not work with multiple scores, as only the duration of the last score will be displayed. But that is manageable, if needed.

HTH
Jan-Peter

Am 05.09.2016 um 11:01 schrieb Marc Hohl:
Hi list,

I have a couple of songs in my latest theatre project. It would be nice
to have something like "duration: 3'22''" at the end of each song.

Doing this by hand is straightforward:I generate a midi file that sounds
accurate and let it play by timidity – but IMHO it would be less tedious
and less error-prone if lilypond were capable of doing these
calculations itself.

Tempo indications and meter changes have to be taken into account, so
this is probably doable with a special engraver only IIUC.

Has someone else already done something like this? I have no experience
in writing scheme engravers, so any hint would be highly appreciated.

Thanks in advance,

Marc

_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user

\version "2.19.47"

% format seconds as min:sec
#(define-public (format-time dur)
   (let* ((minutes (floor (/ dur 60)))
          (seconds (round (- dur (* 60 minutes)) ) ))
     (format "~2'0d:~2'0d" (inexact->exact minutes) (inexact->exact seconds))
     ))

% complete duration of score - set after finalizing
duration = 0

% markup command to display complete time
#(define-markup-command (duration layout props)()
   (let* ((gauge-stencil (interpret-markup layout props "00:00"))
          (x-ext (ly:stencil-extent gauge-stencil X))
          (y-ext (ly:stencil-extent gauge-stencil Y)))
     (ly:make-stencil
      `(delay-stencil-evaluation
        ,(delay (ly:stencil-expr
                 (interpret-markup layout props (format-time duration))
                 )))
        x-ext y-ext)
     ))

% consist an engraver to collect time
\layout {
  \context {
    \Score
    \consists
    #(lambda (context)
       (let ((dur 0) ; duration in seconds
             (start (ly:make-moment 0)) ; last calc-time the duration was calculated
             )
         ; function to calculate duration in seconds since last calc-time
         (define (calc-dur)
           (let ((diff (ly:moment-sub (ly:context-now context) start) ) ; moment since last calc-time
                 (tempo (ly:context-property context 'tempoWholesPerMinute (ly:make-moment 60/4)) )) ; current tempo
             (set! start (ly:context-now context)) ; set calc-time
             (set! dur ; add 60*(diff/tempo) to duration
                       ; if tempo is 120 BPM and 120/4 elapsed,
                       ; we have 60 * 120/4 * 4/120 = 60 seconds
                   (+ dur
                     (* 60
                       (exact->inexact (ly:moment-main (ly:moment-div diff tempo)))
                       )))
             dur
             ))
         (make-engraver
          (listeners
           ((tempo-change-event engraver event)
            (calc-dur) ; calculate duration on every tempo-change-event (new tempo will be set after we listened to the event)
            (ly:message "duration: ~A" (format-time dur))
            )
           ) ; listeners
          ((finalize trans)
           (calc-dur) ; last calculation of duration
           (set! duration dur) ; set global duration (for the markup command)
           (ly:message "duration: ~A final" (format-time dur))
           )
          )))
  }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% example

% TODO repeats are not included !!

meta = { \tempo 4=90 s1*4 | \tempo 4=120 \repeat volta 2 { s1*4 } }

\score {
  \new Staff <<
    \meta
    \repeat unfold 8 \relative c'' { bes4 a c b }
  >>
  \layout { }
  \midi { }
}

\markup {
  \box \duration
}
_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to