Skip to content

Commit

Permalink
Merge dc10b0e into 5cbc1c9
Browse files Browse the repository at this point in the history
  • Loading branch information
lasconic committed Mar 23, 2018
2 parents 5cbc1c9 + dc10b0e commit 1dd2293
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 15 deletions.
9 changes: 9 additions & 0 deletions mscore/exportmidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,18 @@ bool ExportMidi::write(const QString& name, bool midiExpandRepeats)

for (auto i = events.begin(); i != events.end(); ++i) {
const NPlayEvent& event = i->second;

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;
}

char eventPort = cs->midiPort(event.channel());
char eventChannel = cs->midiChannel(event.channel());
if (port != eventPort || channel != eventChannel)
Expand Down
10 changes: 8 additions & 2 deletions mscore/seq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,6 @@ void Seq::playEvent(const NPlayEvent& event, unsigned framePos)
if (type == ME_NOTEON) {
bool mute;
const Note* note = event.note();

if (note) {
Instrument* instr = note->staff()->part()->instrument(note->chord()->tick());
const Channel* a = instr->channel(note->subchannel());
Expand All @@ -520,8 +519,15 @@ void Seq::playEvent(const NPlayEvent& event, unsigned framePos)
else
mute = false;

if (!mute)
if (!mute) {
if (event.discard()) { // ignore noteoff but restrike noteon
if (event.velo() > 0)
putEvent(NPlayEvent(ME_NOTEON, event.channel(), event.pitch(), 0) ,framePos);
else
return;
}
putEvent(event, framePos);
}
}
else if (type == ME_CONTROLLER || type == ME_PITCHBEND)
putEvent(event, framePos);
Expand Down
1 change: 1 addition & 0 deletions mtest/libmscore/midi/tst_midi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ void TestMidi::events()
QTextStream out(&filehandler);
multimap<int, NPlayEvent> ::iterator iter;
for (auto iter = events.begin(); iter!= events.end(); ++iter){
if (iter->second.discard()) continue;
out << qSetFieldWidth(5) << "Tick = ";
out << qSetFieldWidth(5) << iter->first;
out << qSetFieldWidth(5) << " Type = ";
Expand Down
35 changes: 22 additions & 13 deletions synthesizer/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,38 +377,47 @@ void EventList::insert(const Event& e)

void EventMap::fixupMIDI()
{
unsigned short nowPlaying[_highestChannel + 1][128 /* notes */];
int originatingTrack[_highestChannel + 1][128 /* notes */];
auto it = begin();
/* track info for each of the 128 possible MIDI notes */
struct channelInfo {
/* which event the first ME_NOTEON came from */
NPlayEvent *event[128];
/* how often is the note on right now? */
unsigned short nowPlaying[128];
};

memset(nowPlaying, 0, (_highestChannel + 1) * 128 * sizeof(unsigned short));
/* track info for each channel (on the heap, 0-initialised) */
struct channelInfo *info = (struct channelInfo *)calloc(_highestChannel + 1, sizeof(struct channelInfo));

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 = nowPlaying[it->second.channel()][it->second.pitch()];
unsigned short np = info[it->second.channel()].nowPlaying[it->second.pitch()];
if (it->second.velo() == 0) {
/* already off or still playing? */
if (np == 0 || --np > 0)
discard = true;
else
else {
/* hoist NOTEOFF to same track as NOTEON */
it->second.setOriginatingStaff(originatingTrack[it->second.channel()][it->second.pitch()]);
it->second.setOriginatingStaff(info[it->second.channel()].event[it->second.pitch()]->getOriginatingStaff());
}
}
else if (++np > 1)
discard = true; /* already playing */
discard = true;
else
originatingTrack[it->second.channel()][it->second.pitch()] = it->second.getOriginatingStaff();
nowPlaying[it->second.channel()][it->second.pitch()] = np;
info[it->second.channel()].event[it->second.pitch()] = &(it->second);
info[it->second.channel()].nowPlaying[it->second.pitch()] = np;
}

if (discard)
it = erase(it);
else
++it;
it->second.setDiscard(true);

++it;
}

free((void *)info);
}

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

public:
NPlayEvent() : PlayEvent() {}
NPlayEvent(uchar t, uchar c, uchar a, uchar b)
: PlayEvent(t, c, a, b) {}
NPlayEvent(const MidiCoreEvent& e) : PlayEvent(e) {}
NPlayEvent(BeatType beatType);

const Note* note() const { return _note; }
void setNote(const Note* v) { _note = v; }

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

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

0 comments on commit 1dd2293

Please sign in to comment.