Current octave in relative mode

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Current octave in relative mode

Klaus Blum
Hi,

I have a function that uses a music expression twice.
My problem is:
In relative mode, this expression can lead into a different octave. Then
the second application of the music expression starts from that new octave.
(See the last two invocations of "\highlight" in the example below)

Is there something I can do INSIDE my function to prevent this? E.g.
storing and re-applying the current octave? Thanks for any hint.  :)


% ----------------------------------------
highlight =
#(define-music-function (mus)
    (ly:music?)
    #{
      <<
        $mus
        \makeClusters $mus
      >>
    #})

\new Staff {
   \highlight { c'8 d' e' f' g' a' b' c'' }
   \relative c' {
     c1  \highlight { c8 d e f g f e d }
     c1  \highlight { c8 d e f g a b c }
     c1  \highlight { f,4 e d c }
     c1
   }
}
% ----------------------------------------

Cheers,
Klaus

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

David Kastrup
Klaus Blum <[hidden email]> writes:

> Hi,
>
> I have a function that uses a music expression twice.
> My problem is:
> In relative mode, this expression can lead into a different octave. Then
> the second application of the music expression starts from that new octave.
> (See the last two invocations of "\highlight" in the example below)
>
> Is there something I can do INSIDE my function to prevent this? E.g.
> storing and re-applying the current octave? Thanks for any hint.  :)
>
>
> % ----------------------------------------
> highlight =
> #(define-music-function (mus)
>    (ly:music?)
>    #{
>      <<
>        $mus
>        \makeClusters $mus
>      >>
>    #})
>
> \new Staff {
>   \highlight { c'8 d' e' f' g' a' b' c'' }
>   \relative c' {
>     c1  \highlight { c8 d e f g f e d }
>     c1  \highlight { c8 d e f g a b c }
>     c1  \highlight { f,4 e d c }
>     c1
>   }
> }
> % ----------------------------------------
If your mail client cannot be kept from mangling spaces into unbreakable
spaces, you might want to think about attaching program files.

Try this.


% ----------------------------------------
highlight =
#(define-music-function (mus)
  (ly:music?)
  (make-relative (mus) mus
   #{
     <<
       $mus
       \makeClusters $mus
     >>
   #}))

\new Staff {
  \highlight { c'8 d' e' f' g' a' b' c'' }
  \relative c' {
    c1  \highlight { c8 d e f g f e d }
    c1  \highlight { c8 d e f g a b c }
    c1  \highlight { f,4 e d c }
    c1
  }
}
% ----------------------------------------



--
David Kastrup
Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

antlists
In reply to this post by Klaus Blum
There's a function Han Wen wrote for me years ago, that's made its way
in to standard lilypond. It's probably mentioned in the docu about
relative mode. Something along the lines of

       c1  \highlight { c8 d e f g f e d }
       \setAbsoluteOctave ...
       c1  \highlight { c8 d e f g a b c }

Don't quote me on the function name though ... (I needed it for
Pennsylvania 6-5-0-0-0

Cheers,
Wol

On 15/05/2020 11:01, Klaus Blum wrote:

> Hi,
>
> I have a function that uses a music expression twice.
> My problem is:
> In relative mode, this expression can lead into a different octave. Then
> the second application of the music expression starts from that new octave.
> (See the last two invocations of "\highlight" in the example below)
>
> Is there something I can do INSIDE my function to prevent this? E.g.
> storing and re-applying the current octave? Thanks for any hint.  :)
>
>
> % ----------------------------------------
> highlight =
> #(define-music-function (mus)
>     (ly:music?)
>     #{
>       <<
>         $mus
>         \makeClusters $mus
>       >>
>     #})
>
> \new Staff {
>    \highlight { c'8 d' e' f' g' a' b' c'' }
>    \relative c' {
>      c1  \highlight { c8 d e f g f e d }
>      c1  \highlight { c8 d e f g a b c }
>      c1  \highlight { f,4 e d c }
>      c1
>    }
> }
> % ----------------------------------------
>
> Cheers,
> Klaus
>

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

Klaus Blum
In reply to this post by David Kastrup
Hi David,

That's perfect, thanks a lot!
Cool to know that this doesn't require complicated tweaks and hacks...

Cheers,
Klaus

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

David Kastrup
Klaus Blum <[hidden email]> writes:

> Hi David,
>
> That's perfect, thanks a lot!
> Cool to know that this doesn't require complicated tweaks and hacks...

If you think this isn't a complicated hack, you haven't looked at the
source code of make-relative...

Its three arguments, by the way, are a list of variables, an expression
containing the variables that is passed through \relative and modifies
the variables according to their occurence in the expression, and
finally the expression you _actually_ want calculated.

So if you have three arguments of music expression that should be
relativised after another, you can say

(define-music-function (a b c) (ly:music? ly:music? ly:music?)
  (a b c) #{ #a #b #c #}
  #{ ....... #})

And regardless of how often and in which order you use which argument
inside of your actual music function body, the effect of \relative on
them will be instead as if they had appeared only in #{ #a #b #c #} .

--
David Kastrup

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

Flaming Hakama by Elaine
In reply to this post by Klaus Blum


---------- Forwarded message ----------
From: Klaus Blum <[hidden email]>
To: "[hidden email]" <[hidden email]>
Cc: 
Bcc: 
Date: Fri, 15 May 2020 12:01:06 +0200
Subject: Current octave in relative mode
Hi,

I have a function that uses a music expression twice.
My problem is:
In relative mode, this expression can lead into a different octave. Then
the second application of the music expression starts from that new octave.
(See the last two invocations of "\highlight" in the example below)

Is there something I can do INSIDE my function to prevent this? E.g.
storing and re-applying the current octave? Thanks for any hint.  :)


% ----------------------------------------
highlight =
#(define-music-function (mus)
    (ly:music?)
    #{
      <<
        $mus
        \makeClusters $mus
      >>
    #})

\new Staff {
   \highlight { c'8 d' e' f' g' a' b' c'' }
   \relative c' {
     c1  \highlight { c8 d e f g f e d }
     c1  \highlight { c8 d e f g a b c }
     c1  \highlight { f,4 e d c }
     c1
   }
}
% ----------------------------------------

Cheers,
Klaus

I'm not quite sure what you are after here, except that some things are not in the octave you want, but I'm not sure which.

In any case, the solution to runaway relatives is actually to use more of them.  

You see, each music expression with curly braces { } may or may not be  distinct.  If you do not say \relative or \fixed, then that music expression { } does take it's octave from whatever the current octave is, and whatever follows it starts off from the octave that the music expression { } ends with.

However, if you use \relative on every one, then:
 
1) The octave of the notes inside the \relative c' {} you pass to your function is defined and it does not matter what the current octave is of the enclosing expression.

But more importantly
2) The entirety of the music expression inside the \relative c' {} you pass to your function is omitted from the calculation of the octave of what follows.

So, in your example, if all the c1's are supposed to be the same octave
this is accomplished by just specifying each of the ones you pass to your function. 
 

\version "2.19.81"
% ----------------------------------------
highlight =
#(define-music-function (mus)
  (ly:music?)
  (make-relative (mus) mus
   #{
     <<
       $mus
       \makeClusters $mus
     >>
   #}))

% Unsafe
\new Staff {
  \highlight { c'8 d' e' f' g' a' b' c'' }
  \relative c' {
    c1  \highlight { c8 d e f g f e d }
    c1  \highlight { c8 d e f g a b c }
    c1  \highlight { f,4 e d c }
    c1
  }
}

% Safe
\new Staff {
  \highlight { c'8 d' e' f' g' a' b' c'' }
  \relative c' {
    c1  \highlight \relative c' { c8 d e f g f e d }
    c1  \highlight \relative c' { c8 d e f g a b c }
    c1  \highlight \relative c' { f,4 e d c }
    c1
  }
}
% ----------------------------------------


HTH,

Elaine Alt
415 . 341 .4954                                           "Confusion is highly underrated"
[hidden email]
Producer ~ Composer ~ Instrumentalist ~ Educator
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

David Kastrup
Flaming Hakama by Elaine <[hidden email]> writes:

>> From: Klaus Blum <[hidden email]>
>> To: "[hidden email]" <[hidden email]>
>> Cc:
>> Bcc:
>> Date: Fri, 15 May 2020 12:01:06 +0200
>> Subject: Current octave in relative mode
>> Hi,
>>
>> I have a function that uses a music expression twice.
>> My problem is:
>> In relative mode, this expression can lead into a different octave. Then
>> the second application of the music expression starts from that new octave.
>> (See the last two invocations of "\highlight" in the example below)
>>
>>
>> % ----------------------------------------
>> highlight =
>> #(define-music-function (mus)
>>     (ly:music?)
>>     #{
>>       <<
>>         $mus
>>         \makeClusters $mus
>>       >>
>>     #})
>>
>> \new Staff {
>>    \highlight { c'8 d' e' f' g' a' b' c'' }
>>    \relative c' {
>>      c1  \highlight { c8 d e f g f e d }
>>      c1  \highlight { c8 d e f g a b c }
>>      c1  \highlight { f,4 e d c }
>>      c1
>>    }
>> }
>> % ----------------------------------------

> I'm not quite sure what you are after here, except that some things are not
> in the octave you want, but I'm not sure which.
>

[...]

> So, in your example, if all the c1's are supposed to be the same octave
> this is accomplished by just specifying each of the ones you pass to your
> function.
>
>
> \version "2.19.81"
> % ----------------------------------------
> highlight =
> #(define-music-function (mus)
>   (ly:music?)
>   (make-relative (mus) mus
>    #{
>      <<
>        $mus
>        \makeClusters $mus
>      >>
>    #}))

You are aware that make-relative here fixes the problem?  Did you just
copy the fixed version by accident from my reply?

--
David Kastrup

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

Flaming Hakama by Elaine
Sorry, yes I did copy yours because the original one had some kind of formatting problem and I thought that yours was just a reformatting of the original.


Thanks,

On Sat, May 16, 2020, 3:30 AM David Kastrup <[hidden email]> wrote:
Flaming Hakama by Elaine <[hidden email]> writes:

>> From: Klaus Blum <[hidden email]>
>> To: "[hidden email]" <[hidden email]>
>> Cc:
>> Bcc:
>> Date: Fri, 15 May 2020 12:01:06 +0200
>> Subject: Current octave in relative mode
>> Hi,
>>
>> I have a function that uses a music expression twice.
>> My problem is:
>> In relative mode, this expression can lead into a different octave. Then
>> the second application of the music expression starts from that new octave.
>> (See the last two invocations of "\highlight" in the example below)
>>
>>
>> % ----------------------------------------
>> highlight =
>> #(define-music-function (mus)
>>     (ly:music?)
>>     #{
>>       <<
>>         $mus
>>         \makeClusters $mus
>>       >>
>>     #})
>>
>> \new Staff {
>>    \highlight { c'8 d' e' f' g' a' b' c'' }
>>    \relative c' {
>>      c1  \highlight { c8 d e f g f e d }
>>      c1  \highlight { c8 d e f g a b c }
>>      c1  \highlight { f,4 e d c }
>>      c1
>>    }
>> }
>> % ----------------------------------------

> I'm not quite sure what you are after here, except that some things are not
> in the octave you want, but I'm not sure which.
>

[...]

> So, in your example, if all the c1's are supposed to be the same octave
> this is accomplished by just specifying each of the ones you pass to your
> function.
>
>
> \version "2.19.81"
> % ----------------------------------------
> highlight =
> #(define-music-function (mus)
>   (ly:music?)
>   (make-relative (mus) mus
>    #{
>      <<
>        $mus
>        \makeClusters $mus
>      >>
>    #}))

You are aware that make-relative here fixes the problem?  Did you just
copy the fixed version by accident from my reply?

--
David Kastrup
Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

antlists
In reply to this post by antlists
On 15/05/2020 12:28, antlists wrote:

> There's a function Han Wen wrote for me years ago, that's made its way
> in to standard lilypond. It's probably mentioned in the docu about
> relative mode. Something along the lines of
>
>        c1  \highlight { c8 d e f g f e d }
>        \setAbsoluteOctave ...
>        c1  \highlight { c8 d e f g a b c }
>
> Don't quote me on the function name though ... (I needed it for
> Pennsylvania 6-5-0-0-0

Found it ...

\version "2.8.2"

resetOctave  =
#(define-music-function
     (parser location reference-note)
     (ly:music?)

    (let*
     ((notes (ly:music-property reference-note 'elements))
      (pitch (ly:music-property (car notes) 'pitch))

    )

     (set! (ly:music-property reference-note 'elements) '())
     (set! (ly:music-property reference-note
        'to-relative-callback)
        (lambda (music last-pitch)
         pitch))

     reference-note
     ))

pennsylvania = \context Voice = pennsylvania {
     \override NoteHead #'style = #'cross
     r2_\markup{ shout } f8. f16 f8. f16 f4 f f8. f16 r4
}

pennsylvaniaLyrics = \lyricmode { \small { Penn syl van ia six five thou
sand } }

voiceTromboneI = \relative c' {

        r2  ef4.-- ef8-> ~ ef1 r2 r4 bf8.->( ef16-.) r2 r4 ef,8. af,16-> ~ |
        af2 c-- df-- d-- ef-- df-- c-- bf-- |
        \repeat "volta" 2 { R1*6 } \alternative { { \resetOctave f
\pennsylvania } { \pennsylvania } }
        bf8-. cf4-> bf8-> ~ bf4 bf8.-- af16-. r8 af4.---. r2 bf8-. cf4-- bf8->
~ bf4 bf8.-- af16-> ~ |

>
> Cheers,
> Wol
>
Okay, this is just the start of the file so it won't compile as is :-)
but you can see it defines the function resetOctave. I don't
particularly remember how it works, but you also see how it's used
further down. iirc it eats the first note after it - the f - and treats
it as an absolute pitch of zero length so the subsequent phrase is at
the right pitch regardless of what went in front of it.

As I say, I think this function or something similar has made its way
into lilypond proper.

Cheers,
Wol

> On 15/05/2020 11:01, Klaus Blum wrote:
>> Hi,
>>
>> I have a function that uses a music expression twice.
>> My problem is:
>> In relative mode, this expression can lead into a different octave. Then
>> the second application of the music expression starts from that new
>> octave.
>> (See the last two invocations of "\highlight" in the example below)
>>
>> Is there something I can do INSIDE my function to prevent this? E.g.
>> storing and re-applying the current octave? Thanks for any hint.  :)
>>
I think you can use this inside your function. I explicitly didn't want
to because this phrase appears in at least two different octaves so I
wanted to apply the pitch outside it instead.

Cheers,
Wol

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

David Kastrup
antlists <[hidden email]> writes:

> On 15/05/2020 12:28, antlists wrote:
>> There's a function Han Wen wrote for me years ago, that's made its
>> way in to standard lilypond. It's probably mentioned in the docu
>> about relative mode. Something along the lines of
>>        c1  \highlight { c8 d e f g f e d }
>>        \setAbsoluteOctave ...
>>        c1  \highlight { c8 d e f g a b c }
>> Don't quote me on the function name though ... (I needed it for
>> Pennsylvania 6-5-0-0-0
>
> Found it ...
>
> \version "2.8.2"
>
> resetOctave  =
> #(define-music-function
>     (parser location reference-note)
>     (ly:music?)
>
>    (let*
>     ((notes (ly:music-property reference-note 'elements))
>      (pitch (ly:music-property (car notes) 'pitch))
>
>    )
>
>     (set! (ly:music-property reference-note 'elements) '())
>     (set! (ly:music-property reference-note
>        'to-relative-callback)
>        (lambda (music last-pitch)
>         pitch))
>
>     reference-note
>     ))
>
> pennsylvania = \context Voice = pennsylvania {
>     \override NoteHead #'style = #'cross
>     r2_\markup{ shout } f8. f16 f8. f16 f4 f f8. f16 r4
> }
>
> pennsylvaniaLyrics = \lyricmode { \small { Penn syl van ia six five
> thou sand } }
>
> voiceTromboneI = \relative c' {
>
> r2  ef4.-- ef8-> ~ ef1 r2 r4 bf8.->( ef16-.) r2 r4 ef,8. af,16-> ~ |
> af2 c-- df-- d-- ef-- df-- c-- bf-- |
> \repeat "volta" 2 { R1*6 } \alternative { { \resetOctave f
> \pennsylvania } { \pennsylvania } }
> bf8-. cf4-> bf8-> ~ bf4 bf8.-- af16-. r8 af4.---. r2
> bf8-. cf4-- bf8-> ~ bf4 bf8.-- af16-> ~ |
>
>> Cheers,
>> Wol
>>
> Okay, this is just the start of the file so it won't compile as is :-)
> but you can see it defines the function resetOctave. I don't
> particularly remember how it works, but you also see how it's used
> further down. iirc it eats the first note after it - the f - and
> treats it as an absolute pitch of zero length so the subsequent phrase
> is at the right pitch regardless of what went in front of it.
>
> As I say, I think this function or something similar has made its way
> into lilypond proper.

What advantage over the solution using make-relative that I posted do
you see here?

--
David Kastrup

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

antlists
On 16/05/2020 23:19, David Kastrup wrote:
>> As I say, I think this function or something similar has made its way
>> into lilypond proper.

> What advantage over the solution using make-relative that I posted do
> you see here?

Because if I understand the OP correctly, what he wants is
\resetRelativeOctave, which is already a standard part of lilypond?

I'm guessing Han Wen's resetOctave is its predecessor.

So I guess - at the third attempt - my solution is the best because it
doesn't need a custom function at all :-)

Cheers,
Wol

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

David Kastrup
antlists <[hidden email]> writes:

> On 16/05/2020 23:19, David Kastrup wrote:
>>> As I say, I think this function or something similar has made its way
>>> into lilypond proper.
>
>> What advantage over the solution using make-relative that I posted do
>> you see here?
>
> Because if I understand the OP correctly, what he wants is
> \resetRelativeOctave, which is already a standard part of lilypond?

What he wants is music used twice within a function not to end up in
different octaves.

> I'm guessing Han Wen's resetOctave is its predecessor.
>
> So I guess - at the third attempt - my solution is the best because it
> doesn't need a custom function at all :-)

make-relative has been part of LilyPond in its current form since
2.18.0.  I am not sure what you call "custom function" in this context.
Particularly since your proposal contained a large amount of code.

--
David Kastrup

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

antlists
On 17/05/2020 00:04, David Kastrup wrote:

> antlists <[hidden email]> writes:
>
>> On 16/05/2020 23:19, David Kastrup wrote:
>>>> As I say, I think this function or something similar has made its way
>>>> into lilypond proper.
>>
>>> What advantage over the solution using make-relative that I posted do
>>> you see here?
>>
>> Because if I understand the OP correctly, what he wants is
>> \resetRelativeOctave, which is already a standard part of lilypond?
>
> What he wants is music used twice within a function not to end up in
> different octaves.

Isn't that what \resetRelativeOctave does? His description seems exactly
to match my problem with Pennsylvania 6-5-0-0-0

>
>> I'm guessing Han Wen's resetOctave is its predecessor.
>>
>> So I guess - at the third attempt - my solution is the best because it
>> doesn't need a custom function at all :-)
>
> make-relative has been part of LilyPond in its current form since
> 2.18.0.  I am not sure what you call "custom function" in this context.
> Particularly since your proposal contained a large amount of code.
>
It was an example which - obviously - predated both \resetRelativeOctave
and \makeRelative (you did notice the "version 2.8.0" at the start?)

I couldn't remember what \resetRelativeOctave was, so I was trying to
give him the clues he needed to find it. I did explicitly say "I think
it's now a standard part of lilypond" (implying it wasn't when that code
was written).

So let's give a very simple example of what I think he was trying to
achieve ...

arpeggio = { c e g c }
\new Staff {
   \relative c' {
     \arpeggio \resetRelativeOctave c'
     \arpeggio \resetRelativeOctave c'
     \arpeggio
   }
}

Despite being in relative mode, all the arpeggios will now start on
middle C. The OP's eXample is more complicated but as far as I can tell
this is what he's aiming at.

Oh - and I believe

arpeggio = { \resetRelativeOctave c' c e g c }

would also work. I don't know for certain because I haven't had this
problem since Pennsylvania.

Cheers,
Wol

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

David Kastrup
antlists <[hidden email]> writes:

> On 17/05/2020 00:04, David Kastrup wrote:
>> antlists <[hidden email]> writes:
>>
>>> On 16/05/2020 23:19, David Kastrup wrote:
>>>>> As I say, I think this function or something similar has made its way
>>>>> into lilypond proper.
>>>
>>>> What advantage over the solution using make-relative that I posted do
>>>> you see here?
>>>
>>> Because if I understand the OP correctly, what he wants is
>>> \resetRelativeOctave, which is already a standard part of lilypond?
>> What he wants is music used twice within a function not to end up in
>> different octaves.
>
> Isn't that what \resetRelativeOctave does?

No?  \resetRelativeOctave resets the current relative position to a
specified _absolute_ pitch.  But in the given situation, the function
does not _have_ a specified absolute pitch to revert to.

> So let's give a very simple example of what I think he was trying to
> achieve ...
>
> arpeggio = { c e g c }
> \new Staff {
>   \relative c' {
>     \arpeggio \resetRelativeOctave c'
>     \arpeggio \resetRelativeOctave c'
>     \arpeggio
>   }
> }

He was writing a _function_ using an expression twice.  Not ad-hoc code.
This function would not know what to use for c' here.

> Despite being in relative mode, all the arpeggios will now start on
> middle C. The OP's eXample is more complicated but as far as I can
> tell this is what he's aiming at.
>
> Oh - and I believe
>
> arpeggio = { \resetRelativeOctave c' c e g c }
>
> would also work. I don't know for certain because I haven't had this
> problem since Pennsylvania.

In that case, it would make much more sense to write

arpeggio = \relative c' { c e g c }

since then arpeggio does not leave the current relative position lying
around in some obscure location but rather does not touch it at all.

--
David Kastrup

Reply | Threaded
Open this post in threaded view
|

Re: Current octave in relative mode

Klaus Blum
In reply to this post by Klaus Blum
Peace be with you, guys...   ;-)

<quote author="Wols Lists">The OP's eXample is more complicated but as
far as I can tell
this is what he's aiming at.
</quote>

Of course, I did some experimenting on my own before asking here on the
list.
I was aware that the problem only appears if I use my function inside a
\relative statement, but not (as far as I remember) if I start a
\relative expression at the same moment the function is called. And, of
course, no problem in absolute mode.

I was hoping to to find a solution that can deal with all of the above
situations and the user doesn't have to care. That's why David's
solution is perfect for my aim.

I also have seen Han-Wen's function, but I could not test if it fits my
needs. It did not compile without errors. Maybe it doesn't work with
recent LY versions, maybe it was a mistake by me...

Thanks to everyone who replied. I'm glad this list exists and I know
where to find help.

Cheers,
Klaus