Re: relative music inside music functions explodes when used twice

2014-10-13 Thread David Kastrup
Janek Warchoł  writes:

> 2014-10-12 12:45 GMT+02:00 David Kastrup :
>> I'm not even sure I understand _how_ you want the relativization to
>> happen.  One after the other?
>
> If you mean \musicII should be relativized after \music, that's
> roughly what i want.
>
>> In that case, you can use
>>
>> voiceDivisi =
>> #(define-music-function (parser location m1 m2) (ly:music? ly:music?)
>>   (make-relative (m1 m2) #{ #m1 #m2 #}
>>   #{
>>   \tag divI { $m1 }
>>   \tag divII { $m2 }
>>   \tag together << { \dynamicUp $m1 } \\ { \dynamicDown $m2 } >>
>>   #}))
>
> Seems to work! :)
>
>> > How should i work around this?  Maybe instead of using tags i should
>> > write a function with a switch statement inside?  I know that i can
>> > put \relative command inside \voiceDivisi, but i'd like to avoid this
>> > as it would add a lot of typing.
>>
>> It seems like the ingenuity of my make-relative macro never really
>> caught on...
>
> I've found https://code.google.com/p/lilypond/issues/detail?id=3118
> and looked at input/regression/make-relative.ly but i don't think i
> really understand what it does (and how).

Probably neither do I.  Let's see.

(defmacro-public make-relative (variables reference music)
  "The list of pitch or music variables in @var{variables} is used as
a sequence for creating relativable music from @var{music}.

When the constructed music is used outside of @code{\\relative}, it
just reflects plugging in the @var{variables} into @var{music}.

The action inside of @code{\\relative}, however, is determined by
first relativizing the surrogate @var{reference} with the variables
plugged in and then using the variables relativized as a side effect
of relativizing @var{reference} for evaluating @var{music}.

Since pitches don't have the object identity required for tracing the
effect of the reference call, they are replaced @emph{only} for the
purpose of evaluating @var{reference} with simple pitched note events.

The surrogate @var{reference} expression has to be written with that
in mind.  In addition, it must @emph{not} contain @emph{copies} of
music that is supposed to be relativized but rather the
@emph{originals}.  This @emph{includes} the pitch expressions.  As a
rule, inside of @code{#@{@dots{}#@}} variables must @emph{only} be
introduced using @code{#}, never via the copying construct @code{$}.
The reference expression will usually just be a sequential or chord
expression naming all variables in sequence, implying that following
music will be relativized according to the resulting pitch of the last
or first variable, respectively.

Since the usual purpose is to create more complex music from general
arguments and since music expression parts must not occur more than
once, one @emph{does} generally need to use copying operators in the
@emph{replacement} expression @var{music} when using an argument more
than once there.  Using an argument more than once in @var{reference},
in contrast, does not make sense.

There is another fine point to mind: @var{music} must @emph{only}
contain freshly constructed elements or copied constructs.  This will
be the case anyway for regular LilyPond code inside of
@code{#@{@dots{}#@}}, but any other elements (apart from the
@var{variables} themselves which are already copied) must be created
or copied as well.

The reason is that it is usually permitted to change music in-place as
long as one does a @var{ly:music-deep-copy} on it, and such a copy of
the whole resulting expression will @emph{not} be able to copy
variables/values inside of closures where the information for
relativization is being stored.
"

That's some DOC string alright.  So how does it work?  Short of the doc
string, the definition is

(defmacro-public make-relative (variables reference music)
  (define ((make-relative::to-relative-callback variables music-call ref-call)
   music pitch)
(let* ((ref-vars (map (lambda (v)
(if (ly:pitch? v)
(make-music 'NoteEvent 'pitch v)
(ly:music-deep-copy v)))
  variables))
   (after-pitch (ly:make-music-relative! (apply ref-call ref-vars) 
pitch))
   (actual-vars (map (lambda (v r)
   (if (ly:pitch? v)
   (ly:music-property r 'pitch)
   r))
 variables ref-vars))
   (rel-music (apply music-call actual-vars)))
  (set! (ly:music-property music 'element) rel-music)
  after-pitch))
  `(make-music 'RelativeOctaveMusic
   'to-relative-callback
   (,make-relative::to-relative-callback
(list ,@variables)
(lambda ,variables ,music)
(lambda ,variables ,reference))
   'element ,music))

So it creates "RelativeOctaveMusic" (which is just a wrapper for
absolute and/or relativized music) but with an add

Re: relative music inside music functions explodes when used twice

2014-10-12 Thread Janek Warchoł
2014-10-12 12:45 GMT+02:00 David Kastrup :
> I'm not even sure I understand _how_ you want the relativization to
> happen.  One after the other?

If you mean \musicII should be relativized after \music, that's
roughly what i want.

> In that case, you can use
>
> voiceDivisi =
> #(define-music-function (parser location m1 m2) (ly:music? ly:music?)
>   (make-relative (m1 m2) #{ #m1 #m2 #}
>   #{
>   \tag divI { $m1 }
>   \tag divII { $m2 }
>   \tag together << { \dynamicUp $m1 } \\ { \dynamicDown $m2 } >>
>   #}))

Seems to work! :)

> > How should i work around this?  Maybe instead of using tags i should
> > write a function with a switch statement inside?  I know that i can
> > put \relative command inside \voiceDivisi, but i'd like to avoid this
> > as it would add a lot of typing.
>
> It seems like the ingenuity of my make-relative macro never really
> caught on...

I've found https://code.google.com/p/lilypond/issues/detail?id=3118
and looked at input/regression/make-relative.ly but i don't think i
really understand what it does (and how).  I'll try digging deeper,
but any additional explanations you could provide would be very
welcome (as i have very limited time available for tinkering...) - i'd
very much like to be able to understand your ingenuity :)

> By the way: I'm not sure it will be transparent enough to have << \\ >>
> be recognized at the proper point of time.  If not, you'll need to use
> explicit voices instead.

Absolutely.  My code is just a proof of concept, and I've used << \\
>> to minimize the example.

best,
Janek

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: relative music inside music functions explodes when used twice

2014-10-12 Thread David Kastrup
Janek Warchoł  writes:

> Thanks David and Paul - that's helpful.  However, while the situation
> improved the output is still not what i want:
> \version "2.19.13"
>
> voiceDivisi =
> #(define-music-function (parser location m1 m2) (ly:music? ly:music?)
>#{
>  \tag divI { $m1 }
>  \tag divII { $m2 }
>  \tag together << { \dynamicUp $m1 } \\ { \dynamicDown $m2 } >>
>#})
>
> music = \relative c' {
>   \voiceDivisi {
> c4 d e f
>   }{
> a,1
>   }
> }
> musicII = \relative c' {
>   \voiceDivisi {
> f4 e d c
>   } {
> a1
>   }
> }
>
> \new Staff \with { instrumentName = "part I" }
> \removeWithTag divII.together { \music \musicII }
>
> \new Staff \with { instrumentName = "part II" }
> \removeWithTag divI.together { \music \musicII }
>
> \new Staff \with { instrumentName = "combined" }
> \removeWithTag divI.divII { \music \musicII }
>
> if i understand correctly, "relativization" happens too late, i.e. after
> the music is processed by the voiceDivisi function.

I'm not even sure I understand _how_ you want the relativization to
happen.  One after the other?  In that case, you can use

voiceDivisi =
#(define-music-function (parser location m1 m2) (ly:music? ly:music?)
  (make-relative (m1 m2) #{ #m1 #m2 #}
  #{
  \tag divI { $m1 }
  \tag divII { $m2 }
  \tag together << { \dynamicUp $m1 } \\ { \dynamicDown $m2 } >>
  #}))

> How should i work around this?  Maybe instead of using tags i should
> write a function with a switch statement inside?  I know that i can
> put \relative command inside \voiceDivisi, but i'd like to avoid this
> as it would add a lot of typing.

It seems like the ingenuity of my make-relative macro never really
caught on...

By the way: I'm not sure it will be transparent enough to have << \\ >>
be recognized at the proper point of time.  If not, you'll need to use
explicit voices instead.

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: relative music inside music functions explodes when used twice

2014-10-12 Thread Janek Warchoł
Thanks David and Paul - that's helpful.  However, while the situation
improved the output is still not what i want:
\version "2.19.13"

voiceDivisi =
#(define-music-function (parser location m1 m2) (ly:music? ly:music?)
   #{
 \tag divI { $m1 }
 \tag divII { $m2 }
 \tag together << { \dynamicUp $m1 } \\ { \dynamicDown $m2 } >>
   #})

music = \relative c' {
  \voiceDivisi {
c4 d e f
  }{
a,1
  }
}
musicII = \relative c' {
  \voiceDivisi {
f4 e d c
  } {
a1
  }
}

\new Staff \with { instrumentName = "part I" }
\removeWithTag divII.together { \music \musicII }

\new Staff \with { instrumentName = "part II" }
\removeWithTag divI.together { \music \musicII }

\new Staff \with { instrumentName = "combined" }
\removeWithTag divI.divII { \music \musicII }

if i understand correctly, "relativization" happens too late, i.e. after
the music is processed by the voiceDivisi function.
How should i work around this?  Maybe instead of using tags i should write
a function with a switch statement inside?  I know that i can put \relative
command inside \voiceDivisi, but i'd like to avoid this as it would add a
lot of typing.

best,
Janek

2014-10-11 21:01 GMT+02:00 David Kastrup :

> Janek Warchoł  writes:
>
> > Hi,
> >
> > i have a function that takes music as an argument and uses it twice -
> each
> > time with a different tag appended, so that later on i can decide what to
> > output:
> >
> > voiceDivisi =
> > #(define-music-function (parser location m1 m2) (ly:music? ly:music?)
> >#{
> >  \tag divI \context Voice = "divI" { #m1 }
> >  \tag divII \context Voice = "divII" { #m2 }
> >  \tag together \context Voice = "both" << #m1 #m2 >>
> >#})
> >
> > The problem is that when used with relative mode, the output gets crazy:
> >
> > music = \relative c' {
> >   \voiceDivisi {
> > c4 d e f
> >   }
> >   {
> > e4 f g a
> >   }
> > }
> >
> > \new Staff \keepWithTag divI \music
> > \new Staff \keepWithTag divII \music
> > \new Staff \keepWithTag together \music
> >
> > (see attachment)
> >
> > I have checked that the problem disappears when the function uses the
> > arguments (m1 and m2) only once.  Is this a bug?
>
> No.
>
>  http://www.lilypond.org/doc/v2.19/Documentation/extending/adding-articulation-to-notes-_0028example_0029
> >
>
> In an earlier example, we constructed music by repeating a given
> music argument. In that case, at least one repetition had to be a
> copy of its own. If it weren’t, strange things may happen. For
> example, if you use \relative or \transpose on the resulting music
> containing the same elements multiple times, those will be subjected
> to relativation or transposition multiple times. If you assign them
> to a music variable, the curse is broken since referencing ‘\name’
> will again create a copy which does not retain the identity of the
> repeated elements.
>
> > Can i work around it, or maybe i should be doing this in an altogether
> > different way?
>
> Use ly:music-deep-copy on one of the copies.  Better both.  Or write $x
> instead of #x in order to get such a copy.
>
> --
> David Kastrup
>
>
> ___
> lilypond-user mailing list
> lilypond-user@gnu.org
> https://lists.gnu.org/mailman/listinfo/lilypond-user
>
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: relative music inside music functions explodes when used twice

2014-10-11 Thread David Kastrup
Janek Warchoł  writes:

> Hi,
>
> i have a function that takes music as an argument and uses it twice - each
> time with a different tag appended, so that later on i can decide what to
> output:
>
> voiceDivisi =
> #(define-music-function (parser location m1 m2) (ly:music? ly:music?)
>#{
>  \tag divI \context Voice = "divI" { #m1 }
>  \tag divII \context Voice = "divII" { #m2 }
>  \tag together \context Voice = "both" << #m1 #m2 >>
>#})
>
> The problem is that when used with relative mode, the output gets crazy:
>
> music = \relative c' {
>   \voiceDivisi {
> c4 d e f
>   }
>   {
> e4 f g a
>   }
> }
>
> \new Staff \keepWithTag divI \music
> \new Staff \keepWithTag divII \music
> \new Staff \keepWithTag together \music
>
> (see attachment)
>
> I have checked that the problem disappears when the function uses the
> arguments (m1 and m2) only once.  Is this a bug?

No.

http://www.lilypond.org/doc/v2.19/Documentation/extending/adding-articulation-to-notes-_0028example_0029>

In an earlier example, we constructed music by repeating a given
music argument. In that case, at least one repetition had to be a
copy of its own. If it weren’t, strange things may happen. For
example, if you use \relative or \transpose on the resulting music
containing the same elements multiple times, those will be subjected
to relativation or transposition multiple times. If you assign them
to a music variable, the curse is broken since referencing ‘\name’
will again create a copy which does not retain the identity of the
repeated elements.

> Can i work around it, or maybe i should be doing this in an altogether
> different way?

Use ly:music-deep-copy on one of the copies.  Better both.  Or write $x
instead of #x in order to get such a copy.

-- 
David Kastrup


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: relative music inside music functions explodes when used twice

2014-10-11 Thread Paul Morris
Janek Warchoł wrote
> The problem is that when used with relative mode, the output gets crazy:

Hi Janek, you just need to use $m1 instead of #m1 in your function.
http://lilypond.org/doc/v2.18/Documentation/extending/scheme-function-definitions
HTH,
-Paul

\version "2.18.2"

voiceDivisi =
#(define-music-function (parser location m1 m2) (ly:music? ly:music?)
   #{
 \tag divI \context Voice = "divI" { $m1 }
 \tag divII \context Voice = "divII" { $m2 }
 \tag together \context Voice = "both" << $m1 $m2 >>
   #})

% The problem is that when used with relative mode, the output gets crazy:

music = \relative c' {
  \voiceDivisi {
c4 d e f
  }
  {
e4 f g a
  }
}

\new Staff \keepWithTag divI \music
\new Staff \keepWithTag divII \music
\new Staff \keepWithTag together \music



--
View this message in context: 
http://lilypond.1069038.n5.nabble.com/relative-music-inside-music-functions-explodes-when-used-twice-tp167420p167422.html
Sent from the User mailing list archive at Nabble.com.

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


relative music inside music functions explodes when used twice

2014-10-11 Thread Janek Warchoł
Hi,

i have a function that takes music as an argument and uses it twice - each
time with a different tag appended, so that later on i can decide what to
output:

voiceDivisi =
#(define-music-function (parser location m1 m2) (ly:music? ly:music?)
   #{
 \tag divI \context Voice = "divI" { #m1 }
 \tag divII \context Voice = "divII" { #m2 }
 \tag together \context Voice = "both" << #m1 #m2 >>
   #})

The problem is that when used with relative mode, the output gets crazy:

music = \relative c' {
  \voiceDivisi {
c4 d e f
  }
  {
e4 f g a
  }
}

\new Staff \keepWithTag divI \music
\new Staff \keepWithTag divII \music
\new Staff \keepWithTag together \music

(see attachment)

I have checked that the problem disappears when the function uses the
arguments (m1 and m2) only once.  Is this a bug?  Can i work around it, or
maybe i should be doing this in an altogether different way?

best,
Janek
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user