lilypond-user
[Top][All Lists]
Advanced

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

Re: arbitrary repeat counter


From: Simon Bailey
Subject: Re: arbitrary repeat counter
Date: Sat, 4 Jun 2022 18:37:21 +0100

mind. officially. blown. :D

Thanks, Jean, for the additional input. I learnt some more ;)

Happy weekending,
sb

On Wed, 1 Jun 2022 at 19:21, Jean Abou Samra <jean@abou-samra.fr> wrote:
>
> 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
>
>
>
>


-- 
Do not meddle in the affairs of trombonists, for they are subtle and
quick to anger.



reply via email to

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