AudioDeviceManager active MIDI ins XML bug/limitation + fix


#1

In my app I use a AudioDeviceSelector component. When I activate some MIDI Inputs of my USB MIDI card and exit my application, and open my application again, everything’s fine.

But if I run my application again without having the USB MIDI card connected, then exit the application and then run it again with the USB MIDI card connected, all my previously activated MIDI Inputs are not activated anymore (but the default MIDI Output I selected is still ok).

So it seems that when the USB MIDI card is disconnected once when starting the AudioDeviceManager, all previously activated MIDI Inputs are thrown away.

I guess it isn’t intended this way?


#2

Ok, I don’t have time to wait, so here’s how I fixed it:

  1. I moved the StringArray enabledMidiIns (that was declared locally in the AudioDeviceManager constructor) into the private section of AudioDeviceManager.

  2. I added this code to the function updateXml(). The code has to be put in front of the 2 last code lines of this function (if (defaultMidiOutputName.isNotEmpty())
    lastExplicitSettings->setAttribute (T(“defaultMidiOutput”), defaultMidiOutputName); ).

What it does: It checks if the enabledMidiIns previously found in the last saved XML are present on the system and if they are not it adds them to the XML again (the original AudioDeviceManager does only take those activated midi inputs in account which are on the system, which is OK for PCI cards, but not for USB cards that are often disconnected and connected again).

StringArray s=MidiInput::getDevices();
	for (int i = 0; i < enabledMidiIns.size(); ++i)
    {
		bool forceAdd=true;
		for (int j=0; j<s.size(); j++)
			if (enabledMidiIns.contains(s[j])) forceAdd=false;
			
		if (forceAdd) // this means that some activated midi input from the previous xml settings
					  // was not in the midi input devices list that are present on system,
					  // and so it should still be saved in the XML
		{
			XmlElement* const m = new XmlElement (T("MIDIINPUT"));
			m->setAttribute (T("name"), enabledMidiIns[i]);
        	lastExplicitSettings->addChildElement (m);
		}
	}

#3

Ok, that all sounds pretty sensible - I’ll see if I can do something along those lines. Thanks!


#4

Does this do the job? (I changed the name of enabledMidiIns to midiInsFromXml).

[code]
if (midiInsFromXml.size() > 0)
{
// Add any midi devices that have been enabled before, but which aren’t currently
// open because the device has been disconnected.
const StringArray availableMidiDevices (MidiInput::getDevices());

    for (int i = 0; i < midiInsFromXml.size(); ++i)
    {
        if (! availableMidiDevices.contains (midiInsFromXml[i], true)) 
        {
            XmlElement* const m = new XmlElement (T("MIDIINPUT"));
            m->setAttribute (T("name"), midiInsFromXml[i]);

            lastExplicitSettings->addChildElement (m);
        }
    }
}[/code]

#5

Works for me.