Strange MIDI behaviour


#1

Hey
I currently have the following hardware-software set-up - A USB MIDI device which sends SysEx messages to my JUCE-made software, and then depending on settings applied within the software and the received SysEx messages, MIDI note-on, note-off, and CC messages are sent back to the device (which is MIDI Thru) so that these messages can then be sent to any other MIDI software. I do realise that this is a weird setup (especially as any MIDI being sent out of the software will end up coming back in!) - eventually the hardware will be able to create all it’s own MIDI messages, however for now I just wanted to test that the SysEx messages were being sent and decoded correctly.

My problem is this - SysEx messages are being received fine however when I try and send MIDI messages back to the device to be transmitted elsewhere the software seems to just disconnect from the MIDI input (so I cannot receive the SySex messages), however MIDI can still be sent out to the device and transmitted to other software. If I just send note on and off messages fairly slowly everything works OK, and also it seems to work fine on Linux, but not Windows or OSX. Within handleIncomingMidiMessage() I’m only responding to SysEx messages - anything else (e.g. the messages being sent out and then consequently back in) is simply ignored. Also once the MIDI input crashes, if I click on the MIDI input selector within the AudioDeviceSelectorComponent the whole software just freezes.

Why is this? Is it due to the fact that there is just too much MIDI activity going on which causes the MIDI input to crash? Is this something handled within Juce or within the actual MIDI protocol?


#2

I’m writing a big MIDI app and had no problems so far on any platform. The MIDI code is very stable and never “crashes” or “freezes” anything, though i must say i do not use the AudioDeviceManager stuff cause i don’t use AUDIO at all just MIDI so i don’t touch those classes. I just open and close my MIDI device using JUCE calls and it all seems fine. Maybe you can share some of the relevant parts of your code (midi callbacks, places where you open/close devices) and we can say a bit more then.


#3

Hey atom,
Sorry for the delay in replying; thought I would see if updating to Juce 2.0 would solve my problem, but unfortunately not.

I’ve done a lot of testing since and it seems like the software just disconnects from the MIDI input device if there’s ‘too much’ MIDI data coming in. I’ve programmed the hardware device to send out note on/off and CC messages at the same time as it sends out the SysEx messages, and if I try and send note and CC data quickly my app suddenly stops responding to the data, however other software (e.g. Logic Pro) is still receiving and responding to the messages fine.

Any ideas?

This is how I setup my MIDI I/O devices:

    #if JUCE_MAC
    audioDeviceManager.addMidiInputCallback(String::empty, this);
    audioDeviceManager.setMidiInputEnabled("HIDUINO", true);
    #endif
    
    #if JUCE_WINDOWS || JUCE_LINUX
    audioDeviceManager.addMidiInputCallback(String::empty, this);
    audioDeviceManager.setMidiInputEnabled("alpha-testrig", true);
    #endif
    
    
    //SET UP MIDI OUTPUT
    #if JUCE_MAC
    audioDeviceManager.setDefaultMidiOutput("HIDUINO");
    #endif
    
    #if JUCE_WINDOWS || JUCE_LINUX
    audioDeviceManager.setDefaultMidiOutput("alpha-testrig");
    #endif
    
    midiOutputDevice = MidiOutput::openDevice(MidiOutput::getDefaultDeviceIndex());
    
    if(midiOutputDevice)
        midiOutputDevice->startBackgroundThread();
    else
        std::cout << "Failed to connect to a MIDI device!" << std::endl;

And this is my MIDI callback:

void OscRouting::handleIncomingMidiMessage(MidiInput* midiInput, const MidiMessage& midiMessage)
{
    if(midiMessage.isSysEx())
    {
        std::cout << "SysEx\n";
        std::cout << String::toHexString(midiMessage.getRawData(), midiMessage.getRawDataSize()) << std::endl;
    
        unsigned char *sysexData = midiMessage.getRawData();
        
        //check for the device ID
        if (sysexData[1] == 0x00 && sysexData[2] == 0x21 && sysexData[3] == 0x0c)
        {
            if (midiMessage.getRawDataSize() == 8)
            {
                //get values from the relevent sysexData arrays
                int pad = sysexData[4];
                int pressure = sysexData[6] * (511.0/127.0);
                
                //do something with the values
                oscCallBack (pad, pressure);
                
            }
        }
    }
}

#4

Something else I should have mentioned in my last post - once the MIDI input device disconnects I am still able to successfully send MIDI data back out , even though it is the same device.