MIDI input breaks for rest of session

• created 4 months ago
Version
2.1
Priority
normal
Status
active
Component
Code
Category
bug report
Project

Steps to reproduce bug:

  1. Follow handbook instructions for MIDI keyboard input
  2. (optional) Play single note(s) on MIDI keyboard
  3. Play multiple notes on MIDI keyboard at the same time
  4. Release notes at the same time

Expected behavior:

MIDI input should continue to work, even if multiple keys are played simultaneously and released simultaneously.

Actual behavior:

One can, in fact play multiple keys at a time, but one must be careful to release them one at a time. If one releases multiple notes at the same time, the notes that were already input on the attack are input again on the release. Afterwards, MIDI input becomes restricted to the current note location and any subsequent notes played will simply stack on top of the existing chord. If a different location is then selected by mouse or arrow keys, MIDI input ceases to work at all. This state persists until the session is ended and MuseScore is relaunched.

Version number:

  • 2.1 revision 871c8ce
  • 3.0.0, Revision 7bb6f4e

Operating System:

Mac OS X 10.11.3.

Other Equipment:

  • MIDI keyboard: Roland RS-5
  • MIDI connection: AGPtek MIDI-to-USB cable.

Comments

Which MIDI input method are you using? Step time?

In MIDI, there is no such thing as doing anything simultaneously; everything is one at a time just a question of how quickly one event follows another. So even when you think you are releasing simultaneously, what MuseScore receives are one at a time release messages, just quickly all right in a row. How quickly do you find you need to release to trigger this?

My guess is it will turn out your keyboard is not correctly sending note-off messages for all the notes, and that is why MuseScore thinks you haven't moved on. But it's also possible that in some specific case MuseScore is dropping one fo the note off messages.

MIDI input method: Step Time.

How quickly do I need to release to trigger this problem... I really don't know how to measure that.

I doubt it's my keyboard, as I've never had any problems with it before. But this is a new (and rather inexpensive) MIDI-to-USB connector, so I would buy that that's the source of the problem.

You could try releasing the keys say, one second apart, and see if that works or not. If so, try releasing somewhat more quickly. If not, try releasing a little more slowly. Basically, trying to understand whether this problem only kicks in when releasing keys super fast or if it happens even when releasing a second or more apart.

Just because the keyboard works in other respects doesn't mean the keyboard isn't doing the wrong thing here. In other situations, it might not matter so much if all the note off messages get sent or not.

I guess I didn't make that clear in my original post. If I release them a second apart, there is no problem whatsoever. So, yes, the problem only kicks in when releasing them super fast.

Additional details:

The attacks can be any amount of time apart or at any velocity, and that makes no difference. The order the notes are released in doesn't appear to have an impact, if they are released far enough apart.

But, if more than one note is released within a second of each other, that's when the problem occurs. Taking rmattes' suggestion, I ran MIDIMonitor. The offending results are here:

23:42:07.662 From Port 1 Note On 1 C3 50
23:42:07.667 From Port 1 Note On 1 D3 62
23:42:07.720 From Port 1 Active Sense
23:42:07.976 From Port 1 Active Sense
23:42:07.993 From Port 1 Note Off 1 D3 75
23:42:08.008 From Port 1 Note On 1 C3 64

The second Note Off becomes a Note On. So, I concede that it may be a hardware problem after all (hopefully in the adapter rather than the keyboard itself).

However, In Step Time, the duration of the note is not determined by the MIDI keyboard. So, is there a reason MuseScore is even listening for Note Off events in this context? Could a future release ignore them while in Step Time (or at least have an option to do so)?

In reply to by Simmon Keith Barney

Thanks for the investigation!

My understanding is we trigger the completion of entry on note off. The reason is to facilitate the building of chords - to allow several notes played "at once" (which really note on events in quick succession before any note off event) to be understood as part of the same chord.

I believe this issue is the cause of https://musescore.org/en/node/196816#comment-808577, so it's clearly happening with multiple users, including me. Although the root cause is external (lost midi event), the result is an internal state error within Musescore which is not easily recovered, and gives the impression that Musescore has crashed.

Musescore counts the number of "active" notes by incrementing a counter for each "note-on" event, and decrementing for each "note-off" event. It does this all the time, regardless of "note entry" mode. If a "note-off" event is lost - for whatever reason - the counter value is wrong, and midi input is useless from this point on.

I think this could be fixed by resetting the counter to zero when entering "note entry" mode. As far as I can see, the counter value is only useful in "note entry" mode, so zeroing here would be a good defensive approach. Alternatively, the counter could be held at zero while not in "note entry" mode (which would have the same effect).

Relevant code is in mscore/musescore.cpp, method: MuseScore::midiNoteReceived().
This declares: static int active = 0; and increments, decrements etc. as note events are processed.

Two workarounds for now:
1. Force extra "note-off" events: disable midi input, press midi key, enable midi input, release key. Repeat as required...
2. Enable midi remote control, and allocate a midi key to do something - which then zeroes the counter when pressed.

I like the idea of adding a failsafe to the note input command. Probably we should reset our internal state and also send an "all notes off" event.

I'm not super familiar with the MIDI handling code in MuseScore, but this is something I feel would be good to address for 2.2. Anyone want to give it a shot?

In reply to by Marc Sabatella

The MIDI standard does have an all-notes-off message which was probably meant for such usecases.
Older MIDI applications often had a 'panic' button to stop all sounds (Aeolus still has example).

Maybe MuseScore needs such a button/action/menu entry. And MuseScore should react to an all-note-off message (I have this mapped to one of my keyboard's buttons). Performing 'magic' on entering/leaving note-input mode seems like a really bad idea. That's fixing broken hardware at the wrong place.

In reply to by rmattes

Agreed that supporting the "all-notes-off" midi message would be a good thing to have. Also strongly agree that 'magic' fixes are a very bad idea - the unintended side effects are generally a real pain.

But there's no magic fix here. The "active note counter" is only used in note-entry mode. It's a state variable that belongs within a note-entry session, and so it should be initialised at the start of each new note-entry session.

If I've missed something here, and the active note counter has some other use outside of a note entry session, then that would be quite different, so please advise if that is the case.

In reply to by rickfitz

Been looking some more at MuseScore::midiNoteReceived(), and found why MuseScore gets into this bad mode. As I suspected, it's not necessarily caused by hardware - and this explains why I've been seeing the issue so often.

QWidget* w = QApplication::activeModalWidget();
if (!cv || w) {
active = 1;
return;
}

So if there's no view open, any midi note received sets active to 1. Later on, when a score is opened and note-entry is enabled, it's still set to 1 - so midi input can't enter new notes. Bingo! I've no idea why this is needed, or what it's trying to achieve.

To try this, open MuseScore but don't open any actual score. Enter a midi note. Create a new score, enable note-input mode, and try entering notes using midi.

There's other weird stuff in there too. static int iter = 0; is compared to a (magic number) threshold of 3 etc., but it's never incremented. This is something to do with drum modules, but it looks unfinished.

So I think someone who knows how this is meant to work needs to take a look and comment on what should be done here.

In reply to by rmattes

The bug report is "MIDI input breaks for rest of session". However, there is more than one way way to trigger this fault condition. The OP reported one way (missing note-off event); I have found another way (any midi note event while no score is open). Different triggers, but both resulting in the exact same problem - that "MIDI input breaks for rest of session".