Skip to content

Commit

Permalink
fix #77376: don't render those tied notes which are handled on render…
Browse files Browse the repository at this point in the history
…ing previous notes.

This helps to fix playback of tied trills for which extra note play
events were created.
  • Loading branch information
dmitrio95 committed Nov 15, 2018
1 parent ef48b60 commit cf73f52
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 8 deletions.
6 changes: 5 additions & 1 deletion libmscore/noteevent.h
Expand Up @@ -28,7 +28,9 @@ class NoteEvent {
int _len; // 1/1000 of nominal note len

public:
NoteEvent() : _pitch(0), _ontime(0), _len(1000) {}
constexpr static int NOTE_LENGTH = 1000;

NoteEvent() : _pitch(0), _ontime(0), _len(NOTE_LENGTH) {}
NoteEvent(int a, int b, int c) : _pitch(a), _ontime(b), _len(c) {}

void read(XmlReader&);
Expand All @@ -51,6 +53,8 @@ class NoteEvent {
class NoteEventList : public QList<NoteEvent> {
public:
NoteEventList();

int offtime() { return empty() ? 0 : std::max_element(cbegin(), cend(), [](const NoteEvent& n1, const NoteEvent& n2) { return n1.offtime() < n2.offtime(); })->offtime(); }
};


Expand Down
35 changes: 31 additions & 4 deletions libmscore/rendermidi.cpp
Expand Up @@ -1564,6 +1564,25 @@ void renderChordArticulation(Chord* chord, QList<NoteEventList> & ell, int & gat
}
}

//---------------------------------------------------------
// shouldRenderNote
//---------------------------------------------------------

static bool shouldRenderNote(Note* n)
{
int dist = 0;
while (n->tieBack()) {
n = n->tieBack()->startNote();
++dist;
if (n && n->playEvents().offtime() > (dist * NoteEvent::NOTE_LENGTH)) {
// The previous tied note probably has events for this note too.
// That is, we don't need to render this note separately.
return false;
}
}
return true;
}

//---------------------------------------------------------
// renderChord
// ontime and trailtime in 1/1000 of duration
Expand All @@ -1581,21 +1600,29 @@ static QList<NoteEventList> renderChord(Chord* chord, int gateTime, int ontime,
for (size_t i = 0; i < notes; ++i)
ell.append(NoteEventList());

bool arpeggio = false;
if (chord->tremolo()) {
renderTremolo(chord, ell);
}
else if (chord->arpeggio() && chord->arpeggio()->playArpeggio()) {
renderArpeggio(chord, ell);
return ell; // dont apply gateTime to arpeggio events
arpeggio = true;
}
else
renderChordArticulation(chord, ell, gateTime);

//
// apply gateTime
//
// Check each note and apply gateTime
for (int i = 0; i < int(notes); ++i) {
NoteEventList* el = &ell[i];
if (!shouldRenderNote(chord->notes()[i])) {
el->clear();
continue;
}
if (arpeggio)
continue; // don't add extra events and apply gateTime to arpeggio

// If we are here then we still need to render the note.
// Render its body if necessary and apply gateTime.
if (el->size() == 0 && chord->tremoloChordType() != TremoloChordType::TremoloSecondNote) {
el->append(NoteEvent(0, ontime, 1000 - ontime - trailtime));
}
Expand Down
6 changes: 3 additions & 3 deletions mtest/libmscore/midi/testTieTrill-ref.txt
Expand Up @@ -65,6 +65,7 @@ Tick = 1795 Type = 144 Pitch = 72 Velocity = 0 Channel =
Tick = 1800 Type = 144 Pitch = 74 Velocity = 80 Channel = 0
Tick = 1855 Type = 144 Pitch = 74 Velocity = 0 Channel = 0
Tick = 1860 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 1915 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 1920 Type = 144 Pitch = 69 Velocity = 80 Channel = 0
Tick = 1920 Type = 3 Pitch = 0 Velocity = 127 Channel = 0
Tick = 1975 Type = 144 Pitch = 69 Velocity = 0 Channel = 0
Expand Down Expand Up @@ -113,9 +114,9 @@ Tick = 3175 Type = 144 Pitch = 69 Velocity = 0 Channel =
Tick = 3180 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 3235 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 3240 Type = 144 Pitch = 69 Velocity = 80 Channel = 0
Tick = 3283 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 3295 Type = 144 Pitch = 69 Velocity = 0 Channel = 0
Tick = 3300 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 3355 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 3360 Type = 4 Pitch = 0 Velocity = 80 Channel = 0
Tick = 3840 Type = 144 Pitch = 60 Velocity = 80 Channel = 0
Tick = 3840 Type = 3 Pitch = 0 Velocity = 127 Channel = 0
Expand All @@ -125,8 +126,7 @@ Tick = 3955 Type = 144 Pitch = 62 Velocity = 0 Channel =
Tick = 3960 Type = 144 Pitch = 64 Velocity = 80 Channel = 0
Tick = 4015 Type = 144 Pitch = 64 Velocity = 0 Channel = 0
Tick = 4020 Type = 144 Pitch = 62 Velocity = 80 Channel = 0
Tick = 4267 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 4320 Type = 4 Pitch = 0 Velocity = 80 Channel = 0
Tick = 4800 Type = 4 Pitch = 0 Velocity = 127 Channel = 0
Tick = 5215 Type = 144 Pitch = 62 Velocity = 0 Channel = 0
Tick = 5280 Type = 4 Pitch = 0 Velocity = 80 Channel = 0
Tick = 6127 Type = 144 Pitch = 62 Velocity = 0 Channel = 0

0 comments on commit cf73f52

Please sign in to comment.