On 09/09/2016 05:27 PM, Thomas Morley wrote:
Attached you'll find a different version.
I noticed that text-only tempos (\tempo "Andante") caused problems. See attached revision which fixes this. It also has improved code for detecting a missing initial tempo (to then supply the default one). See attached diff file for changes.
Cheers, -Paul
\version "2.19.47" printScoreDuration = { \once \override Score.RehearsalMark.direction = #DOWN \once \override Score.RehearsalMark.self-alignment-X = #RIGHT \mark "print-score-duration" } formatScoreDuration = #(define-scheme-function (dur)(exact?) "Returns the given duration as a formated markup containing minutes and seconds." (let* ((minutes (floor dur)) ;; Is using floor correct? (seconds (floor (* (- dur minutes ) 60))) (duration-string (format #f "Duration: ~a:~2,,,'0@a" minutes seconds))) #{ \markup \rounded-box \fontsize #-3 #duration-string #})) #(define (get-seconds lst rl) "Takes a list of kind '((#<Mom 17> 1/15) (#<Mom 31/2> 1/30) (#<Mom 0> 1/15)) Calculates the time passed between each moment. Returns the addition of it as an exact numerical value. " (if (null? (cdr lst)) (apply + rl) (get-seconds (cdr lst) (cons (* (cdr (cadr lst)) (ly:moment-main (ly:moment-sub (caar lst) (caadr lst)))) rl)))) #(define (score-duration-engraver context) (let* ((evts '()) (last-evt #f) (tempo-change-evts '()) (duration-marks '())) (make-engraver (listeners ((rhythmic-event engraver event) (set! last-evt (ly:event-property event 'length)) (set! evts (cons (ly:context-current-moment context) evts))) ((tempo-change-event engraver event) (let ((tempo-unit (ly:event-property event 'tempo-unit)) (metronome-count (ly:event-property event 'metronome-count))) ;; Accumulate pairs of "moment when it happens" and ;; "quotient of tempo-unit and metronome-count"in `tempo-change-evts' ;; for use in `get-seconds' ;; text-only tempo changes like \tempo "Andante" have no tempo-unit (if (and tempo-unit metronome-count) (set! tempo-change-evts (cons (cons (ly:context-current-moment context) ;; Hmm, ugly code... (/ (string->number (ly:duration->string tempo-unit)) metronome-count)) tempo-change-evts)))))) (acknowledgers ((mark-interface engraver grob source-engraver) (let ((mark-text (ly:grob-property grob 'text))) (if (and (string? mark-text) (string=? mark-text "print-score-duration")) (set! duration-marks (cons grob duration-marks)))))) ((finalize translator) (if (not (null? duration-marks)) (let* ((moment-zero (ly:make-moment 0)) ; add default tempo at moment zero, if one does not already exist (tempo-changes (if (or (null? tempo-change-evts) (not (equal? moment-zero (car (last tempo-change-evts))))) ;; 1/15 is default tempo, could this be accessed somewhere? (append tempo-change-evts (list (cons moment-zero 1/15))) tempo-change-evts)) (duration-before-last-tempo-change (get-seconds tempo-changes '())) (duration-after-last-tempo-change-without-last-dur (* (cdr (car tempo-changes)) (ly:moment-main (ly:moment-sub (car evts) (caar tempo-changes))))) (last-ev-duration (* (cdar tempo-changes) (ly:moment-main last-evt))) (final-duration (+ duration-before-last-tempo-change duration-after-last-tempo-change-without-last-dur last-ev-duration))) (for-each (lambda (g) (ly:grob-set-property! g 'text (formatScoreDuration final-duration))) duration-marks) (set! evts '()) (set! last-evt #f) (set! tempo-change-evts '()) (set! duration-marks '()))))))) \layout { \context { \Score \consists \score-duration-engraver } } %%%%%%%%%%%%%%%%%%%%%% %% EXAMPLE %%%%%%%%%%%%%%%%%%%%%% voiceI = \new Voice { \partial 4 c'4 \repeat unfold 61 c'4 \tempo 4=120 c'2. d'2 \tempo 8=120 c'2~ | \tuplet 3/2 { c'2 2 2 } \tempo "Andante" c'2 c'2 } voiceII = { \partial 4 cis'4 \printScoreDuration \repeat unfold 17 cis'1 %% fiddling with two simultaneous RehearsalMarks... cis'1*31/32 \printScoreDuration s1*1/32 \mark \default cis'1 } \score { << \voiceI \voiceII >> \layout { } \midi {} }
51,54c51 < (let ((tempo-unit < ;; Hmm, ugly code... < (string->number < (ly:duration->string (ly:event-property event 'tempo-unit)))) --- > (let ((tempo-unit (ly:event-property event 'tempo-unit)) 59,64c56,66 < (set! tempo-change-evts < (cons < (cons < (ly:context-current-moment context) < (/ tempo-unit metronome-count)) < tempo-change-evts))))) --- > ;; text-only tempo changes like \tempo "Andante" have no tempo-unit > (if (and tempo-unit metronome-count) > (set! tempo-change-evts > (cons > (cons > (ly:context-current-moment context) > ;; Hmm, ugly code... > (/ (string->number (ly:duration->string tempo-unit)) > metronome-count)) > tempo-change-evts)))))) 72,95c74,96 < (if duration-marks < (let* (;; default tempo, could this be grapped somewhere? < (default-tempo-setting (cons (ly:make-moment 0) 1/15)) < ; add default tempo, if not introduced at score-begin < (tempo-changes < (if (or (null? tempo-change-evts) < (not (equal? (last tempo-change-evts) < default-tempo-setting))) < (append < tempo-change-evts (list default-tempo-setting)) < tempo-change-evts)) --- > (if (not (null? duration-marks)) > (let* ((moment-zero (ly:make-moment 0)) > ; add default tempo at moment zero, if one does not already exist > (tempo-changes > (if (or (null? tempo-change-evts) > (not (equal? moment-zero > (car (last tempo-change-evts))))) > ;; 1/15 is default tempo, could this be accessed somewhere? > (append tempo-change-evts (list (cons moment-zero 1/15))) > tempo-change-evts)) 126a128,129 > \tempo "Andante" > c'2 c'2 139c142 < --- > cis'1
_______________________________________________ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user