2016-09-08 14:21 GMT+02:00 Marc Hohl <m...@hohlart.de>:
> 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
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to