MPEInstrument::getLastNotePlayedPtr (int midiChannel) does not return the last note played on a midi channel

const MPENote* MPEInstrument::getLastNotePlayedPtr (int midiChannel) const noexcept
{
const ScopedLock sl (lock);

for (auto i = notes.size(); --i >= 0;)
{
    auto& note = notes.getReference (i);

    if (note.midiChannel == midiChannel
         && (note.keyState == MPENote::keyDown || note.keyState == MPENote::keyDownAndSustained))
        return &note;
}

return nullptr;

}

This implementation should be looking at MPENote::noteId to make sure that the note it’s returning is actually the last note played on a given channel … but obs it does not.

This will usually work anyway, because having more than one note played per channel is unusual in MPE.

Since new notes are add()-ed at the end of MPEInstrument::notes, this algorithm will (usually) return the first note played on a channel, not the last, if there is more than one.

Could you elaborate more on the issue you are seeing? The function you posted loops through the notes in reverse order so it should indeed return the last note added to notes with the matching MIDI channel and a key down state.

Shouldn’t the loop start at size () - 1?

I don’t think so because it does a pre-decrement in the condition check which runs before the body of the loop. For example Imagine size() is 2

  • i is assigned the value of 2
  • --i >= 0 becomes 1 >= 0 which returns true
  • The loop runs with i set to 1
  • --i >= 0 becomes 0 >= 0 which returns true
  • The loop runs with i set to 0
  • --i >= 0 becomes -1 >= 0 which returns false
  • Exit the loop

My bad, this function is working fine.

1 Like