2016-09-08 14:21 GMT+02:00 Marc Hohl <[email protected]>:
> Hi Harm,
>
> thanks a lot for your engraver, works out of the box!
>
> Best regards,
>
> Marc
Hi Marc,
you're welcome.
Attached you'll find a different version.
It avoids creating all those grobs and killing most of them in the
end. Instead a preexisting RehearsalMark (or more of them) is taken
and 'text is reset.
Some other changes for better usability.
HTH,
Harm
\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
;; Hmm, ugly code...
(string->number
(ly:duration->string (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'
(set! tempo-change-evts
(cons
(cons
(ly:context-current-moment context)
(/ 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 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))
(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 }
}
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
}
\score {
<<
\voiceI
\voiceII
>>
\layout { }
\midi {}
}
_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user