On Sat, Jan 12, 2013 at 12:52 PM, Adam Spiers <lilypond-de...@adamspiers.org> wrote: > [thread moved from lilypond-user] > > On Tue, Jan 8, 2013 at 5:59 PM, Adam Spiers > <lilypond-u...@adamspiers.org> wrote: >> On Tue, Jan 8, 2013 at 5:41 PM, Eluze <elu...@gmail.com> wrote: >>> I've added an issue to the tracker: >>> https://code.google.com/p/lilypond/issues/detail?id=3091&thanks=3091&ts=1357666391 >> >> Thanks! >> >>> I'm not aware of a workaround - I could imagine using 2 voices, one without >>> the grace the other with just the grace and a muted note - but this seems >>> pretty awkward! >> >> Is it perhaps the fault of the >> >> if (now_mom ().grace_part_) >> >> section in Note_performer::process_music() in lily/note-performer.cc? >> Does it somehow reintroduce the previous note when shortening it to >> make room for the grace note, even though the previous note was tied >> to the one before? > > Is there a performer tutorial similar to the engraver tutorial? > > http://lilypond.org/doc/v2.16/Documentation/contributor/engraver-tutorial > > I've started trying to fix the above bug, but my knowledge of > LilyPond's C++ performer code (let alone any other code) is poor, and > getting to grips with the various data structures is slow work. I'm > running it through gdb which helps, but any other pointers would be > really useful. Thanks!
I have finally pinned this down! And I'm close to a fix. The culprit is in Midi_walker::process(): if (note->audio_->length_mom_.to_bool ()) do_start_note (note); This to_bool () check is too simplistic. Here is the explanation ... If you have a tie followed by a grace: a1~a4 \grace b8 then Tie_performer::acknowledge_audio_element() will invoke Audio_note::tie_to() which will lengthen the duration of the Audio_note corresponding to the a1 by 1/4, and then set the length of the Audio_note corresponding corresponding to the a4 to zero. Later, when Note_performer::process_music() encounters the b8 grace note, it will shorten the grace_part_ of the now-zero-length Audio_note for a4 by 1/8, reducing it to -1/8. If you were to invoke to_string() on the Audio_note at this point, you'd get "0G-1/8". Now we see why the to_bool() check above is too simplistic. It's implemented as: bool Moment::to_bool () const { return main_part_ || grace_part_; } but because the grace_part_ is no longer zero, do_start_note will be invoked for the tied note! I believe a reasonable approach would be to use a different check: if (note->audio_->length_mom_.main_part_ || note->audio_->length_mom_.grace_part_.sign () == 1) do_start_note (note); It may even warrant a new Audio_note::is_positive_duration() method which could be used here. Thoughts? However, this suggested workaround is not sufficient by itself - there is a related issue with the ordering of NoteOff events which I'm working on now. _______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel