fix #293733: If note is tied to preceding grace note of equal pitch, only the grace note is played back
Why this is happening In collectNote() in rendermidi.cpp, grace notes are currently not treated as notes that could potentially have forward ties; in fact, it is assumed that they will not. When a note is encountered that ties back to a previous note, it is assumed that the length of the note has already been added to the previous note, when in fact this is not the case if the previous note is a grace note. Why this commit fixes the issue The code for computing the entire length of the tie chain is now executed whether the current note is a grace note or not.
This commit is contained in:
parent
3d4488323c
commit
e98b0edd1d
1 changed files with 23 additions and 27 deletions
|
@ -253,35 +253,31 @@ static void collectNote(EventMap* events, int channel, const Note* note, int vel
|
|||
if (chord->isGrace()) {
|
||||
Q_ASSERT( !graceNotesMerged(chord)); // this function should not be called on a grace note if grace notes are merged
|
||||
chord = toChord(chord->parent());
|
||||
ticks = chord->actualTicks().ticks(); // ticks of the parent note
|
||||
tieLen = 0;
|
||||
}
|
||||
else {
|
||||
ticks = chord->actualTicks().ticks(); // ticks of the actual note
|
||||
// calculate additional length due to ties forward
|
||||
// taking NoteEvent length adjustments into account
|
||||
// but stopping at any note with multiple NoteEvents
|
||||
// and processing those notes recursively
|
||||
if (note->tieFor()) {
|
||||
Note* n = note->tieFor()->endNote();
|
||||
while (n) {
|
||||
NoteEventList nel = n->playEvents();
|
||||
if (nel.size() == 1) {
|
||||
// add value of this note to main note
|
||||
// if we wish to suppress first note of ornament,
|
||||
// then do this regardless of number of NoteEvents
|
||||
tieLen += (n->chord()->actualTicks().ticks() * (nel[0].len())) / 1000;
|
||||
}
|
||||
else {
|
||||
// recurse
|
||||
collectNote(events, channel, n, velo, tickOffset, staffIdx);
|
||||
break;
|
||||
}
|
||||
if (n->tieFor() && n != n->tieFor()->endNote())
|
||||
n = n->tieFor()->endNote();
|
||||
else
|
||||
break;
|
||||
ticks = chord->actualTicks().ticks();
|
||||
// calculate additional length due to ties forward
|
||||
// taking NoteEvent length adjustments into account
|
||||
// but stopping at any note with multiple NoteEvents
|
||||
// and processing those notes recursively
|
||||
if (note->tieFor()) {
|
||||
Note* n = note->tieFor()->endNote();
|
||||
while (n) {
|
||||
NoteEventList nel = n->playEvents();
|
||||
if (nel.size() == 1) {
|
||||
// add value of this note to main note
|
||||
// if we wish to suppress first note of ornament,
|
||||
// then do this regardless of number of NoteEvents
|
||||
tieLen += (n->chord()->actualTicks().ticks() * (nel[0].len())) / 1000;
|
||||
}
|
||||
else {
|
||||
// recurse
|
||||
collectNote(events, channel, n, velo, tickOffset, staffIdx);
|
||||
break;
|
||||
}
|
||||
if (n->tieFor() && n != n->tieFor()->endNote())
|
||||
n = n->tieFor()->endNote();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue