\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 scores - set after finalizing duration = #'() % markup command to display complete time #(define-markup-command (duration layout props scoretag)(symbol?) (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 (ly:assoc-get scoretag duration 0 #t))) ))) x-ext y-ext) )) calcDuration = #(define-scheme-function (tag)(symbol?) (define (calc-duration 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 (acknowledgers ((volta-bracket-interface engraver grob source-engraver) (ly:message "saw volta bracket @ ~A" (ly:context-now context))) ((bar-line-interface engraver grob source-engraver) (let ((bar (ly:context-property context 'whichBar))) (if (not (equal? "|" bar)) (ly:message "bar ~A" bar)) )) ) (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 (assoc-set! duration tag dur)) ; set global duration (for the markup command) (ly:message "duration: ~A final" (format-time dur)) ) ))) #{ \with { \consists #calc-duration } #} ) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % example % TODO repeats are not included !! meta = { \tempo 4=90 s1*4 | \tempo 4=120 \repeat volta 3 { s1*4 } \alternative { { s1 } { s1*2 } { \tempo 4=100 s1 } } s1*4 } \score { \new Staff << \meta \repeat unfold 32 \relative c'' { bes4 a c b } >> \layout { \context { \Score \calcDuration scoreBACH } } \midi { } } \markup { \box \duration #'scoreBACH }