Re: relative music inside music functions explodes when used twice
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 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
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
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
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
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
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