About monitoring MIDI devices, you need to reopen the program after unplugging

Hi, hello,

I’m just getting started with juce, and now I’m doing a project about MIDI communication to start with juce. When I start the program MIDI input and MIDI output are running normally, I can receive information, but when I unplug the UBS power supply and plug in the program again, I can’t receive MIDI information. I need to restart the program again to run normally! How can I solve this problem? Does anyone know what to do? Thank you very much.

IIRC the juce MidiInput won’t reconnect automatically. You will need to store the last selected MidiInput name, and once it disconnects, you can start a timer to poll for either the selected name, or if you want for the next possible device and reconnect once one is available.

Both are valid strategies, depending on your preference.

Hope that helps

@daniel This is the code I listened to MIDI input:

void setMiDiInput(int index)
	{
		auto list = MidiInput::getDevices();
		deviceMangger.removeMidiInputCallback(list[lastInputIndex], this);
		auto newOutput = list[index];
		
		if (!deviceMangger.isMidiInputEnabled(newOutput))
		{
			deviceMangger.setMidiInputEnabled(newOutput, true);
		}
		deviceMangger.addMidiInputCallback(newOutput, this);
		output.setSelectedId(index + 2, dontSendNotification);
		midiInputList.setSelectedId(index + 1, dontSendNotification);
		lastInputIndex = index;
	}

This is the code to call the timer:

void timerCallback() override
	{
		inp_now_item_list = MidiInput::getDevices();
		if (inp_now_item_list == inp_pre_item_list)
		{
			midiInputList.clear(dontSendNotification);
			midiInputList.addItemList(inp_now_item_list, 1);
			inp_now_item_list.clear();
			setMiDiInput(0);
		}
		inp_pre_item_list = inp_now_item_list;
		
	}

When I plug in or unplug the device name, it can be displayed normally, but as long as I unplug the device and open it again, I can’t receive the information, so I need to reopen the program to run normally. Why?

Can you please add three back ticks ``` in the line before and after your code to fix the layout?
Use the pen symbol to edit your post above

I am actually not the best person to ask MIDI specifics. I saw @leehu was typing while I was typing too, maybe he knows…

@daniel
Thank you very much for your help

This problem has been bothering me for a long time. I don’t know how to solve it

Hi. Stopped typing as your answer came up first and I had nothing to add :slight_smile: Windows won’t reconnect MIDI once it’s been disconnected. Ill check the code later.

Looking at your code, not sure what the stuff you’re doing with device manager is - I simply use MidiInput::openDevice() and then call start() on the returned device - maybe try that.

@leehu
hey,leehu!
I mainly use the timer callback function. When the device is unplugged and plugged again, the device items list will change. Once the device items list change, it would update the device items list and reset the midi input port.

@leehu
But I failed. Obviously, it can update the list of items, but when I reset the input port, it will not respond and I will not receive the MIDI information. I need to open the program again to receive the information!

I don’t know how the device manager is interacting, and you don’t need to access this directly which I why I was suggesting just using MidiInput::openDevice() and then start() to see if this worked.

@leehu
I tried it. I think there is something wrong with my operation! Do you have relevant examples for me to refer to?

m_p_midi_in = MidiInput::openDevice( phys_index, p_callback );

if ( m_p_midi_in )
    m_p_midi_in->start();

@leehu
I don’t think I know too much! Do you have an instance that can be run for me to refer to? Thank you very much.

sorry, no, as my code is wrapped into my own framework.

Not sure what’s confusing about the example, just call openDevice() and then start() on the result…

There does appear to be a problem with reconnected enabled devices not working. I dont know if its a windows only issue or not.

Im modifying AudioDeviceManager for my own purposes and editing audioDeviceListChanged() to pick up the dis / re connections. Ive tried a number of approaches which seem valid but don’t work.

Whats strange is that I even resorted to running through the exact same routine as manually toggling the device in AudioDeviceSelectorComponent; so removing the old then opening a new one.

Stepping through I can see no difference in implementation when passing through AudioDeviceManager::setMidiInputDeviceEnabled, but still it doesnt work.

Anyone have any ideas?.

Ok, because im such a great guy il provide the answer for posterity.

Seems to be a timing issue, the enabled device, when reconnected, does require disposing of. But reopening a new device in the same call doesnt work, i guess because removing the callback overlaps adding a new one, and its assigned by identifier, not instance.

So simply setting a timer after removal for 100ms, then creating a new MidiInput works.

@huddink
OMG Thank, I’ve been killing myself trying to fix this issue with not receiving input MIDI data after re-opening. You’re right, if you close then re-open in the same call it doesn’t work, you need to wait a bit. I have a period timer looking for MIDI devices so if a close a devices If skip the re-opening until the next timer, works as you said.

Thank you so much for taking the time to come back and post the solution!

As a note, this happens on Windows (where I deploy my app) but not in Linux where I develop my app.