Hi Marc,

nice to hear, that you have a workflow.
For the record I noted two things in the file. (And if there's some spare time, I might further work on it.)

1. The durations are tagged by score and stored in an a-list, so you can first collect durations in multiple scores and display them later with a score-unique tag. 2. There are acknowledgers for volta-brackets and barlines. It should be possible to use that information for acknowledging volta repeats and ajusting the duration accordingly. Those grobs are created by engravers, but if one creates the barlines *not* with \repeat volta, but with \bar ".|:", it should be acknowledged too.

Cheers
Jan-Peter


Am 15.09.2016 um 08:10 schrieb Marc Hohl:
Am 14.09.2016 um 14:24 schrieb Marc Hohl:
[...]
I thought of writing the duration to a external file to be read from
within the markup call in the score to be printed, but did not follow
this route any further yet.

Update: a simple test file shows that this works.

I can

- compute the total duration of a file designed for
  midi output only by means of your engraver
- write the duration to a file and
- read that string while processing the "print-only" file.

Merging that stuff together with some Makefile should be
straightforward, I hope ;-)

And it has the advantage that some MIDI-related changes do not appear in
the printed score, but the duration will be updated accordingly.

Cheers,

Marc


_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
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 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
}
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to