Re: arbitrary repeat counter

2022-06-06 Thread Wols Lists

On 06/06/2022 14:10, David Kastrup wrote:

Ah. So now if you do a relative repeat, the contents of the braces are
converted to absolute before the unfold? That's neat.

It never used to be like that, Han Wen wrote that "reset octave"
thingy for me yonks ago (2.4?) because I ran in to that very problem.

Unfolded repeats worked via an iterator (and thus were not having the
\relative problem since the music is not being duplicated) as early as
1.5.66 whereas the first occurence of resetRelativeOctave appears to be
2.9.8.

You probably were thinking about a different problem.


Well, I'm pretty certain the piece of music was Pennsylvania 65-000, and 
I remember Han-Wen writing it specifically for me.


I can't remember the first version of lilypond I used, but the fact it 
first appeared in lilypond proper much later makes sense - I know I 
posted it back to the list on at least one occasion.


Aha - I've found the music, and yes, it's not quite the same problem ... 
also, no surprise, the music has a "version 2.8.2" statement at the top, 
and my function is called "resetOctave". It's a phrase that's repeated 
in voltas, so I need to reset relative pitch when I use the phrase.


So very similar, but not quite the same :-)

Cheers,
Wol



Re: arbitrary repeat counter

2022-06-06 Thread David Kastrup
Wols Lists  writes:

>> What do you mean? Something like
>> \relative {
>>    \repeat unfold 2 { c' g' }
>> }
>> gives the attached output. As you can see, notes are made
>> relative in order without taking the repeat into account,
>> so both repeats play at the same octave. This is not
>> equivalent to
>> \relative {
>>    c' g' c' g'
>> }
>> 
> Ah. So now if you do a relative repeat, the contents of the braces are
> converted to absolute before the unfold? That's neat.
>
> It never used to be like that, Han Wen wrote that "reset octave"
> thingy for me yonks ago (2.4?) because I ran in to that very problem.

Unfolded repeats worked via an iterator (and thus were not having the
\relative problem since the music is not being duplicated) as early as
1.5.66 whereas the first occurence of resetRelativeOctave appears to be
2.9.8.

You probably were thinking about a different problem.

-- 
David Kastrup



Re: arbitrary repeat counter

2022-06-06 Thread Wols Lists

On 06/06/2022 11:46, Jean Abou Samra wrote:

Le 06/06/2022 à 12:17, Wols Lists a écrit :

On 01/06/2022 18:03, Simon Bailey wrote:

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?


No ideas what's causing the difference in behaviour, but if you need 
to fix it, there's the "reset ocatave" command, whatever the exact 
syntax is.




I've already provided a fix for this code. Didn't you receive
that message? It's archived here:

https://lists.gnu.org/archive/html/lilypond-user/2022-06/msg00039.html


Specifically written for relative-mode repeats where the first and 
last notes are a fifth or more apart, and give you that exact effect ...



What do you mean? Something like

\relative {
   \repeat unfold 2 { c' g' }
}

gives the attached output. As you can see, notes are made
relative in order without taking the repeat into account,
so both repeats play at the same octave. This is not
equivalent to

\relative {
   c' g' c' g'
}

Ah. So now if you do a relative repeat, the contents of the braces are 
converted to absolute before the unfold? That's neat.


It never used to be like that, Han Wen wrote that "reset octave" thingy 
for me yonks ago (2.4?) because I ran in to that very problem.


Cheers,
Wol



Re: arbitrary repeat counter

2022-06-06 Thread Jean Abou Samra

Le 06/06/2022 à 12:17, Wols Lists a écrit :

On 01/06/2022 18:03, Simon Bailey wrote:

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?


No ideas what's causing the difference in behaviour, but if you need 
to fix it, there's the "reset ocatave" command, whatever the exact 
syntax is.




I've already provided a fix for this code. Didn't you receive
that message? It's archived here:

https://lists.gnu.org/archive/html/lilypond-user/2022-06/msg00039.html


Specifically written for relative-mode repeats where the first and 
last notes are a fifth or more apart, and give you that exact effect ...



What do you mean? Something like

\relative {
  \repeat unfold 2 { c' g' }
}

gives the attached output. As you can see, notes are made
relative in order without taking the repeat into account,
so both repeats play at the same octave. This is not
equivalent to

\relative {
  c' g' c' g'
}

Best,
Jean


Re: arbitrary repeat counter

2022-06-06 Thread Wols Lists

On 01/06/2022 18:03, Simon Bailey wrote:

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?


No ideas what's causing the difference in behaviour, but if you need to 
fix it, there's the "reset ocatave" command, whatever the exact syntax 
is. Specifically written for relative-mode repeats where the first and 
last notes are a fifth or more apart, and give you that exact effect ...


Cheers,
Wol



Re: arbitrary repeat counter

2022-06-04 Thread Simon Bailey
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  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
>

Re: arbitrary repeat counter

2022-06-01 Thread Jean Abou Samra

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







Re: arbitrary repeat counter

2022-06-01 Thread Jean Abou Samra

Le 01/06/2022 à 18:19, Simon Bailey a écrit :

Hi,

On Wed, 1 Jun 2022 at 17:09, Jean Abou Samra - jean at abou-samra.fr
 wrote:

What did not work? This is perfectly valid Scheme:

(set! count (1+ count))

(set! counter (+ counter 1))

was giving an error message. Probably had some misaligned parentheses
or other weirdness. I didn't know about (1+ var) ;)


You're welcome. To be honest, and simplifying a bit, I had a
year of unsuccessful attempts to grasp Scheme before Urs'
Scheme tutorial made me learn as much of Scheme in 4 hours
as I had learnt in a year, then another year without that kind
of help to learn LilyPond internals, so if I've managed to write
something that is similarly turning a year into 4 hours for
you, I'm quite happy.

Your readthedocs thing really helped; I still need to have a look at
Urs' tutorial. I did some functional programming sometime at the
beginning of the millenium, but 20yrs of OOP is a hard habit to break
;-)



For what it's worth, while LilyPond's seldom uses it, Guile actually
has an object-oriented layer.

https://www.gnu.org/software/guile/manual/html_node/GOOPS.html

You may find yourself liking that. This shows that OOP is or
can be largely orthogonal to functional vs. imperative.




A further definition:

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

ebass = \relative c {
   \clef bass
   \time 7/4
   \repeatCountingWithTags 4 { c4. 8 r4 8 r c2. | d4. 4. 4 e2. | 1 r2 r4 | }
}

\new StaffGroup <<
   \new Staff \with { instrumentName = "Score" } \keepWithTag #'score \ebass
   \new Staff \with { instrumentName = "Part" } \keepWithTag #'part \ebass
and I get the attached output, which is exactly what I want. And it
makes my input files so much easier to read and manage.

Thanks ever so much for your help!




Again, you're welcome.

Best,
Jean




Re: arbitrary repeat counter

2022-06-01 Thread Simon Bailey
Hi,

On Wed, 1 Jun 2022 at 17:09, Jean Abou Samra - jean at abou-samra.fr
 wrote:
> What did not work? This is perfectly valid Scheme:
>
> (set! count (1+ count))

(set! counter (+ counter 1))

was giving an error message. Probably had some misaligned parentheses
or other weirdness. I didn't know about (1+ var) ;)

> You're welcome. To be honest, and simplifying a bit, I had a
> year of unsuccessful attempts to grasp Scheme before Urs'
> Scheme tutorial made me learn as much of Scheme in 4 hours
> as I had learnt in a year, then another year without that kind
> of help to learn LilyPond internals, so if I've managed to write
> something that is similarly turning a year into 4 hours for
> you, I'm quite happy.

Your readthedocs thing really helped; I still need to have a look at
Urs' tutorial. I did some functional programming sometime at the
beginning of the millenium, but 20yrs of OOP is a hard habit to break
;-)

A further definition:

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

ebass = \relative c {
  \clef bass
  \time 7/4
  \repeatCountingWithTags 4 { c4. 8 r4 8 r c2. | d4. 4. 4 e2. | 1 r2 r4 | }
}

\new StaffGroup <<
  \new Staff \with { instrumentName = "Score" } \keepWithTag #'score \ebass
  \new Staff \with { instrumentName = "Part" } \keepWithTag #'part \ebass
>>
and I get the attached output, which is exactly what I want. And it
makes my input files so much easier to read and manage.

Thanks ever so much for your help!

Kind regards,
sb

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


Re: arbitrary repeat counter

2022-06-01 Thread Jean Abou Samra




Le 01/06/2022 à 18:04, Simon Bailey a écrit :

On Wed, 1 Jun 2022 at 16:14, Jean Abou Samra  wrote:

1. What is the duration of a measure dependent on the current time signature?

In an engraver :-)

(ly:context-property context 'measureLength)

You can't get it in the music function, since timing is not
established at that point (just think that the time signature
could come from another element of a << >> construct, for
example).

Remember, though, that the time signature might change
in the middle of the repeat. Thus it will be a bit
more reliable to actually acknowledge the PercentRepeatCount
grobs and increment a counter whenever you see one.

I actually tried that and ran into scheme problems (incrementing a
counter didn't seem to work).



What did not work? This is perfectly valid Scheme:

(set! count (1+ count))

In fact, it's in the code of my engraver.



2. How long is a given musical expression (in measures or beats)?

(ly:music-length your-music)


I think I might use your engraver ;)  But I've definitely learnt more
today. Thanks!



You're welcome. To be honest, and simplifying a bit, I had a
year of unsuccessful attempts to grasp Scheme before Urs'
Scheme tutorial made me learn as much of Scheme in 4 hours
as I had learnt in a year, then another year without that kind
of help to learn LilyPond internals, so if I've managed to write
something that is similarly turning a year into 4 hours for
you, I'm quite happy.

Best,
Jean




Re: arbitrary repeat counter

2022-06-01 Thread Simon Bailey
On Wed, 1 Jun 2022 at 16:14, Jean Abou Samra  wrote:
> > 1. What is the duration of a measure dependent on the current time 
> > signature?
>
> In an engraver :-)
>
> (ly:context-property context 'measureLength)
>
> You can't get it in the music function, since timing is not
> established at that point (just think that the time signature
> could come from another element of a << >> construct, for
> example).
>
> Remember, though, that the time signature might change
> in the middle of the repeat. Thus it will be a bit
> more reliable to actually acknowledge the PercentRepeatCount
> grobs and increment a counter whenever you see one.

I actually tried that and ran into scheme problems (incrementing a
counter didn't seem to work).

> > 2. How long is a given musical expression (in measures or beats)?
>
> (ly:music-length your-music)
>

I think I might use your engraver ;)  But I've definitely learnt more
today. Thanks!

I did make one small change to your engraver:

(if (> count 1)
   (ly:grob-set-property! spanner 'text (number->string count))) ;;;
<== here

So that it only prints the numbers for repeated phrases.

Kind regards,
sb

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



Re: arbitrary repeat counter

2022-06-01 Thread Jean Abou Samra

Le 01/06/2022 à 17:04, Simon Bailey a écrit :

A bit more work and I now have the following:

\version "2.23.9"
#(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

\defineBarLine "!|" #'("!|" "" "!|")
repeatCounting =
#(define-music-function (n bar-length phrase-length music) (index?
ly:music? integer? ly:music?)
#{
  <<
\repeat unfold #n { #music \bar "!|" }
{
  \set countPercentRepeats = ##t
  \hide PercentRepeat
  \override PercentRepeatCounter.phrase-length = #phrase-length
  \override PercentRepeatCounter.stencil = #counter-stencil
  \repeat percent #(* phrase-length n) { #bar-length }
}
  >>
#})

\new Staff \relative c' {
   \repeatCounting 4 s1 2 {c4 d e f | g f e d }
   \break c1
   \time 7/4
   \repeatCounting 4 s4*7 3 {c4 d e f r r r | g f e d r r r| c1 r2 r4 }
}

How can I find out the following two bits of information?

1. What is the duration of a measure dependent on the current time signature?




In an engraver :-)

(ly:context-property context 'measureLength)

You can't get it in the music function, since timing is not
established at that point (just think that the time signature
could come from another element of a << >> construct, for
example).

Remember, though, that the time signature might change
in the middle of the repeat. Thus it will be a bit
more reliable to actually acknowledge the PercentRepeatCount
grobs and increment a counter whenever you see one.




2. How long is a given musical expression (in measures or beats)?



(ly:music-length your-music)


Best,
Jean




Re: arbitrary repeat counter

2022-06-01 Thread Simon Bailey
On Wed, 1 Jun 2022 at 15:50, Jean Abou Samra  wrote:
> 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:
>


I'll test that in a moment.

> > 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 :-)

A bit more work and I now have the following:

\version "2.23.9"
#(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

\defineBarLine "!|" #'("!|" "" "!|")
repeatCounting =
#(define-music-function (n bar-length phrase-length music) (index?
ly:music? integer? ly:music?)
   #{
 <<
   \repeat unfold #n { #music \bar "!|" }
   {
 \set countPercentRepeats = ##t
 \hide PercentRepeat
 \override PercentRepeatCounter.phrase-length = #phrase-length
 \override PercentRepeatCounter.stencil = #counter-stencil
 \repeat percent #(* phrase-length n) { #bar-length }
   }
 >>
   #})

\new Staff \relative c' {
  \repeatCounting 4 s1 2 {c4 d e f | g f e d }
  \break c1
  \time 7/4
  \repeatCounting 4 s4*7 3 {c4 d e f r r r | g f e d r r r| c1 r2 r4 }
}

How can I find out the following two bits of information?

1. What is the duration of a measure dependent on the current time signature?
2. How long is a given musical expression (in measures or beats)?

If I can work out those two problems, then I could get rid of the two
extra parameters bar-length and phrase-length…

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



Re: arbitrary repeat counter

2022-06-01 Thread Jean Abou Samra

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




Re: arbitrary repeat counter

2022-06-01 Thread Simon Bailey
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'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.

Thanks, kind regards,
sb

On Wed, 1 Jun 2022 at 13:51, Jean Abou Samra  wrote:
>
> Le 01/06/2022 à 12:25, Simon Bailey a écrit :
> > Hi,
> >
> > with a little bit of digging through your manual, i have solved some
> > of my questions:
> >
> > #(define (counter-stencil grob)
> > (let* ((counter (ly:grob-property grob 'text)))  ; get the value of
> > the counter
> >   (ly:stencil-aligned-to
> > (grob-interpret-markup grob
> >   (markup counter "!")) ; print the counter back with !
> > Y
> > CENTER)))
> >
> > This basically replicates the behaviour of the regular percent counter
> > and adds an exclamation mark. so now i can just add some if/mod/div
> > magic and it should do what I want. Getting there… ;)
>
>
>
> Well, you have two possible approaches. The one you sketch above is
> the backend approach: override the measure counter's alignment so
> it aligns within the first measure rather than the whole span.
> The other is the translation approach: arrange to create the
> counter so that it has the right bound you want from the start.
> I think that is simpler in this case, so I'd do something like
>
> \version "2.22.2"
>
> 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 'count-from count)
>   (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 }
> }
>
>
> Best,
> Jean
>


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



Re: arbitrary repeat counter

2022-06-01 Thread Jean Abou Samra

Le 01/06/2022 à 12:25, Simon Bailey a écrit :

Hi,

with a little bit of digging through your manual, i have solved some
of my questions:

#(define (counter-stencil grob)
(let* ((counter (ly:grob-property grob 'text)))  ; get the value of
the counter
  (ly:stencil-aligned-to
(grob-interpret-markup grob
  (markup counter "!")) ; print the counter back with !
Y
CENTER)))

This basically replicates the behaviour of the regular percent counter
and adds an exclamation mark. so now i can just add some if/mod/div
magic and it should do what I want. Getting there… ;)




Well, you have two possible approaches. The one you sketch above is
the backend approach: override the measure counter's alignment so
it aligns within the first measure rather than the whole span.
The other is the translation approach: arrange to create the
counter so that it has the right bound you want from the start.
I think that is simpler in this case, so I'd do something like

\version "2.22.2"

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 'count-from count)
 (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 }
}


Best,
Jean




Re: arbitrary repeat counter

2022-06-01 Thread Simon Bailey
Hi,

with a little bit of digging through your manual, i have solved some
of my questions:

#(define (counter-stencil grob)
   (let* ((counter (ly:grob-property grob 'text)))  ; get the value of
the counter
 (ly:stencil-aligned-to
   (grob-interpret-markup grob
 (markup counter "!")) ; print the counter back with !
   Y
   CENTER)))

This basically replicates the behaviour of the regular percent counter
and adds an exclamation mark. so now i can just add some if/mod/div
magic and it should do what I want. Getting there… ;)

Kind regards,
sb



Re: arbitrary repeat counter

2022-06-01 Thread Simon Bailey
Hi Jean,

On Wed, 1 Jun 2022 at 10:04, Jean Abou Samra  wrote:
> How about doing it like this?
> < SNIP SNIP SNIP>
> <<
>\new Staff \unfoldRepeats \part
>\new Staff \otherPart
> >>

Yeah, I know about unfoldRepeats. But using voltas in a part where
they're not in a score is a big no-no. I realise it was given practice
in some editions, but it just leads to confusion and panic in
rehearsals. Also, simply unfolding the repeats does not solve the
numbering issue ;) (indeed, \repeat volta 8 doesn't indicate that it
gets repeated 8 times without adding some markup somewhere).

Gould says on repeated sections:
<<
Repeated section[s] in instrumental parts must correspond exactly with
the layout of a score. Parts must have the same number of notated bars
as a score and repeats must occur in identical places in all material,
[…]
>>

> Sadly, the extending manual isn't overly helpful. That's
> the reason why I wrote
>
> https://extending-lilypond.readthedocs.io
>
> You may find it more useful. At any rate, it is definitely
> more thorough.

I'll bookmark that one right away. Thanks!

Kind regards,
sb

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



Re: arbitrary repeat counter

2022-06-01 Thread Jean Abou Samra

Le 01/06/2022 à 10:53, Simon Bailey a écrit :

Hi,

There's a handy snippet for counting repeated bars in the manual. But
I'm running into limitations when for instance I'd like to have 2- or
4-bar sections that I'd like to count. Usage example: a bass guitar
has a 4-bar riff that's repeated 8 times, but I can't use a volta
repeat in the part because the rest of the ensemble doesn't have
repeatable music;




How about doing it like this?

\version "2.22.2"

part = {
  \repeat volta 8 { c'1 1 1 1 }
}

{ \part }

otherPart = {
  c'1 1 1 1
  d'1 1 1 1
  e'1 1 1 1
  f'1 1 1 1
  g'1 1 1 1
  a'1 1 1 1
  b'1 1 1 1
  c'1 1 1 1
}

<<
  \new Staff \unfoldRepeats \part
  \new Staff \otherPart







I'd like to print a counting number over the centre
of the first bar of each phrase.

For 2-bar phrases, using the example from the manual, I get the
following, but the Counter is centred over the middle bar-line. Does
anyone have a suggestion for some scheme magic I can investigate to
calculate the X-offset to the centre of the first bar?

\new Staff \relative c' {
   <<
 {
   \set countPercentRepeats = ##t
   \hide DoublePercentRepeat
   \repeat percent 4 { s1*2}
 }
 \repeat unfold 4 { c4. 8 r4 8 r | d4. 4. 4 }
   >>
}

For 4-bar phrases, the best thing I've managed to come up with is this:

\new Staff \relative c {
   \clef bass
   <<
 \context Voice = "foo" {
   \repeat unfold 4 { r4 d8 r r f r4 | a8 r r g r a f r8 | r4 d'8 r
r f, r4 | a8 r r g8 ~ g4 r | }
 }
 \context Voice = "foo" {
   \hide MultiMeasureRest
   \override Voice.MultiMeasureRestText.font-encoding = #'fetaText
   \override Voice.MultiMeasureRestText.font-size = #-2
   s1*4 | R1^"(2)" s1*3  | R1^"(3)" s1*3  | R1-"(4)" s1*3  |
 }
   >>
}

but that's all a bit "manual" ;)

I was thinking it may be possible to override the stencil for the
PercentRepeatCounter and do some math on the current percent repeat
count, but I have no idea how to:

a) get the current repeat number
b) replace a text-interface::print stencil

I've just spent 2 hours digging through LSR and the exending lilypond
manual, but that was a bit fruitless.



Sadly, the extending manual isn't overly helpful. That's
the reason why I wrote

https://extending-lilypond.readthedocs.io

You may find it more useful. At any rate, it is definitely
more thorough.

That said, if you use the suggestion above, the problem
is solved without needing it at all ;-)




I'm also wondering if there's any form of convention to show these
repeated phrases – as a player, if I was given a part with these
repeated phrases and no counting, I'd add the numbers in pencil and
probably a flare to the final barline of each phrase. I'm open to
suggestions ;)



I don't know whether there is an established convention, but
I would say it is definitely easier to follow the score if
the repeat is condensed, especially for something repeated 8
times. On the other hand, it might be trickier to make it
easy to jump to a specific bar number.


Regards,
Jean




arbitrary repeat counter

2022-06-01 Thread Simon Bailey
Hi,

There's a handy snippet for counting repeated bars in the manual. But
I'm running into limitations when for instance I'd like to have 2- or
4-bar sections that I'd like to count. Usage example: a bass guitar
has a 4-bar riff that's repeated 8 times, but I can't use a volta
repeat in the part because the rest of the ensemble doesn't have
repeatable music; I'd like to print a counting number over the centre
of the first bar of each phrase.

For 2-bar phrases, using the example from the manual, I get the
following, but the Counter is centred over the middle bar-line. Does
anyone have a suggestion for some scheme magic I can investigate to
calculate the X-offset to the centre of the first bar?

\new Staff \relative c' {
  <<
{
  \set countPercentRepeats = ##t
  \hide DoublePercentRepeat
  \repeat percent 4 { s1*2}
}
\repeat unfold 4 { c4. 8 r4 8 r | d4. 4. 4 }
  >>
}

For 4-bar phrases, the best thing I've managed to come up with is this:

\new Staff \relative c {
  \clef bass
  <<
\context Voice = "foo" {
  \repeat unfold 4 { r4 d8 r r f r4 | a8 r r g r a f r8 | r4 d'8 r
r f, r4 | a8 r r g8 ~ g4 r | }
}
\context Voice = "foo" {
  \hide MultiMeasureRest
  \override Voice.MultiMeasureRestText.font-encoding = #'fetaText
  \override Voice.MultiMeasureRestText.font-size = #-2
  s1*4 | R1^"(2)" s1*3  | R1^"(3)" s1*3  | R1-"(4)" s1*3  |
}
  >>
}

but that's all a bit "manual" ;)

I was thinking it may be possible to override the stencil for the
PercentRepeatCounter and do some math on the current percent repeat
count, but I have no idea how to:

a) get the current repeat number
b) replace a text-interface::print stencil

I've just spent 2 hours digging through LSR and the exending lilypond
manual, but that was a bit fruitless.

I'm also wondering if there's any form of convention to show these
repeated phrases – as a player, if I was given a part with these
repeated phrases and no counting, I'd add the numbers in pencil and
probably a flare to the final barline of each phrase. I'm open to
suggestions ;)

Thanks, kind regards,
sb

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