|
|
Created:
13 years, 8 months ago by MikeSol Modified:
13 years, 8 months ago Reviewers:
mike, Graham Percival, james.lowe, carl.d.sorensen, Neil Puttock, c_sorensen, reinhold, bernardobarros2, pkx166h, hanwenn CC:
lilypond-devel_gnu.org Visibility:
Public. |
DescriptionAdds glissando stems to Lilypond.
Patch Set 1 #Patch Set 2 : Fixes naming. #
Total comments: 9
Patch Set 3 : Addresses comments from Han-Wen and Neil. #Patch Set 4 : Fixes issue with beam slopes. #Patch Set 5 : Fixes some tremolo issues. #Patch Set 6 : Documents stem placement function. #Patch Set 7 : Adds event property definition for glissando-stem #Patch Set 8 : Nixes message in stem-tremolo. #
Total comments: 1
Patch Set 9 : Minimal implementation of glissando stems. #Patch Set 10 : Creates new GlissandoStem grob. #
Total comments: 28
Patch Set 11 : Merge with new stem code. #
MessagesTotal messages: 35
I have a functional version of this feature up with a regtest. I think the input syntax works, but it could be cleaner. All suggestions are welcome! Off now to typeset crazy glissandi... Cheers, MS
Sign in to reply to this message.
hello, I'm in no way qualified to comment on code, but am uncomfortable with the function name: \startGStems It has two caps in the middle and is 'plural'. \startGlissandoStem while quite long, isn't that long. I realise this is not GLISS but thought it worth mentioning now.
Sign in to reply to this message.
On Thu, Jun 30, 2011 at 09:21:21AM +0000, pkx166h@gmail.com wrote: > \startGlissandoStem > > while quite long, isn't that long. +1 > I realise this is not GLISS but thought it worth mentioning now. Long-term, I'll be pushing for a different naming scheme, but I have no objection to \startGlissandoStem for the next few months. Cheers, - Graham
Sign in to reply to this message.
> Long-term, I'll be pushing for a different naming scheme, but I > have no objection to \startGlissandoStem for the next few months. > > Cheers, > - Graham New patchset up w/ changed names. Cheers, MS
Sign in to reply to this message.
can you show png examples of what you're trying to do? I think this patch has serious issues. http://codereview.appspot.com/4661061/diff/13/lily/music-sequence.cc File lily/music-sequence.cc (right): http://codereview.appspot.com/4661061/diff/13/lily/music-sequence.cc#newcode118 lily/music-sequence.cc:118: continue; why can't you do this with an override for the to-relative function property? http://codereview.appspot.com/4661061/diff/13/lily/note-spacing.cc File lily/note-spacing.cc (right): http://codereview.appspot.com/4661061/diff/13/lily/note-spacing.cc#newcode53 lily/note-spacing.cc:53: if (to_boolean (stem->get_property ("glissando-stem"))) if (a&&b) .. http://codereview.appspot.com/4661061/diff/13/lily/note-spacing.cc#newcode258 lily/note-spacing.cc:258: if (!stem || !stem->is_live () || Stem::is_invisible (stem) || to_boolean (stem->get_property ("glissando-stem"))) didn't we have a gop or something prohibiting tabs? http://codereview.appspot.com/4661061/diff/13/lily/stem.cc File lily/stem.cc (right): http://codereview.appspot.com/4661061/diff/13/lily/stem.cc#newcode1082 lily/stem.cc:1082: Stem::after_line_breaking (SCM smob) can you rethink your functionality to not need this callback? we should try to kill the {after/before}_linebreaking functions as they dont play well with the callback on get_property() mechanism http://codereview.appspot.com/4661061/diff/13/lily/stem.cc#newcode1116 lily/stem.cc:1116: Spanner *gls = dynamic_cast<Spanner *> (glissandi[i]); to_spanner() ? http://codereview.appspot.com/4661061/diff/13/lily/stem.cc#newcode1118 lily/stem.cc:1118: Spanner *orig = gls->is_broken () ? gls : dynamic_cast<Spanner *> (gls->original ()); hosed if gls == NULL http://codereview.appspot.com/4661061/diff/13/lily/stem.cc#newcode1133 lily/stem.cc:1133: huh? What is this needed for? The break processing automatically substitutes spanners to only point to the ones in the same system.
Sign in to reply to this message.
Hi Mike, The interface is an improvement on the patch you originally posted, but it still leaves a lot to be desired. :) I don't like the way you flag the glissando stems; ideally they'd be a separate grob which doesn't require noteheads and legers to be removed. Cheers, Neil http://codereview.appspot.com/4661061/diff/13/lily/stem.cc File lily/stem.cc (right): http://codereview.appspot.com/4661061/diff/13/lily/stem.cc#newcode532 lily/stem.cc:532: Grob *glissando_column = unsmob_grob (me->get_object ("glissando-column")); glissando-column is unused http://codereview.appspot.com/4661061/diff/13/ly/music-functions-init.ly File ly/music-functions-init.ly (right): http://codereview.appspot.com/4661061/diff/13/ly/music-functions-init.ly#newc... ly/music-functions-init.ly:386: 'ignore-in-relative #t you don't need this, since there's already a callback for relative mode which you can override: 'to-relative-callback (lambda (music pitch) pitch) -> ignore these pitches in relative mode
Sign in to reply to this message.
On Jun 30, 2011, at 5:29 PM, hanwenn@gmail.com wrote: > can you show png examples of what you're trying to do? >
Sign in to reply to this message.
On Jun 30, 2011, at 5:29 PM, n.puttock@gmail.com wrote: > Hi Mike, > > The interface is an improvement on the patch you originally posted, but > it still leaves a lot to be desired. :) > If it didn't, my patch wouldn't have potential, and who likes a patch without potential? > I don't like the way you flag the glissando stems; ideally they'd be a > separate grob which doesn't require noteheads and legers to be removed. > > Ideally, people should be able to use whatever noteheads they desire (i.e. x noteheads to represent intermittent full stops during a harmonic glissando) and adjust the stem accordingly. Furthermore, these stems need to be able to carry dynamics, articulations, markups, and all the other things that a note column carries. { a''1 \glissando\p\< \startGlissandoStem \override Stem #'glissando-stem = ##t <d g>4 <d g>8 <d g>8\> <d g>16 <d g>16\< <d g>8 <d g>4 \override Stem #'glissando-stem = ##f \stopGlissandoStem c'1\fff }
Sign in to reply to this message.
Hey Han-Wen, I see the to_spanner of which you speak in gdb.cc, but I'm not sure how to access it. Should a gdb.hh be put in include/ so that it can be included and used? Cheers, MS On Jun 30, 2011, at 5:29 PM, hanwenn@gmail.com wrote: > can you show png examples of what you're trying to do? > > I think this patch has serious issues. > > > http://codereview.appspot.com/4661061/diff/13/lily/music-sequence.cc > File lily/music-sequence.cc (right): > > http://codereview.appspot.com/4661061/diff/13/lily/music-sequence.cc#newcode118 > lily/music-sequence.cc:118: continue; > why can't you do this with an override for the to-relative function > property? > > http://codereview.appspot.com/4661061/diff/13/lily/note-spacing.cc > File lily/note-spacing.cc (right): > > http://codereview.appspot.com/4661061/diff/13/lily/note-spacing.cc#newcode53 > lily/note-spacing.cc:53: if (to_boolean (stem->get_property > ("glissando-stem"))) > if (a&&b) .. > > http://codereview.appspot.com/4661061/diff/13/lily/note-spacing.cc#newcode258 > lily/note-spacing.cc:258: if (!stem || !stem->is_live () || > Stem::is_invisible (stem) || to_boolean (stem->get_property > ("glissando-stem"))) > didn't we have a gop or something prohibiting tabs? > > http://codereview.appspot.com/4661061/diff/13/lily/stem.cc > File lily/stem.cc (right): > > http://codereview.appspot.com/4661061/diff/13/lily/stem.cc#newcode1082 > lily/stem.cc:1082: Stem::after_line_breaking (SCM smob) > can you rethink your functionality to not need this callback? > > we should try to kill the {after/before}_linebreaking functions as they > dont play well with the callback on get_property() mechanism > > http://codereview.appspot.com/4661061/diff/13/lily/stem.cc#newcode1116 > lily/stem.cc:1116: Spanner *gls = dynamic_cast<Spanner *> > (glissandi[i]); > to_spanner() ? > > http://codereview.appspot.com/4661061/diff/13/lily/stem.cc#newcode1118 > lily/stem.cc:1118: Spanner *orig = gls->is_broken () ? gls : > dynamic_cast<Spanner *> (gls->original ()); > hosed if gls == NULL > > http://codereview.appspot.com/4661061/diff/13/lily/stem.cc#newcode1133 > lily/stem.cc:1133: > huh? > > What is this needed for? The break processing automatically substitutes > spanners to only point to the ones in the same system. > > http://codereview.appspot.com/4661061/
Sign in to reply to this message.
New patch-set uploaded addressing all minor concerns so far. The biggest change is that, as per Han-Wen's suggestion, the glissando-stem stuff no longer happens courtesy of after-line-breaking but rather in response to a callback for glissando-stem.
Sign in to reply to this message.
Added issue 1727 for tracking
Sign in to reply to this message.
Hey all, I've uploaded a new patchset that kinda sorta makes tremolos work. There are still issues with beam placement and tremolo placement, though, that I'll need to work out. In the first attached example, you'll see that the beam is typeset in the wrong direction and yet pushes the dynamics as if it were typeset in the correct direction. In the second, the beam is forced in the correct direction, but the tremolo placement is incorrect. Anyway, this gives you more of an idea of what I'm after. I think that, rather than inventing a new grob to handle this, stems already provide a lot of valuable functionality that, with the correct code, can be exploited for these glissando stems. As of now, I can't think of any way to make these stems work with scripts. Scripts, through the side-position-interface, need to know their direction before line breaking. I'd need a few hours to try to figure out a workaround. The glissando stems don't go bonkers, though, with text scripts and dynamics, although I've only run a couple test cases. This is all a subset of the perennial issue in Lilypond that all directions of grobs are known (or knowable) by the horizontal spacing upon which the line breaking is based, which changes glissando length, which may change stem direction, which changes the direction of some grobs, which would change the horizontal spacing, and thus the line breaking, which naturally changes glissando length, which could potentially have an impact on stem direction, therefore changing the direction of some grobs, which would.... Cheers, MS
Sign in to reply to this message.
On 2011/07/01 09:33:50, mike_apollinemike.com wrote: > Hey all, > I've uploaded a new patchset that kinda sorta makes tremolos work. I'm struggling to get a clean 'make check' I always get an Error 1 Looking back it seems I found the place.. Processing `/home/james/lilypond-git/build/out/lybook-testdb/35/lily-87d99e07.ly' Parsing... Renaming input to: `glissando-stem.ly' warning: cannot find property type-check for `glissando-stem' (music-type?). perhaps a typing error? Writing timing to 35/lily-87d99e07.profile... Hope this helps.
Sign in to reply to this message.
On Jul 1, 2011, at 12:47 PM, pkx166h@gmail.com wrote: > On 2011/07/01 09:33:50, mike_apollinemike.com wrote: >> Hey all, >> I've uploaded a new patchset that kinda sorta makes tremolos work. > > I'm struggling to get a clean 'make check' I always get an Error 1 > > Looking back it seems I found the place.. > > Processing > `/home/james/lilypond-git/build/out/lybook-testdb/35/lily-87d99e07.ly' > Parsing... > Renaming input to: `glissando-stem.ly' > warning: cannot find property type-check for `glissando-stem' > (music-type?). perhaps a typing error? > > Writing timing to 35/lily-87d99e07.profile... > > Hope this helps. > Fixed, new patch set uploaded. Cheers, MS
Sign in to reply to this message.
sorry - disregard; brainfart. On Thu, Jun 30, 2011 at 1:09 PM, mike@apollinemike.com <mike@apollinemike.com> wrote: > Hey Han-Wen, > > I see the to_spanner of which you speak in gdb.cc, but I'm not sure how to access it. Â Should a gdb.hh be put in include/ so that it can be included and used? -- Han-Wen Nienhuys - hanwen@xs4all.nl - http://www.xs4all.nl/~hanwen
Sign in to reply to this message.
On Thu, Jun 30, 2011 at 12:46 PM, mike@apollinemike.com <mike@apollinemike.com> wrote: >> can you show png examples of what you're trying to do? Honestly, I cannot allow this patch in its current design. I don't see a reason for an obscure feature to be touching code of note-spacing, stem-tremolo, stem, beam etc. If we add patches like this for every composer's favorite avant-garde notation, the large parts of the lilypond codebase will shortly become a tangle of hard to understand dependencies; code for uncommon notation constructs should only be added if their implementation is separate, modular and generic. This patch is neither. Can you try a minimal implementation first? For example, * Have a stem property that determines the end of the stem. Currently, we have y2 = Staff_symbol_referencer::get_position (lh); for that. This feature is generic and cleanly implemented with a callback. Should be a separate patch. * Have a mechanism for glissando engraver to ignore note-heads. Maybe a boolean property: #'glissando-note Then, in your .ly file you do the following * Have an engraver (by preference written in Scheme) that hooks up the glissandi with the stems. * Create normal beamed 16th notes with #'glissando-note on their note-heads. * Hook a callback on that, that looks at the glissando's slope and the stem's X position to determine where the stem starts printing * Make the noteheads very small and invisible. hope this helps. On a tangent: what is the glissando-index property for? I can't see it being read anywhere. -- Han-Wen Nienhuys - hanwen@xs4all.nl - http://www.xs4all.nl/~hanwen
Sign in to reply to this message.
Hey Han Wen, I'm responding to your e-mail backwards, with answers to the technical parts first followed by answers to the broader questions you raise. > Can you try a minimal implementation first? For example, > > * Have a stem property that determines the end of the stem. Currently, we have > > y2 = Staff_symbol_referencer::get_position (lh); > The problem with this is that the stem's direction needs to be known by other grobs before the print function is called (before line breaking, even). This could result in the scenario where the stem has the correct terminus but the direction is based on whatever the original fictive note position was, leading to stems that don't go the way one would expect them to go given their terminal point w/ the glissando. > * Have a mechanism for glissando engraver to ignore note-heads. Maybe > a boolean property: #'glissando-note > This would be necessary - it is part of the current patch. > Then, in your .ly file you do the following > > * Have an engraver (by preference written in Scheme) that hooks up the > glissandi with the stems. > > * Create normal beamed 16th notes with #'glissando-note on their note-heads. > > * Hook a callback on that, that looks at the glissando's slope and the > stem's X position to determine where the stem starts printing > > * Make the noteheads very small and invisible. > This was what I originally did, but the crucial issue that arises is that of stem direction. Left to its own devices, Lily will pick the direction of whatever original arbitrary pitch was chosen, which may be nowhere near where the glissando actually falls. Even if a typesetter does her best to estimate this meetup point, it cannot be guaranteed, forcing the typesetter to manually set the direction of any problematic stems (and re-set the direction of the length of the glissando changes because of activity in other staves & changes to the horizontal spacing). > > Honestly, I cannot allow this patch in its current design. I don't see > a reason for an obscure feature to be touching code of note-spacing, > stem-tremolo, stem, beam etc. > You say that this is obscure, but this is a staple feature of innumerable contemporary scores. I encourage you to read through works for strings written by Helmut Lachenmann, Chaya Czernowin, Karlheinz Stockhausen, Mark Applebaum, Roger Reynolds, and Iannis Xenakis, just for starters. You will find this notation all over their music. This is only obscure to a person if contemporary music is obscure to that person. The goal is not to change note-spacing, stem-tremolos, stems, or beams, but rather to find intelligent exceptions to their default mechanisms that accommodate these stems. > If we add patches like this for every composer's favorite avant-garde > notation, the large parts of the lilypond codebase will shortly become > a tangle of hard to understand dependencies; I agree. In order to make the distinction between people's pet projects in notation land (which I do on the side, outside of my lilypond development efforts - check out my graphical notation stuff, for example, which I would never want to include in LilyPond) and essential advancements in contemporary musical writing and typesetting, I would encourage you to do the survey of the above literature. After having done so, you would be empirically obliged to acknowledge that what I'm proposing is a favorite of almost everybody. > code for uncommon > notation constructs should only be added if their implementation is > separate, modular and generic. Early music particularities find their way into the heart of the code, as do those having to do with feathered beams (which I'm glad you added to LilyPond (and which are as obscure as (if not more than) glissando stems in the contemporary repertoire)), both of which only apply to a certain swath of music. I think there is nothing wrong with hardcoding something into the guts of LilyPond, with ample comments, if it allows LilyPond to perform better for an important aspect of musical engraving. Lest one stand in opposition to several Pulitzer Prize winning pieces and many-a Guggenheim fellow, glissando stems are unambiguously important. Making LilyPond modular is a good idea (I'm all for porting as much to scheme as possible), and separate comes with modular, but I do not see any way to do it here outside of what I've already done (most of the work is done in one callback linked up to glissando-stem). As for generic, this seems to be a generic approach - using a Stem (generic) to serve multiple functions instead of creating a new grob that code dups a fair bit of its functionality. Cheers, MS
Sign in to reply to this message.
On Fri, Jul 01, 2011 at 07:17:08PM +0200, mike@apollinemike.com wrote: > I'm responding to your e-mail backwards, with answers to the technical > parts first followed by answers to the broader questions you raise. I'll briefly comment on those broader questions. > * Have an engraver (by preference written in Scheme) that hooks up the > glissandi with the stems. This might be an ideal way forward -- not necessarily with this specific issue, but as a general means of extending lilypond. I think it could be really helpful if we had a few more examples of how to write + include such scheme engravers. > This was what I originally did, but the crucial issue that arises is that > of stem direction. Left to its own devices, Lily will pick the direction > of whatever original arbitrary pitch was chosen, which may be nowhere near > where the glissando actually falls. If we want to push the ideal of custom scheme engravers (and I don't want to assume that we _do_ want to encourage this approach, although at the moment I can't think of any problems with it), then perhaps we need more hooks to pass information around, to allow "programmer" users to avoid such problems with their custom scheme engravers. > code for uncommon > notation constructs should only be added if their implementation is > separate, modular and generic. > > Early music particularities find their way into the heart of the code, as > do those having to do with feathered beams (which I'm glad you added to > LilyPond (and which are as obscure as (if not more than) glissando stems > in the contemporary repertoire)), both of which only apply to a certain > swath of music. I think there is nothing wrong with hardcoding something > into the guts of LilyPond, with ample comments, if it allows LilyPond to > perform better for an important aspect of musical engraving. I'm not certain about this point -- but I mean this literally, rather than the "understated British manner" of politely saying "I disagree". I am not at all certain how much hard-coding we want, either in our current code or future code. I think few people would argue against a general notion that "separate, modular and generic" code is good, but such general sayings have a habit of breaking down when we look at specific cases. Could we postpone this discussion for a few weeks, and tackle it as a serious GOP proposal? I think a good way to approach the question is by thinking about our *current* code base -- what do we think about the balance of "specific features vs. generic mechanisms" in current git? People naturally assume that if they follow the existing practices, then a patch will be ok, but I don't think we should assume that everybody likes the current code base. Cheers, - Graham
Sign in to reply to this message.
2011/7/1 Han-Wen Nienhuys <hanwenn@gmail.com>: > If we add patches like this for every composer's favorite avant-garde > notation, the large parts of the lilypond codebase will shortly become > a tangle of hard to understand dependencies; code for uncommon > notation constructs should only be added if their implementation is Hi Han-Wen, I agree that new features should not break simple features, but please do not prevent this software to be a valid free alternative for contemporary composers that are sick of software like Finale and Sibelius not caring *at all+ about contemporary music, since contemporary music does not have a big ``market share''. And I share enthusiasm for LilyPond exactly because of its potential for expanding on those ``not commercially interesting'' territories. BTW It's not a esoteric contemporary notation. I'd say it is pretty common the music composed in the last 4 decades. But I understand your main concern is not breaking old code and features, on that I completely agree with you :=)
Sign in to reply to this message.
On Jul 1, 2011, at 7:45 PM, Graham Percival wrote: > On Fri, Jul 01, 2011 at 07:17:08PM +0200, mike@apollinemike.com wrote: >> I'm responding to your e-mail backwards, with answers to the technical >> parts first followed by answers to the broader questions you raise. > > I'll briefly comment on those broader questions. > >> * Have an engraver (by preference written in Scheme) that hooks up the >> glissandi with the stems. > > This might be an ideal way forward -- not necessarily with this > specific issue, but as a general means of extending lilypond. I > think it could be really helpful if we had a few more examples of > how to write + include such scheme engravers. > I completely agree - I use custom engravers all the time to hook stuff up. Either that or I write stuff in Python that auto-generates LilyPond syntax. >> This was what I originally did, but the crucial issue that arises is that >> of stem direction. Left to its own devices, Lily will pick the direction >> of whatever original arbitrary pitch was chosen, which may be nowhere near >> where the glissando actually falls. > > If we want to push the ideal of custom scheme engravers (and I > don't want to assume that we _do_ want to encourage this approach, > although at the moment I can't think of any problems with it), > then perhaps we need more hooks to pass information around, to > allow "programmer" users to avoid such problems with their custom > scheme engravers. I think information is already very well passed around - a custom engraver can listen to anything, acknowledge anything, create any grob, etc.. As you say above, we just need more examples. The issue in this particular case is subtle. Deep in the optical spacing code (far removed from anything a user could reasonably override or do without), there are decisions made based on a stem's direction, but the direction of a glissando stem cannot be known until the line breaking is done and the full length of the glissando is known. This is also the issue with pure properties, as Joe pointed out a little while ago. Even if this issue has ceased to show itself because of good safeguarding, it is still present. I am a proponent of using mixed integer linear programming to solve these issues. I believe that 100% of LilyPond's spacing could be rewritten as constraints in a linear program, in which case the vertical and horizontal spacing would all happen at the same time, and contingencies like this could be built into the linear program. That'd take a lot of time, but if people were interested, I would love to work on this. It would also make LilyPond more modular because cyclical dependencies could be simply sorted out in the linear program instead of avoid through the nightmare to which Han-Wen alludes when he correctly warns against source code fraught with exceptions. Cheers, MS
Sign in to reply to this message.
On 7/1/11 2:12 PM, "mike@apollinemike.com" <mike@apollinemike.com> wrote: > > I am a proponent of using mixed integer linear programming to solve these > issues. I believe that 100% of LilyPond's spacing could be rewritten as > constraints in a linear program, in which case the vertical and horizontal > spacing would all happen at the same time, and contingencies like this could > be built into the linear program. I think I agree with you, in theory, that the music layout problem could be written as a mixed integer linear programming problem. But mixed integer linear programming problems are generally NP-hard, so I don't think that would buy us much. I also believe there is a practical problem as well -- when all the elements in a score are connected for purposes of spacing calculations, the space required grows quadratically, and I don't think it would be solvable on real computers, even if I'm wrong in my previous paragraph. But I haven't studied these things carefully enough to say that my beliefs are correct. I do think, however, that they are plausible. > That'd take a lot of time, but if people > were interested, I would love to work on this. It would also make LilyPond > more modular because cyclical dependencies could be simply sorted out in the > linear program instead of avoid through the nightmare to which Han-Wen alludes > when he correctly warns against source code fraught with exceptions. I believe the cyclical dependencies are actually an important characteristic of the problem, rather than an undesired result of the solution technique. But I'd be very happy to be shown wrong in this belief . Thanks, Carl
Sign in to reply to this message.
On Jul 1, 2011, at 5:50 PM, Han-Wen Nienhuys wrote: > On Thu, Jun 30, 2011 at 12:46 PM, mike@apollinemike.com > <mike@apollinemike.com> wrote: >>> can you show png examples of what you're trying to do? > > > Can you try a minimal implementation first? For example, > The more I think about this problem, the less tractable it is. It leads unpredictably to infinite loops when calculating direction no matter how you cut it (horizontal placement depends on note column width which depends on horizontal placement). I'll try the minimum implementation you suggest below with the known issue that users must manually set the direction of all glissandi stem. Cheers, MS
Sign in to reply to this message.
Looking at the details of the code, it seems fine. But I tend to agree with Han-Wen's concerns. I'm wondering if it's possible to avoid code dup by making a base_stem_engraver of which glissando_stem_engraver and stem_engraver would be children. I probably don't have the right terminology for this (in fact I'm sure I don't), but I'm thinking of what happens with ligature_engraver and mensural_ligature_engraver. Feel free to ignore this message if it's not helpful. I haven't tried it and don't have a concrete suggestion. Thanks, Carl http://codereview.appspot.com/4661061/diff/12004/lily/stem.cc File lily/stem.cc (right): http://codereview.appspot.com/4661061/diff/12004/lily/stem.cc#newcode1093 lily/stem.cc:1093: programming_error ("Glissandi stem must have two and only two noteheads."); I'd probably prefer to have this stated "Glissando stem does not have exactly two noteheads", because then it's a description of the error, instead of a description of the desired behavior.
Sign in to reply to this message.
On Jul 5, 2011, at 6:10 AM, Carl.D.Sorensen@gmail.com wrote: > Looking at the details of the code, it seems fine. > > But I tend to agree with Han-Wen's concerns. > > I'm wondering if it's possible to avoid code dup by making a > base_stem_engraver of which glissando_stem_engraver and stem_engraver > would be children. > > I probably don't have the right terminology for this (in fact I'm sure I > don't), but I'm thinking of what happens with ligature_engraver and > mensural_ligature_engraver. > This is a good idea, although I think that the overlap is significant enough that they can co-habitate one engraver (I can see them varying in one function call maximum). But the logic is exactly this. I absolutely agree w/ Han-Wen that solutions should be generic, and I feel that this problem is the subset of the larger problem that the simple spacer is agnostic of the spacing in other lines. This fouls up a few scenarios: 1) Glissando stems are grobs whose directions change based on horizontal spacing, causing certain elements to change direction, which causes different stencils (think tremolos / articulations) & extents that could subsequently effect the value of the line forces calculated in Constrained_breaking::initialize (). A better way to say this is that these forces should not be static but rather contingent on the distribution of stems on neighboring lines. 2) Certain arpeggio substitutes, such as chord braces and chord slurs, change their width in response to the distance between staves, which changes based on horizontal spacing. Currently, this distance between staves is calculated way downstream from the simple spacer. 3) textLengthOn and textLengthOff. Currently, there is no way to automatically space lines such that (a) a4^"really really really really really really really really long" doesn't fall towards the end of a line; or even better (b) a function distributes spacing error across subsequent lines such that other quarter notes around a4^"really really really really really really really really long" have similar distances that get more "normal" as the quarters get farther away from this distance. This function calculates a sort of force can be accessed via the same system of penalties used for ties/slurs/beams. All of these issues would be solvable in the following scenario. Note that the following scenario is VERY inefficient, but there are shortcuts that could be taken to cache certain values. 1) In any given score, there are always 2**(n-1) line breaking configurations possible, where n is the size of the vector breaks (see line 396 of simple-spacer.cc). 2) Each of these configurations is subject to various callbacks that determine how to handle glissando stems, distribute spacing error, widen/shorten arpeggios, etc. The properties that are changed based on these functions would be marked internally as `volatile', and their values would not be cached until after a good spacing was chosen. For example, in glissando stems, stem direction, stem tremolo direction / extent / stencil, articulation direction / extent / stencil are all volatile. 3) Make the lines_ of a constrained breaker a sparse binary tree (see below) of matrices, not a single matrix, that stores the information above. Each node of the tree would branch off into break/noBreak for a single point in breaks. The above approach is, of course, absurdly large as it would require 1125899906842624 line-breaking matrices for a 51 measure score (2**(51-1)). However, a lot of caching can happen based on where there are and aren't volatile grobs. It is for this reason that I say "sparse" binary tree (or a binary tree where, if after node n all paths lead to the same result, node n represents all of these paths). This can be made even sparser because certain paths will invariably start the same, diverge, and meet back up at certain places - their similarities can be represented by one data structure that holds a group of node indices and the shared result for these indices. Thoughts? Cheers, MS
Sign in to reply to this message.
On Jul 5, 2011, at 9:58 AM, mike@apollinemike.com wrote: > > 3) Make the lines_ of a constrained breaker a sparse binary tree (see below) of matrices, not a single matrix, that stores the information above. Each node of the tree would branch off into break/noBreak for a single point in breaks. > Errata - the binary tree nodes would hold either null (no break) or vectors (break), where each vector represented the forces of the previous lines. Or maybe not even this...essentially, it'd be a data structure that holds the forces associated with a lot of different line breaking configurations in a way that eliminates redundant storage.* Cheers, MS * I know nothing about best practices in data management, but I'd be willing to learn if there isn't anyone who is good at this and would be willing to take on this project with me :)
Sign in to reply to this message.
Am Dienstag 05 Juli 2011, 06:10:12 schrieb Carl.D.Sorensen@gmail.com: > I'm wondering if it's possible to avoid code dup by making a > base_stem_engraver of which glissando_stem_engraver and stem_engraver > would be children. > > I probably don't have the right terminology for this (in fact I'm sure I > don't), but I'm thinking of what happens with ligature_engraver and > mensural_ligature_engraver. Hmm, I always thought that engravers should NEVER use inheritance... At least that´s what the comments in the slur-engraver.cc and the phrasing-slur- engraver.cc (which are basically identical except for melisma handling) says... Cheers, Reinhold -- ------------------------------------------------------------------ Reinhold Kainhofer, Vienna University of Technology, Austria email: reinhold@kainhofer.com, http://reinhold.kainhofer.com/ * Financial and Actuarial Mathematics, TU Wien, http://www.fam.tuwien.ac.at/ * Edition Kainhofer Music Publishing, http://www.edition-kainhofer.com/ * LilyPond music typesetting software, http://www.lilypond.org/
Sign in to reply to this message.
On Jul 1, 2011, at 5:50 PM, Han-Wen Nienhuys wrote: > > On a tangent: what is the glissando-index property for? I can't see > it being read anywhere. > > \relative c' { \override Glissando #'style = #(lambda (grob) (if (eq? (ly:grob-property grob 'glissando-index) 1) 'zigzag 'dashed-line)) <c e g>1 \glissando <c' e g> }
Sign in to reply to this message.
On Jul 1, 2011, at 5:50 PM, Han-Wen Nienhuys wrote: > > On a tangent: what is the glissando-index property for? I can't see > it being read anywhere. > > \relative c' { \override Glissando #'style = #(lambda (grob) (if (eq? (ly:grob-property grob 'glissando-index) 1) 'zigzag 'dashed-line)) <c e g>1 \glissando <c' e g> }
Sign in to reply to this message.
I've paired this down to a minimal implementation that only contains: 1) Init file stuff for syntax (this could be made much better...) 2) Modifications to the glissando engraver to ID glissando stems. 3) A function that links them up to glissandi in stem.hh 4) The triggering of this function via a callback in stem-end-position in two places in the code (it'd be in one place save that the beam code doesn't completely behave nicely with stems). I think my university-based research for the next year will be on dynamical systems in typesetting: I am getting results that resemble more and more a Lorenz attractor as I try to navigate all of the internal dependencies that arise when one implements a horizontal spacing algorithm whose constituent members' widths are dependent on the results of said algorithm. Cheers, MS
Sign in to reply to this message.
On 7/17/11 12:22 PM, "mtsolo@gmail.com" <mtsolo@gmail.com> wrote: > I've paired this down to a minimal implementation that only contains: > > 1) Init file stuff for syntax (this could be made much better...) > 2) Modifications to the glissando engraver to ID glissando stems. > 3) A function that links them up to glissandi in stem.hh > 4) The triggering of this function via a callback in stem-end-position > in two places in the code (it'd be in one place save that the beam code > doesn't completely behave nicely with stems). > > I think my university-based research for the next year will be on > dynamical systems in typesetting: I am getting results that resemble > more and more a Lorenz attractor as I try to navigate all of the > internal dependencies that arise when one implements a horizontal > spacing algorithm whose constituent members' widths are dependent on the > results of said algorithm. For those who aren't up on the literature -- Mike is talking about chaos theory ;) Thanks, Carl
Sign in to reply to this message.
Hello, ________________________________________ From: lilypond-devel-bounces+james.lowe=datacore.com@gnu.org [lilypond-devel-bounces+james.lowe=datacore.com@gnu.org] on behalf of mtsolo@gmail.com [mtsolo@gmail.com] Sent: 17 July 2011 19:22 To: pkx166h@gmail.com; graham@percival-music.ca; n.puttock@gmail.com; mike@apollinemike.com; hanwenn@gmail.com; bernardobarros2@gmail.com; c_sorensen@byu.edu; carl.d.sorensen@gmail.com; reinhold@kainhofer.com Cc: reply@codereview.appspotmail.com; lilypond-devel@gnu.org Subject: Re: Adds glissando stems to Lilypond. (issue4661061) I've paired this down to a minimal implementation that only contains: 1) Init file stuff for syntax (this could be made much better...) 2) Modifications to the glissando engraver to ID glissando stems. 3) A function that links them up to glissandi in stem.hh 4) The triggering of this function via a callback in stem-end-position in two places in the code (it'd be in one place save that the beam code doesn't completely behave nicely with stems). I think my university-based research for the next year will be on dynamical systems in typesetting: I am getting results that resemble more and more a Lorenz attractor as I try to navigate all of the internal dependencies that arise when one implements a horizontal spacing algorithm whose constituent members' widths are dependent on the results of said algorithm. ----------- Don't you just get an ellipse? :) James
Sign in to reply to this message.
After a discussion w/ Han-Wen, I've tried to implement this using a new GlissandoStem grob. It is very code-dupey and you'll see that the regtest has one big problem, but other than that it works. I've done a bit of research on why this problem exists. I can already see fishy numbers popping up in Beam::calc_least_squares_positions and its call to Stem::get_stem_info, but I don't know how to avoid/redo these yet. Thoughts would be appreciated it. I know that as a general rule one should avoid after-line-breaking, but I use it here because it resets the clock on a lot of properties and it seems like this is the only place to safely redo them in one fell swoop. Future versions of this patch will break up after-line-breaking into smaller functions so that users can override directions without them being systematically reset - for now, it'd be great if people could give this code a spin (no regtests at this point, as I still need to do some cleanup) and let me know if they have any intuition about why the last example in input/regression/glissando-stem.ly comes out wrong. Cheers, MS
Sign in to reply to this message.
http://codereview.appspot.com/4661061/diff/29001/lily/glissando-engraver.cc File lily/glissando-engraver.cc (right): http://codereview.appspot.com/4661061/diff/29001/lily/glissando-engraver.cc#n... lily/glissando-engraver.cc:83: if (Glissando_stem::has_interface (stem)) acknowledge_glissando_stem ? http://codereview.appspot.com/4661061/diff/29001/lily/include/stem.hh File lily/include/stem.hh (right): http://codereview.appspot.com/4661061/diff/29001/lily/include/stem.hh#newcode75 lily/include/stem.hh:75: class Glissando_stem file glissando-stem.{cc,h} http://codereview.appspot.com/4661061/diff/29001/lily/stem-engraver.cc File lily/stem-engraver.cc (right): http://codereview.appspot.com/4661061/diff/29001/lily/stem-engraver.cc#newcode67 lily/stem-engraver.cc:67: stem_ = make_item (to_boolean (get_property ("glissandoStem")) ? "GlissandoStem" : "Stem", gi.grob ()->self_scm ()); this is borderline acceptable. Put a TODO here to make a separate glissando Note Column engraver if the stem engraver needs to become more elaborate in the future. Probably, you could have a engraver create a GlissandoStem directly from a glissando-note-event. http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc File lily/stem.cc (right): http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1071 lily/stem.cc:1071: Glissando_stem::after_line_breaking (SCM smob) can you try to use property callbacks instead? what does this do? http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1164 lily/stem.cc:1164: extremals[d]->translate_axis (ypos[d] - (0.5 * Staff_symbol_referencer::get_position (extremals[d])), Y_AXIS); what are the extremal heads of a glissando stem, and why do they need to be translated? http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1168 lily/stem.cc:1168: me->set_property ("flag", Stem::calc_flag_proc); init in define-grobs.scm http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1171 lily/stem.cc:1171: beam->set_property ("direction", Beam::calc_direction_proc); why can't the beam figure this out itself? http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1177 lily/stem.cc:1177: elts[i]->set_property ("direction", Script_interface::calc_opposite_direction_proc); why can't the scripts figure this out for themselves? http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1184 lily/stem.cc:1184: } why doesnt the engraver already arrange this ? http://codereview.appspot.com/4661061/diff/29001/scm/define-grob-properties.scm File scm/define-grob-properties.scm (right): http://codereview.appspot.com/4661061/diff/29001/scm/define-grob-properties.s... scm/define-grob-properties.scm:848: at the correct places.") this will use the stem-begin property you introduced in the other patch, right? http://codereview.appspot.com/4661061/diff/29001/scm/define-grobs.scm File scm/define-grobs.scm (right): http://codereview.appspot.com/4661061/diff/29001/scm/define-grobs.scm#newcode953 scm/define-grobs.scm:953: (GlissandoStem ; ugh...massive code dup... this is not really code, but data. You can also drop a lot of the variables (stemlets?) Perhaps it's worth the trouble to put the details into a separate scheme variable.
Sign in to reply to this message.
Most of my comments below are Han-Wen specific, but I do have one request (also echoed below) for anybody. I need to figure out an input syntax for this stuff, which means I'm gonna have to write parser/lexer related code. Ideally, I'd like the syntax to be a4 mikeSolomonIsANinja8 mikeSolomonIsANinja16 a16 Where mikeSolomonIsANinja (or a suitable variant) would be the input syntax for a glissando stem. This would have to insert into the music stream a glissando-note-event (probably within an EventChord), and from that I could create a new engraver and dispense with all the cruft in music-functions-init.ly (meaning no more startGlissandoStem, startGlissandoStem). I just need a brief tutorial on how to do this and I'll be able to do it. I tried to learn about modifying input syntax from the chord-repetition symbol commits (q), but there is a lot of extra stuff about repeating chords in there and I'm having trouble figuring out what parts I'd need to follow. Cheers, MS http://codereview.appspot.com/4661061/diff/29001/lily/glissando-engraver.cc File lily/glissando-engraver.cc (right): http://codereview.appspot.com/4661061/diff/29001/lily/glissando-engraver.cc#n... lily/glissando-engraver.cc:83: if (Glissando_stem::has_interface (stem)) On 2011/07/19 12:33:45, hanwenn wrote: > acknowledge_glissando_stem ? So long as we can get the stems from the note columns, it seems that it'd be cleaner to get the glissando stems this way. http://codereview.appspot.com/4661061/diff/29001/lily/include/stem.hh File lily/include/stem.hh (right): http://codereview.appspot.com/4661061/diff/29001/lily/include/stem.hh#newcode75 lily/include/stem.hh:75: class Glissando_stem On 2011/07/19 12:33:45, hanwenn wrote: > file glissando-stem.{cc,h} Done. http://codereview.appspot.com/4661061/diff/29001/lily/stem-engraver.cc File lily/stem-engraver.cc (right): http://codereview.appspot.com/4661061/diff/29001/lily/stem-engraver.cc#newcode67 lily/stem-engraver.cc:67: stem_ = make_item (to_boolean (get_property ("glissandoStem")) ? "GlissandoStem" : "Stem", gi.grob ()->self_scm ()); On 2011/07/19 12:33:45, hanwenn wrote: > this is borderline acceptable. Put a TODO here to make a separate glissando Note > Column engraver if the stem engraver needs to become more elaborate in the > future. > > Probably, you could have a engraver create a GlissandoStem directly from a > glissando-note-event. Doable - in general, I'm gonna need to figure out a good input syntax for this sorta thing. Question: how would one modify the parser/lexer/whatever to create a new symbol for glissando stems? It'd work just like notes (a, b, c...), rests (r), or the repeat chord thingee (q). Once I figured out how to do this and how to get a glissando-note-event into the music stream, I could make this happen and make the input syntax a lot cleaner. http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc File lily/stem.cc (right): http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1071 lily/stem.cc:1071: Glissando_stem::after_line_breaking (SCM smob) On 2011/07/19 12:33:45, hanwenn wrote: > can you try to use property callbacks instead? > > what does this do? It repositions the note-heads to their appropriate place so that the glissando stem links up with them. But why reposition noteheads, you ask, when they have no positive extent? Why not dispense with this notehead business and just roll this into stem-begin-position? Because I can imagine a case where people want noteheads printed (i.e. crosses to signify stopping a string momentarily) and want the glissando stem to pass through the notehead The bulk of this can be farmed out to a property callback for something like "position-noteheads" - I'd be calling that callback, though, from after_line_breaking. http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1164 lily/stem.cc:1164: extremals[d]->translate_axis (ypos[d] - (0.5 * Staff_symbol_referencer::get_position (extremals[d])), Y_AXIS); On 2011/07/19 12:33:45, hanwenn wrote: > what are the extremal heads of a glissando stem, and why do they need to be > translated? See the above comment. Ideally, there will be as many noteheads on a glissando stem as there are glissandi, and each one will be positioned right over the glissando. In fact, I should work on this next... http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1168 lily/stem.cc:1168: me->set_property ("flag", Stem::calc_flag_proc); On 2011/07/19 12:33:45, hanwenn wrote: > init in define-grobs.scm The problem is that they take dummy-inits in define-grobs.scm that allow for the spacing-spanner to do its thing. This resets these properties so that the correct values can be calculated after the note-heads are moved above. http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1171 lily/stem.cc:1171: beam->set_property ("direction", Beam::calc_direction_proc); On 2011/07/19 12:33:45, hanwenn wrote: > why can't the beam figure this out itself? It can, but like the properties above, it needs to be reset from the incorrect cached value used before line breaking. http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1177 lily/stem.cc:1177: elts[i]->set_property ("direction", Script_interface::calc_opposite_direction_proc); On 2011/07/19 12:33:45, hanwenn wrote: > why can't the scripts figure this out for themselves? It can, but like the properties above, it needs to be reset. http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1184 lily/stem.cc:1184: } On 2011/07/19 12:33:45, hanwenn wrote: > why doesnt the engraver already arrange this ? It does, but like the properties above, these properties need to be reset. http://codereview.appspot.com/4661061/diff/29001/scm/define-grob-properties.scm File scm/define-grob-properties.scm (right): http://codereview.appspot.com/4661061/diff/29001/scm/define-grob-properties.s... scm/define-grob-properties.scm:848: at the correct places.") On 2011/07/19 12:33:45, hanwenn wrote: > this will use the stem-begin property you introduced in the other patch, right? Yes'r. http://codereview.appspot.com/4661061/diff/29001/scm/define-grobs.scm File scm/define-grobs.scm (right): http://codereview.appspot.com/4661061/diff/29001/scm/define-grobs.scm#newcode953 scm/define-grobs.scm:953: (GlissandoStem ; ugh...massive code dup... On 2011/07/19 12:33:45, hanwenn wrote: > this is not really code, but data. You can also drop a lot of the variables > (stemlets?) Perhaps it's worth the trouble to put the details into a separate > scheme variable. Agreed. After I get this to a stable point, I am going to make a series of comprehensive regtests and attempt to pick these variables off one-by-one to see which ones are actually necessary.
Sign in to reply to this message.
hi there, as you see I am really strict here; I hope you understand it is my duty as maintainer to push back on anything invasive, so we can keep lilypond as simple as possible; nothing personal. http://codereview.appspot.com/4661061/diff/29001/lily/glissando-engraver.cc File lily/glissando-engraver.cc (right): http://codereview.appspot.com/4661061/diff/29001/lily/glissando-engraver.cc#n... lily/glissando-engraver.cc:83: if (Glissando_stem::has_interface (stem)) On 2011/07/19 13:42:06, MikeSol wrote: > On 2011/07/19 12:33:45, hanwenn wrote: > > acknowledge_glissando_stem ? > > So long as we can get the stems from the note columns, it seems that it'd be > cleaner to get the glissando stems this way. I don't think this is cleaner. Acknowledge_glissando_stem is a much more direct way of saying what you want. http://codereview.appspot.com/4661061/diff/29001/lily/stem-engraver.cc File lily/stem-engraver.cc (right): http://codereview.appspot.com/4661061/diff/29001/lily/stem-engraver.cc#newcode67 lily/stem-engraver.cc:67: stem_ = make_item (to_boolean (get_property ("glissandoStem")) ? "GlissandoStem" : "Stem", gi.grob ()->self_scm ()); On 2011/07/19 13:42:06, MikeSol wrote: > On 2011/07/19 12:33:45, hanwenn wrote: > > this is borderline acceptable. Put a TODO here to make a separate glissando > Note > > Column engraver if the stem engraver needs to become more elaborate in the > > future. > > > > Probably, you could have a engraver create a GlissandoStem directly from a > > glissando-note-event. > > Doable - in general, I'm gonna need to figure out a good input syntax for this > sorta thing. > > Question: how would one modify the parser/lexer/whatever to create a new symbol > for glissando stems? It'd work just like notes (a, b, c...), rests (r), or the Don't create syntax; it's hard and not worth the payoff. Use a music function instead that substitutes NoteEvents with GlissandoStemEvents \asGlissandoStems { c4 c16 c8. } http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc File lily/stem.cc (right): http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1071 lily/stem.cc:1071: Glissando_stem::after_line_breaking (SCM smob) On 2011/07/19 13:42:06, MikeSol wrote: > On 2011/07/19 12:33:45, hanwenn wrote: > > can you try to use property callbacks instead? > > > > what does this do? > > It repositions the note-heads to their appropriate place so that the glissando > stem links up with them. > > But why reposition noteheads, you ask, when they have no positive extent? Why > not dispense with this notehead business and just roll this into > stem-begin-position? > > Because I can imagine a case where people want noteheads printed (i.e. crosses can you imagine or do you really need it now? If it's a future extension, drop it for now and worry about it when someone asks for it. Since the cross "notehead" has a continuous Y position (depending on the glissando slope and whatnot), it is not a normal notehead. Much easier to have a GlissandoHead, and have that adjust its position by reading stem-begin-position of the glissando stem. > to signify stopping a string momentarily) and want the glissando stem to pass > through the notehead > > The bulk of this can be farmed out to a property callback for something like > "position-noteheads" - I'd be calling that callback, though, from > after_line_breaking. http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1168 lily/stem.cc:1168: me->set_property ("flag", Stem::calc_flag_proc); On 2011/07/19 13:42:06, MikeSol wrote: > On 2011/07/19 12:33:45, hanwenn wrote: > > init in define-grobs.scm > > The problem is that they take dummy-inits in define-grobs.scm that allow for the > spacing-spanner to do its thing. This resets these properties so that the > correct values can be calculated after the note-heads are moved above. huh? spacing spanner should not even see these stems. You should remove stem-interface from GlissandoStem. Alternatively, you could add stem-spacing-interface to distinguish between a stem that affects spacing and one that doesnt. However, since the glissandostem is such an odd beast, I think it will be easier to keep it completely separate. http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1184 lily/stem.cc:1184: } On 2011/07/19 13:42:06, MikeSol wrote: > On 2011/07/19 12:33:45, hanwenn wrote: > > why doesnt the engraver already arrange this ? > > It does, but like the properties above, these properties need to be reset. like above, figure a way to not have the problem in the first place, rather than fixing it up afterwards. http://codereview.appspot.com/4661061/diff/29001/lily/stem.cc#newcode1248 lily/stem.cc:1248: "Like stems, but for glissandi", start out with an empty interface, and add properties until your regtest compiles cleanly.
Sign in to reply to this message.
|