Shevek <s...@saultobin.com> writes: > First off, thanks to all the people who worked on 2.16! I'm super excited > about it, and I'm already noticing drastically reduced compile times for my > large projects, compared to 2.14. > > I'm looking at updating my snippet library, and the first issue I've run > into is that http://lsr.dsi.unimi.it/LSR/Snippet?id=604 stopped working in > 2.16. It's pretty simple to fix using event-chord-wrap!, but I was wondering > what a real solution should look like. I'm assuming similar situations will > crop up with other snippets, so I suppose this is just an instance of a more > general question. I'm hoping that maybe updating some snippets will be a > good way for me to learn more Scheme.
This snippet is fairly simple. The first thing to note is that the usual problem with snippets failing as a consequence of implementing issue 2240 <URL:http://code.google.com/p/lilypond/issues/detail?id=2240> is the assumption that even single notes appear as an EventChord. The blackbox giveaway is pretty much when the snippet stopped working in version 2.15.28 and worked in 2.15.27: there are not all that many other highly significant changes. This change is likely the largest contender for LilyPond programs to stop working when moving from 2.14 to 2.16. If we are looking at the LilyPond code itself, the usual giveaway is the use of (ly:music-property ... 'elements) without checking the type of ... beforehand, or checks for EventChord or event-chord without any check for NoteEvent, RestEvent, or rhythmic-event. Now instead of trying a piece-by-piece fix, in this case it is worthwhile to rethink the whole approach and see whether we can fit its operation into #{ #}. Why would we want to do that? Because the internals of the tremolo repeat are non-trivial to calculate, and indeed, there have been several fixes to get the respective code in the LilyPond codebase for entering and displaying tremolo repeats correctly. Taking a look at the user interface, we see %\tremolos <base duration> <music> %Makes each note in music a tremolo repeat. %dur is 8, 16, 32, etc. tremolos = #(define-music-function (parser location dur mus) (integer? ly:music?) (music-map (lambda (x) (tremoloize dur x)) mus)) It is immediately apparent that entering a duration as an integer rather than, well, a duration is less than optimal. music-map works recursively bottom-up. In this case, we don't really want to rerecurse, so using the new function map-some-music seems more appropriate, in particular since it avoids a bit of unnecessary copying and we stop recursing when reaching a target. After all that introduction, let's get to business: tremolos = #(define-music-function (parser location dur mus) (ly:duration? ly:music?) (map-some-music (lambda (m) (and (or (music-is-of-type? m 'event-chord) (music-is-of-type? m 'note-event)) #{ \repeat tremolo $(ly:moment-main (ly:moment-div (ly:music-length m) (ly:duration-length dur))) $(map-some-music (lambda (elt) (and (ly:music-property elt 'duration #f) (begin (set! (ly:music-property elt 'duration) dur) elt))) m) #})) mus)) \relative c' { \tremolos 16 { c4 d2 e4 | f1 | g8 f e d c2 | } } What does this mean? We recurse top-down through the whole music, stopping at event-chord and note-event nodes (there are likely some other rhythmic-event types which would also be susceptible to tremoli, but things like rest-event aren't really, so we play this conservatively, only adding more specific types as needed). The tremolo count is calculated by dividing the respective lengths (the ly:moment-* arithmetic is a bit weird, coming from a time where Guile did not have rational numbers). The repeated music is arrived at by replacing every duration inside of the repeated music with the given duration. We will get a weird error message when the repeat count is not an integer: this could be caught and handled more gracefully, but making a nicer error message is really all one can do in that situation. This should work fine with chords and also when dotted durations come into play. It turns out that the unfoldTremolo stuff in the snippet does not really need any changes. -- David Kastrup _______________________________________________ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user