Browse Source

Added some CoreMidi assertions to warn about getting the midi device list from a non-message thread.

tags/2021-05-28
jules 13 years ago
parent
commit
ee5ef4b5c3
1 changed files with 57 additions and 91 deletions
  1. +57
    -91
      modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp

+ 57
- 91
modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp View File

@@ -39,20 +39,25 @@ namespace CoreMidiHelpers
#define CHECK_ERROR(a) CoreMidiHelpers::logError (a, __LINE__)
//==============================================================================
static String getEndpointName (MIDIEndpointRef endpoint, bool isExternal)
static String getMidiObjectName (MIDIObjectRef entity)
{
String result;
CFStringRef str = 0;
MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &str);
MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str);
if (str != 0)
{
result = String::fromCFString (str);
CFRelease (str);
str = 0;
}
return result;
}
static String getEndpointName (MIDIEndpointRef endpoint, bool isExternal)
{
String result (getMidiObjectName (endpoint));
MIDIEntityRef entity = 0;
MIDIEndpointGetEntity (endpoint, &entity);
@@ -60,41 +65,29 @@ namespace CoreMidiHelpers
return result; // probably virtual
if (result.isEmpty())
{
// endpoint name has zero length - try the entity
MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str);
if (str != 0)
{
result += String::fromCFString (str);
CFRelease (str);
str = 0;
}
}
result = getMidiObjectName (entity); // endpoint name is empty - try the entity
// now consider the device's name
MIDIDeviceRef device = 0;
MIDIEntityGetDevice (entity, &device);
if (device == 0)
return result;
MIDIObjectGetStringProperty (device, kMIDIPropertyName, &str);
if (str != 0)
if (device != 0)
{
const String s (String::fromCFString (str));
CFRelease (str);
const String deviceName (getMidiObjectName (device));
// if an external device has only one entity, throw away
// the endpoint name and just use the device name
if (isExternal && MIDIDeviceGetNumberOfEntities (device) < 2)
{
result = s;
}
else if (! result.startsWithIgnoreCase (s))
if (deviceName.isNotEmpty())
{
// prepend the device name to the entity name
result = (s + " " + result).trimEnd();
// if an external device has only one entity, throw away
// the endpoint name and just use the device name
if (isExternal && MIDIDeviceGetNumberOfEntities (device) < 2)
{
result = deviceName;
}
else if (! result.startsWithIgnoreCase (deviceName))
{
// prepend the device name to the entity name
result = (deviceName + " " + result).trimEnd();
}
}
}
@@ -139,14 +132,7 @@ namespace CoreMidiHelpers
else
{
// Connected to an external device (10.2) (or something else, catch-all)
CFStringRef str = 0;
MIDIObjectGetStringProperty (connObject, kMIDIPropertyName, &str);
if (str != 0)
{
s = String::fromCFString (str);
CFRelease (str);
}
s = getMidiObjectName (connObject);
}
if (s.isNotEmpty())
@@ -170,6 +156,34 @@ namespace CoreMidiHelpers
return getEndpointName (endpoint, false);
}
static StringArray findDevices (const bool forInput)
{
// Since OSX 10.6, the CoreMidi functions that fetch the list of midi
// devices only work correctly when called from the message thread!
jassert (MessageManager::getInstance()->isThisTheMessageThread());
const ItemCount num = forInput ? MIDIGetNumberOfSources()
: MIDIGetNumberOfDestinations();
StringArray s;
for (ItemCount i = 0; i < num; ++i)
{
MIDIEndpointRef dest = forInput ? MIDIGetSource (i)
: MIDIGetDestination (i);
String name;
if (dest != 0)
name = getConnectedEndpointName (dest);
if (name.isEmpty())
name = "<error>";
s.add (name);
}
return s;
}
static MIDIClientRef getGlobalMidiClient()
{
static MIDIClientRef globalMidiClient = 0;
@@ -280,32 +294,8 @@ namespace CoreMidiHelpers
}
//==============================================================================
StringArray MidiOutput::getDevices()
{
StringArray s;
const ItemCount num = MIDIGetNumberOfDestinations();
for (ItemCount i = 0; i < num; ++i)
{
MIDIEndpointRef dest = MIDIGetDestination (i);
String name;
if (dest != 0)
name = CoreMidiHelpers::getConnectedEndpointName (dest);
if (name.isEmpty())
name = "<error>";
s.add (name);
}
return s;
}
int MidiOutput::getDefaultDeviceIndex()
{
return 0;
}
StringArray MidiOutput::getDevices() { return CoreMidiHelpers::findDevices (false); }
int MidiOutput::getDefaultDeviceIndex() { return 0; }
MidiOutput* MidiOutput::openDevice (int index)
{
@@ -417,32 +407,8 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
}
//==============================================================================
StringArray MidiInput::getDevices()
{
StringArray s;
const ItemCount num = MIDIGetNumberOfSources();
for (ItemCount i = 0; i < num; ++i)
{
MIDIEndpointRef source = MIDIGetSource (i);
String name;
if (source != 0)
name = CoreMidiHelpers::getConnectedEndpointName (source);
if (name.isEmpty())
name = "<error>";
s.add (name);
}
return s;
}
int MidiInput::getDefaultDeviceIndex()
{
return 0;
}
StringArray MidiInput::getDevices() { return CoreMidiHelpers::findDevices (true); }
int MidiInput::getDefaultDeviceIndex() { return 0; }
MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
{


Loading…
Cancel
Save