Skip to content

Commit

Permalink
Merge pull request #3588 from mirabilos/midi-270878
Browse files Browse the repository at this point in the history
fix #270878: improve restriking
  • Loading branch information
lasconic committed Apr 3, 2018
2 parents 749bd06 + d3bd3a2 commit f86d007
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 19 deletions.
15 changes: 8 additions & 7 deletions mscore/exportmidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,16 +289,17 @@ bool ExportMidi::write(const QString& name, bool midiExpandRepeats)
for (auto i = events.begin(); i != events.end(); ++i) {
const NPlayEvent& event = i->second;

if (event.discard() == staffIdx + 1 && event.velo() > 0)
// turn note off so we can restrike it in another track
track.insert(pauseMap.addPauseTicks(i->first), MidiEvent(ME_NOTEON, channel,
event.pitch(), 0));

if (event.getOriginatingStaff() != staffIdx)
continue;

if (event.discard()) { // ignore noteoff but restrike noteon
if (event.velo() > 0)
track.insert(pauseMap.addPauseTicks(i->first), MidiEvent(ME_NOTEON, channel,
event.pitch(), 0));
else
continue;
}
if (event.discard() && event.velo() == 0)
// ignore noteoff but restrike noteon
continue;

char eventPort = cs->midiPort(event.channel());
char eventChannel = cs->midiChannel(event.channel());
Expand Down
15 changes: 6 additions & 9 deletions synthesizer/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,30 +390,27 @@ void EventMap::fixupMIDI()

auto it = begin();
while (it != end()) {
bool discard = false;

/* ME_NOTEOFF is never emitted, no need to check for it */
if (it->second.type() == ME_NOTEON) {
unsigned short np = info[it->second.channel()].nowPlaying[it->second.pitch()];
if (it->second.velo() == 0) {
/* already off (should not happen) or still playing? */
if (np == 0 || --np > 0)
discard = true;
it->second.setDiscard(1);
else {
/* hoist NOTEOFF to same track as NOTEON */
it->second.setOriginatingStaff(info[it->second.channel()].event[it->second.pitch()]->getOriginatingStaff());
}
}
else if (++np > 1)
discard = true;
else
else {
if (++np > 1)
/* restrike, possibly on different track */
it->second.setDiscard(info[it->second.channel()].event[it->second.pitch()]->getOriginatingStaff() + 1);
info[it->second.channel()].event[it->second.pitch()] = &(it->second);
}
info[it->second.channel()].nowPlaying[it->second.pitch()] = np;
}

if (discard)
it->second.setDiscard(true);

++it;
}

Expand Down
6 changes: 3 additions & 3 deletions synthesizer/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class PlayEvent : public MidiCoreEvent {
class NPlayEvent : public PlayEvent {
const Note* _note = 0;
int _origin = -1;
bool _discard = false;
int _discard = 0;

public:
NPlayEvent() : PlayEvent() {}
Expand All @@ -250,8 +250,8 @@ class NPlayEvent : public PlayEvent {

int getOriginatingStaff() const { return _origin; }
void setOriginatingStaff(int i) { _origin = i; }
void setDiscard(bool d) {_discard = d; }
bool discard() const { return _discard; }
void setDiscard(int d) { _discard = d; }
int discard() const { return _discard; }
};

//---------------------------------------------------------
Expand Down

0 comments on commit f86d007

Please sign in to comment.