lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: arbitrary repeat counter


From: Jean Abou Samra
Subject: Re: arbitrary repeat counter
Date: Wed, 1 Jun 2022 16:50:46 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.9.1

Le 01/06/2022 à 15:50, Simon Bailey a écrit :
Hi Jean,

thanks for that example. Is it supposed to print any numbers? It's not
doing so in 2.23.9 (windows, frescobaldi).


I tested it with 2.22. There were some changes (by me) in
the internals of MeasureCounter in 2.23, so it needs to
be adapted a little:


\version "2.23.9"

newRepeatMarker = #(make-music 'MeasureCounterEvent 'mark-new-repeat #t)

repeatCounting =
#(define-music-function (n music) (index? ly:music?)
   #{
     \startMeasureCount
     \repeat unfold #n { \newRepeatMarker #music }
   #})

#(define (My_counter_engraver context)
   (let ((count 1)
         (count-here #f)
         (spanner #f)
         (spanner-to-end #f))
     (make-engraver
      (listeners
       ((measure-counter-event engraver event)
        (cond
         ((eqv? LEFT (ly:event-property event 'span-direction))
          (set! count 1))
         ((ly:event-property event 'mark-new-repeat #f)
          (set! count-here #t)))))
      ((process-music engraver)
       (if count-here
           (let ((col (ly:context-property context 'currentCommandColumn)))
             (set! spanner (ly:engraver-make-grob engraver 'MeasureCounter '()))
             (ly:spanner-set-bound! spanner LEFT col)
             (ly:grob-set-property! spanner 'text (number->string count)) ;;; <====== here
             (set! count (1+ count)))))
      (acknowledgers
       ((bar-line-interface engraver grob source-engraver)
        (if spanner-to-end
            (let ((col (ly:context-property context 'currentCommandColumn)))
             (ly:spanner-set-bound! spanner-to-end RIGHT col)
             (ly:engraver-announce-end-grob engraver spanner-to-end '())
             (set! spanner-to-end #f)))))
      ((stop-translation-timestep engraver)
       (if spanner
           (set! spanner-to-end spanner))
       (set! spanner #f)
       (set! count-here #f)))))

\layout {
  \context {
    \Staff
    \consists #My_counter_engraver
  }
}

\new Staff \relative c' {
  \repeatCounting 4 { c4. 8 r4 8 r | d4. 4. 4 | 1 }
}



I've come up with a slightly different approach, that's not quite
finished (and not as fancy as creating a new engraver):

#(set-object-property! 'phrase-length 'backend-type? integer?)
#(define (counter-stencil grob)
    (let* ((counter (string->number (ly:grob-property grob 'text)))
           (phrase-length (ly:grob-property grob 'phrase-length)))
      (if (and (eq? (modulo counter phrase-length) 1) (>= counter 
phrase-length))
          (ly:stencil-aligned-to
           (grob-interpret-markup grob
             (markup (number->string (ceiling (/ counter phrase-length)))))
           Y
           CENTER))))

\relative c' {
   \set countPercentRepeats = ##t
   \override PercentRepeatCounter.phrase-length = 4
   \override PercentRepeatCounter.stencil = #counter-stencil
   \repeat percent 12 { c d e f }
}

I intend to wrap that in a music function that does all the override
magic and will take the music as a parameter (maybe work out the
phrase length from that, or pass it manually) and number of repeats.



Yes, that works too. Good job :-)

Best,
Jean




reply via email to

[Prev in Thread] Current Thread [Next in Thread]