Pulling a out a MIDI device does not disable it -> jassert/crash upon reinsertion


#1

I have an AKAI LPK25 set to enabled (either with DeviceManager::setMidiInputEnabled(true) or by initializing the AudioDeviceManager using an XML). Whenever I pull out the AKAI and then reinsert it, JUCE asserts as follows:

// JUCE_MidiDataConcatenator.h

template <typename UserDataType, typename CallbackType>
void pushMidiData (const void* inputData, int numBytes, double time,
                   UserDataType* input, CallbackType& callback)
{
    ...

    
    if (len > 0) 
    {
        int used = 0;
        const MidiMessage m (data, len, used, 0, time);
        if (used <= 0)
            break; // malformed message..
        jassert (used == len);
        callback.handleIncomingMidiMessage (input, m);
        runningStatus = data[0];
    }
}

len is always 1, used is always 2, but the values in data always change around (hinting at a garbage memory bug).

If I disable the AKAI first (using my GUI) and then pull-out/reinsert, nothing changes. Starting a timer that periodically checks for removed devices and then calling AudioDeviceManager::setMidiInputEnabled(false) on them also works.

When I try to do the same with a StudioLogic VMK-88, everything works just fine.

I am using OSX, but am not sure if this also happens under Windows (which is why I put it in the general forum). Using JUCE 3.1.1.


#2

This seems to me to be a driver issue spitting out garbage when the device is disconnected. I feel the assert should still be there in this case but maybe the callback and reading data[0] should be guarded. Does the following work for you:



if (len > 0)
{
    int used = 0;
    const MidiMessage m (data, len, used, 0, time);
      
    jassert (used == len);

    if (used <= 0 || used != len)
        break;

    callback.handleIncomingMidiMessage (input, m);
    runningStatus = data[0];
}

If yes, we will commit it to the repo.


#3

I'm currently not at work (where the AKAI is), but I'll let you know as soon as I get there.

I don't really see how swapping the jassert and if would solve the problem though, it only moves the assert upwards (len and used are still not-equal). Or am I misunderstanding the problem?


#4

Fabian's point is that this assertion should remain in place because the driver seems to be delivering junk data instead of a valid midi message, and as a developer you probably want to be warned about that.

But by changing the code to ignore the junk message, at least your app can continue to run and no garbage will be sent to to your midi handler callback, even though you may find the assertions annoying.