From 535a55e47a2ef433c4daa88068a6defab801942b Mon Sep 17 00:00:00 2001 From: athrxx Date: Sat, 25 Feb 2012 14:09:05 +0100 Subject: AUDIO: (Windows) fix issue with non-unique MIDI device names This should fix the issue mentioned here: http://forums.scummvm.org/viewtopic.php?t=11255 Apparently Windows doesn't generate unique names for MIDI devices of the exact same type. I do not know whether this could be a problem on other backends, too. --- backends/midi/windows.cpp | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'backends/midi/windows.cpp') diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp index 828411cd22..f4c5431d6e 100644 --- a/backends/midi/windows.cpp +++ b/backends/midi/windows.cpp @@ -177,13 +177,49 @@ MusicDevices WindowsMusicPlugin::getDevices() const { int numDevs = midiOutGetNumDevs(); MIDIOUTCAPS tmp; + Common::StringArray deviceNames; for (int i = 0; i < numDevs; i++) { if (midiOutGetDevCaps(i, &tmp, sizeof(MIDIOUTCAPS)) != MMSYSERR_NOERROR) break; + deviceNames.push_back(tmp.szPname); + } + + // Check for non-unique device names. This may happen if someone has devices with identical + // names (e. g. more than one USB device of the exact same hardware type). It seems that this + // does happen in reality sometimes. We generate index numbers for these devices. + // This is not an ideal solution, since this index could change whenever another USB + // device gets plugged in or removed, switched off or just plugged into a different port. + // Unfortunately midiOutGetDevCaps() does not generate any other unique information + // that could be used. Our index numbers which match the device order should at least be + // a little more stable than just using the midiOutGetDevCaps() device ID, since a missing + // device (e.g. switched off) should actually not be harmful to our indices (as it would be + // when using the device IDs). The cases where users have devices with identical names should + // be rare enough anyway. + Common::Array nonUniqueIndex; + for (int i = 0; i < numDevs; i++) { + int match = -1; + for (int ii = 0; ii < i; ii++) { + if (deviceNames[i] == deviceNames[ii]) { + if (nonUniqueIndex[ii] == -1) + nonUniqueIndex[ii] = 0; + if (++match == 0) + ++match; + } + } + nonUniqueIndex.push_back(match); + } + + // We now add the index number to the non-unique device names to make them unique. + for (int i = 0; i < numDevs; i++) { + if (nonUniqueIndex[i] != -1) + deviceNames[i] = Common::String::format("%s - #%.02d", deviceNames[i].c_str(), nonUniqueIndex[i]); + } + + for (Common::StringArray::iterator i = deviceNames.begin(); i != deviceNames.end(); ++i) // There is no way to detect the "MusicType" so I just set it to MT_GM // The user will have to manually select his MT32 type device and his GM type device. - devices.push_back(MusicDevice(this, tmp.szPname, MT_GM)); - } + devices.push_back(MusicDevice(this, *i, MT_GM)); + return devices; } -- cgit v1.2.3