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 20:21:57 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.9.1

Le 01/06/2022 à 19:03, Simon Bailey a écrit :
Here's a weird one. Using this definition in the c,-octave, I get a
really weird output. Each note in the music drops down an octave. In
the c-octave, it works normally. Using the untagged version of
\repeatCounting doesn't show this issue in either octave.
Any ideas?


Ah, yes. Here's a definition that already works better:

repeatCountingWithTags = #(define-music-function (n music) (index? ly:music?)
  #{
    <<
      \tag #'score \repeat unfold #n { $music }
      \tag #'part \repeatCounting #n { $music \bar "!|" }
    >>
  #})


Namely, it uses $music instead of #music. More details
are here:
https://extending-lilypond.readthedocs.io/en/latest/lily-and-scheme.html#hash-vs-dollar
and here:
https://extending-lilypond.readthedocs.io/en/latest/music.html#copying-music
Basically, for the sake of efficiency, all music functions
are allowed to mutate their input. When you do \variable
in LilyPond code, this actually makes a deep copy of the
content of the variable (at least if it's a music object).
That way, users don't have surprises with music objects
shared between several locations, and music functions can
freely mutate music objects they receive. What's happening
here is that in order to interpret the relative octaves,
\relative walks in the music and converts the pitches
to absolute as needed. In this case, the pitches end up
on the octave of "c,". After that's done on the first
part tagged with #'score, it's done again on the second
one, which shares identity with the first and thus contains
lots of "d,", which get interpreted by \relative as lowering
the octave at every note.

Still, this isn't ideal because it doesn't work on something
like

\repeatCountingWithTags n { d' d }

as that translates to

<<
  \tag #'score \repeat unfold n { d' d }
  \tag #'part { [...] \repeat unfold n { [...] d' d } }
>>

and the second time the music occurs is affected by the
relative octave that the first time left. Of course, you
can fix it by playing with the pitches yourself in the
Scheme code. It's much simpler, however, to rewrite
this definition so that the argument gets just once
into the output. Giving:


\version "2.23.9"

#(define (Phrase_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)
             (if (> count 1)
               (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 #Phrase_counter_engraver
  }
}

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

\defineBarLine "!|" #'("!|" "" " |")

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

repeatCountingWithTags = #(define-music-function (n music) (index? ly:music?)
  #{
    \tag #'part \startMeasureCount
    \repeat unfold #n {
      \tag #'part \newRepeatMarker
      $music
    }
  #})


ebass = \relative c, {
  \clef "bass_8"
  d4. d8 r4 d8 r | r8 d r4 d f8 g  | %45-46
  \repeatCountingWithTags 2 { d4. d8 r4 d8 r | r8 d r4 d8 r c4 | }
  %\octaveCheck c,
  d4. d8 r4 d8 r | r8 d r4 d f8 g  | %45-46
  \repeatCounting 2 { d4. d8 r4 d8 r | r8 d r4 d8 r c4 | }
}

ebassUp = \relative c {
  \clef "bass"
  d4. d8 r4 d8 r | r8 d r4 d f8 g  | %45-46
  \repeatCountingWithTags 2 { d4. d8 r4 d8 r | r8 d r4 d8 r c4 | }
  \octaveCheck c
  d4. d8 r4 d8 r | r8 d r4 d f8 g  | %45-46
  \repeatCounting 2 { d4. d8 r4 d8 r | r8 d r4 d8 r c4 | }
  %\repeatCounting 2 { d4. d8 r4 d8 r | r8 d r4 d8 r c4 | }
}

\new StaffGroup <<
  \new Staff \with { instrumentName = "Up" } \keepWithTag #'score \ebass
  \new Staff \with { instrumentName = "Low" } \keepWithTag #'part \ebass
>>


Best,
Jean







reply via email to

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