/* lifted from portmidi */ static char *get_ep_name(MIDIEndpointRef ep) { MIDIEntityRef entity; MIDIDeviceRef device; CFStringRef endpointName = NULL, deviceName = NULL, fullName = NULL; CFStringEncoding defaultEncoding; char* newName; /* get the default string encoding */ defaultEncoding = CFStringGetSystemEncoding(); /* get the entity and device info */ MIDIEndpointGetEntity(ep, &entity); MIDIEntityGetDevice(entity, &device); /* create the nicely formated name */ MIDIObjectGetStringProperty(ep, kMIDIPropertyName, &endpointName); MIDIObjectGetStringProperty(device, kMIDIPropertyName, &deviceName); if (deviceName != NULL) { fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@: %@"), deviceName, endpointName); } else { fullName = endpointName; } /* copy the string into our buffer */ newName = (char*)mem_alloc(CFStringGetLength(fullName) + 1); CFStringGetCString(fullName, newName, CFStringGetLength(fullName) + 1, defaultEncoding); /* clean up */ if (fullName && !deviceName) CFRelease(fullName); return newName; }
// ____________________________________________________________________________ // 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; }
char * MidiApple::getFullName(MIDIEndpointRef &endpoint_ref) { MIDIEntityRef entity = 0; MIDIEndpointGetEntity(endpoint_ref, &entity); //get the entity MIDIDeviceRef device = 0; MIDIEntityGetDevice(entity, &device); char * deviceName = getName(device); char * endPointName = getName(endpoint_ref); qDebug("device name='%s' endpoint name='%s'",deviceName,endPointName); char * fullName = (char *)malloc(strlen(deviceName) + strlen(endPointName)+1); sprintf(fullName, "%s:%s", deviceName,endPointName); return fullName; }
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; }
int prListMIDIEndpoints(struct VMGlobals *g, int numArgsPushed) { OSStatus error; PyrSlot *a = g->sp; int numSrc = (int)MIDIGetNumberOfSources(); int numDst = (int)MIDIGetNumberOfDestinations(); PyrObject* idarray = newPyrArray(g->gc, 6 * sizeof(PyrObject), 0 , true); SetObject(a, idarray); PyrObject* idarraySo = newPyrArray(g->gc, numSrc * sizeof(SInt32), 0 , true); SetObject(idarray->slots+idarray->size++, idarraySo); g->gc->GCWrite(idarray, idarraySo); PyrObject* devarraySo = newPyrArray(g->gc, numSrc * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, devarraySo); g->gc->GCWrite(idarray, devarraySo); PyrObject* namearraySo = newPyrArray(g->gc, numSrc * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, namearraySo); g->gc->GCWrite(idarray, namearraySo); PyrObject* idarrayDe = newPyrArray(g->gc, numDst * sizeof(SInt32), 0 , true); SetObject(idarray->slots+idarray->size++, idarrayDe); g->gc->GCWrite(idarray, idarrayDe); PyrObject* namearrayDe = newPyrArray(g->gc, numDst * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, namearrayDe); g->gc->GCWrite(idarray, namearrayDe); PyrObject* devarrayDe = newPyrArray(g->gc, numDst * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, devarrayDe); g->gc->GCWrite(idarray, devarrayDe); for (int i=0; i<numSrc; ++i) { MIDIEndpointRef src = MIDIGetSource(i); SInt32 id; MIDIObjectGetIntegerProperty(src, kMIDIPropertyUniqueID, &id); MIDIEntityRef ent; error = MIDIEndpointGetEntity(src, &ent); CFStringRef devname, endname; char cendname[1024], cdevname[1024]; // Virtual sources don't have entities if(error) { MIDIObjectGetStringProperty(src, kMIDIPropertyName, &devname); MIDIObjectGetStringProperty(src, kMIDIPropertyName, &endname); CFStringGetCString(devname, cdevname, 1024, kCFStringEncodingUTF8); CFStringGetCString(endname, cendname, 1024, kCFStringEncodingUTF8); } else { MIDIDeviceRef dev; MIDIEntityGetDevice(ent, &dev); MIDIObjectGetStringProperty(dev, kMIDIPropertyName, &devname); MIDIObjectGetStringProperty(src, kMIDIPropertyName, &endname); CFStringGetCString(devname, cdevname, 1024, kCFStringEncodingUTF8); CFStringGetCString(endname, cendname, 1024, kCFStringEncodingUTF8); } PyrString *string = newPyrString(g->gc, cendname, 0, true); SetObject(namearraySo->slots+i, string); namearraySo->size++; g->gc->GCWrite(namearraySo, (PyrObject*)string); PyrString *devstring = newPyrString(g->gc, cdevname, 0, true); SetObject(devarraySo->slots+i, devstring); devarraySo->size++; g->gc->GCWrite(devarraySo, (PyrObject*)devstring); SetInt(idarraySo->slots+i, id); idarraySo->size++; CFRelease(devname); CFRelease(endname); } // post("numDst %d\n", numDst); for (int i=0; i<numDst; ++i) { MIDIEndpointRef dst = MIDIGetDestination(i); SInt32 id; MIDIObjectGetIntegerProperty(dst, kMIDIPropertyUniqueID, &id); MIDIEntityRef ent; error = MIDIEndpointGetEntity(dst, &ent); CFStringRef devname, endname; char cendname[1024], cdevname[1024]; // Virtual destinations don't have entities either if(error) { MIDIObjectGetStringProperty(dst, kMIDIPropertyName, &devname); MIDIObjectGetStringProperty(dst, kMIDIPropertyName, &endname); CFStringGetCString(devname, cdevname, 1024, kCFStringEncodingUTF8); CFStringGetCString(endname, cendname, 1024, kCFStringEncodingUTF8); } else { MIDIDeviceRef dev; MIDIEntityGetDevice(ent, &dev); MIDIObjectGetStringProperty(dev, kMIDIPropertyName, &devname); MIDIObjectGetStringProperty(dst, kMIDIPropertyName, &endname); CFStringGetCString(devname, cdevname, 1024, kCFStringEncodingUTF8); CFStringGetCString(endname, cendname, 1024, kCFStringEncodingUTF8); } PyrString *string = newPyrString(g->gc, cendname, 0, true); SetObject(namearrayDe->slots+namearrayDe->size++, string); g->gc->GCWrite(namearrayDe, (PyrObject*)string); PyrString *devstring = newPyrString(g->gc, cdevname, 0, true); SetObject(devarrayDe->slots+devarrayDe->size++, devstring); g->gc->GCWrite(devarrayDe, (PyrObject*)devstring); SetInt(idarrayDe->slots+idarrayDe->size++, id); CFRelease(devname); CFRelease(endname); } return errNone; }
//============================================================================== 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; }