void MIDIOut::rescanDevices() { /* Treat all devices nonexistent and doomed for destruction */ QList <MIDIDevice*> destroyList(m_devices); /* Find out which devices are still present */ for (ItemCount i = 0; i < MIDIGetNumberOfDevices(); i++) { MIDIDeviceRef dev = MIDIGetDevice(i); for (ItemCount j = 0; j < MIDIDeviceGetNumberOfEntities(dev); j++) { MIDIEntityRef entity = MIDIDeviceGetEntity(dev, j); OSStatus s = 0; SInt32 uid = 0; /* Check if the entity is able to send data */ if (MIDIEntityGetNumberOfDestinations(entity) == 0) continue; /* Extract UID from the entity */ s = MIDIObjectGetIntegerProperty(entity, kMIDIPropertyUniqueID, &uid); if (s != 0) { qWarning() << "Unable to get entity UID"; continue; } MIDIDevice* dev(deviceByUID(uid)); if (dev != NULL) { /* Device still exists */ destroyList.removeAll(dev); } else { /* New device */ dev = new MIDIDevice(this, entity); Q_ASSERT(dev != NULL); if (dev->extractUID() == true && dev->extractName() == true) { addDevice(dev); } else { delete dev; dev = NULL; } } } } /* Destroy all devices that were no longer present */ while (destroyList.isEmpty() == false) delete destroyList.takeFirst(); }
// ____________________________________________________________________________ // Obtain the name of an endpoint without regard for whether it has connections. // The result should be released by the caller. static CFStringRef EndpointName(MIDIEndpointRef endpoint, bool isExternal) { CFMutableStringRef result = CFStringCreateMutable(NULL, 0); CFStringRef str; // begin with the endpoint's name str = NULL; MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &str); if (str != NULL) { CFStringAppend(result, str); CFRelease(str); } MIDIEntityRef entity = NULL; MIDIEndpointGetEntity(endpoint, &entity); if (entity == NULL) // probably virtual return result; if (CFStringGetLength(result) == 0) { // endpoint name has zero length -- try the entity str = NULL; MIDIObjectGetStringProperty(entity, kMIDIPropertyName, &str); if (str != NULL) { CFStringAppend(result, str); CFRelease(str); } } // now consider the device's name MIDIDeviceRef device = NULL; MIDIEntityGetDevice(entity, &device); if (device == NULL) return result; str = NULL; MIDIObjectGetStringProperty(device, kMIDIPropertyName, &str); if (str != NULL) { // if an external device has only one entity, throw away the endpoint name and just use the device name if (isExternal && MIDIDeviceGetNumberOfEntities(device) < 2) { CFRelease(result); return str; } else { // does the entity name already start with the device name? (some drivers do this though they shouldn't) // if so, do not prepend if (CFStringCompareWithOptions(str /* device name */, result /* endpoint name */, CFRangeMake(0, CFStringGetLength(str)), 0) != kCFCompareEqualTo) { // prepend the device name to the entity name if (CFStringGetLength(result) > 0) CFStringInsert(result, 0, CFSTR(" ")); CFStringInsert(result, 0, str); } CFRelease(str); } } return result; }
//_________________________________________________________ // Find the device model associated to a MIDIEndpointRef Boolean GetModel (MIDIEndpointRef device, char* gmodel, int strlen) { int i,j,k, n,m,o,p; MIDIDeviceRef dev; MIDIEntityRef ref; CFStringRef pmodel; OSStatus err; n = MIDIGetNumberOfDevices(); for (i = 0; i < n; i++) { dev = MIDIGetDevice(i); err = MIDIObjectGetStringProperty(dev, kMIDIPropertyModel, &pmodel); if (err == noErr) { if (!CFStringGetCString(pmodel, gmodel, strlen, 0)) { fprintf(stderr, "GetModel error : string too long\n"); return false; } CFRelease(pmodel); m = MIDIDeviceGetNumberOfEntities(dev); for (j = 0; j < m; j++) { ref = MIDIDeviceGetEntity(dev,j); o = MIDIEntityGetNumberOfSources(ref); p = MIDIEntityGetNumberOfDestinations(ref); for (k = 0; k < o; k++) { if (MIDIEntityGetSource(ref,k) == device) return true; } for (k = 0; k < p; k++) { if (MIDIEntityGetDestination(ref,k) == device) return true; } } } } return false; }
static String getEndpointName (MIDIEndpointRef endpoint, bool isExternal) { String result (getMidiObjectName (endpoint)); MIDIEntityRef entity = 0; // NB: don't attempt to use nullptr for refs - it fails in some types of build. MIDIEndpointGetEntity (endpoint, &entity); if (entity == 0) return result; // probably virtual if (result.isEmpty()) 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) { const String deviceName (getMidiObjectName (device)); if (deviceName.isNotEmpty()) { // 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(); } } } return result; }
void MidiApple::openDevices() { qDebug("openDevices"); m_inputDevices.clear(); // How many MIDI devices do we have? ItemCount deviceCount = MIDIGetNumberOfDevices(); // Iterate through all MIDI devices for (ItemCount i = 0 ; i < deviceCount ; ++i) { // Grab a reference to current device MIDIDeviceRef device = MIDIGetDevice(i); char * deviceName = getName(device); QString qsDeviceName = QString::fromUtf8((char*)(deviceName)); qDebug("Device name:%s",deviceName); // Is this device online? (Currently connected?) SInt32 isOffline = 0; MIDIObjectGetIntegerProperty(device, kMIDIPropertyOffline, &isOffline); qDebug(" is online: %s", (isOffline ? "No" : "Yes")); // How many entities do we have? ItemCount entityCount = MIDIDeviceGetNumberOfEntities(device); // Iterate through this device's entities for (ItemCount j = 0 ; j < entityCount ; ++j) { // Grab a reference to an entity MIDIEntityRef entity = MIDIDeviceGetEntity(device, j); qDebug(" Entity: %s", getName(entity)); // Iterate through this device's source endpoints (MIDI In) ItemCount sourceCount = MIDIEntityGetNumberOfSources(entity); for ( ItemCount k = 0 ; k < sourceCount ; ++k ) { // Grab a reference to a source endpoint MIDIEndpointRef source = MIDIEntityGetSource(entity, k); char * name = getName(source); qDebug(" Source: '%s'", name); QString sourceName = qsDeviceName + ":" + QString::fromUtf8((char*)(name)); qDebug(" Source name: '%s'", sourceName.toLatin1().constData() ); m_inputDevices.insert(sourceName, source); openMidiReference(source,sourceName,true); } // Iterate through this device's destination endpoints (MIDI Out) ItemCount destCount = MIDIEntityGetNumberOfDestinations(entity); for ( ItemCount k = 0 ; k < destCount ; ++k ) { // Grab a reference to a destination endpoint MIDIEndpointRef dest = MIDIEntityGetDestination(entity, k); char * name = getName(dest); qDebug(" Destination: '%s'", name); QString destinationName = qsDeviceName + ":" + QString::fromUtf8((char*)(name)); qDebug(" Destination name: '%s'", destinationName.toLatin1().constData() ); m_outputDevices.insert(destinationName, dest); openMidiReference(dest,destinationName,false); } } qDebug("------"); } printQStringKeys("m_inputDevices:",m_inputDevices); printQStringKeys("m_outputDevices:",m_outputDevices); }
//============================================================================== const String getEndpointName (MIDIEndpointRef endpoint, bool isExternal) { String result; CFStringRef str = 0; MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &str); if (str != 0) { result = PlatformUtilities::cfStringToJuceString (str); CFRelease (str); str = 0; } MIDIEntityRef entity = 0; MIDIEndpointGetEntity (endpoint, &entity); if (entity == 0) return result; // probably virtual if (result.isEmpty()) { // endpoint name has zero length - try the entity MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str); if (str != 0) { result += PlatformUtilities::cfStringToJuceString (str); CFRelease (str); str = 0; } } // now consider the device's name MIDIDeviceRef device = 0; MIDIEntityGetDevice (entity, &device); if (device == 0) return result; MIDIObjectGetStringProperty (device, kMIDIPropertyName, &str); if (str != 0) { const String s (PlatformUtilities::cfStringToJuceString (str)); CFRelease (str); // 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)) { // prepend the device name to the entity name result = (s + " " + result).trimEnd(); } } return result; }
void MidiEnumeratorPrivate::rescan() { qDebug() << Q_FUNC_INFO; bool changed = false; QList <MidiOutputDevice*> destroyOutputs(m_outputDevices); QList <MidiInputDevice*> destroyInputs(m_inputDevices); /* Find out which devices are still present */ ItemCount numDevices = MIDIGetNumberOfDevices(); for (ItemCount devIndex = 0; devIndex < numDevices; devIndex++) { MIDIDeviceRef dev = MIDIGetDevice(devIndex); ItemCount numEntities = MIDIDeviceGetNumberOfEntities(dev); for (ItemCount entIndex = 0; entIndex < numEntities; entIndex++) { MIDIEntityRef entity = MIDIDeviceGetEntity(dev, entIndex); /* Get the entity's UID */ QVariant uid = extractUID(entity); if (uid.isValid() == false) continue; QString name = extractName(entity); qDebug() << Q_FUNC_INFO << "Found device:" << name << "UID:" << uid.toString(); ItemCount destCount = MIDIEntityGetNumberOfDestinations(entity); if (destCount > 0) { MidiOutputDevice* dev = outputDevice(uid); if (dev == NULL) { CoreMidiOutputDevice* dev = new CoreMidiOutputDevice( uid, name, entity, m_client, this); m_outputDevices << dev; changed = true; } else { destroyOutputs.removeAll(dev); } } ItemCount srcCount = MIDIEntityGetNumberOfSources(entity); if (srcCount > 0) { MidiInputDevice* dev = inputDevice(uid); if (dev == NULL) { CoreMidiInputDevice* dev = new CoreMidiInputDevice( uid, name, entity, m_client, this); m_inputDevices << dev; changed = true; } else { destroyInputs.removeAll(dev); } } } } foreach (MidiOutputDevice* dev, destroyOutputs) { m_outputDevices.removeAll(dev); delete dev; changed = true; }
unsigned long MidiDeviceUtil::GetMidiEntityCount(int index) { MIDIDeviceRef device = GetMidiDevice(index); return MIDIDeviceGetNumberOfEntities(device); }