int prConnectMIDIIn(struct VMGlobals *g, int numArgsPushed) { //PyrSlot *a = g->sp - 2; PyrSlot *b = g->sp - 1; PyrSlot *c = g->sp; int err, inputIndex, uid; err = slotIntVal(b, &inputIndex); if (err) return errWrongType; if (inputIndex < 0 || inputIndex >= gNumMIDIInPorts) return errIndexOutOfRange; err = slotIntVal(c, &uid); if (err) return errWrongType; size_t uid_t = uid; MIDIEndpointRef src=0; MIDIObjectType mtype; MIDIObjectFindByUniqueID(uid, (MIDIObjectRef*)&src, &mtype); if (mtype != kMIDIObjectType_Source) return errFailed; //pass the uid to the midiReadProc to identify the src MIDIPortConnectSource(gMIDIInPort[inputIndex], src, (void*)uid_t); return errNone; }
static String getConnectedEndpointName (MIDIEndpointRef endpoint) { String result; // Does the endpoint have connections? CFDataRef connections = nullptr; int numConnections = 0; MIDIObjectGetDataProperty (endpoint, kMIDIPropertyConnectionUniqueID, &connections); if (connections != nullptr) { numConnections = ((int) CFDataGetLength (connections)) / (int) sizeof (MIDIUniqueID); if (numConnections > 0) { const SInt32* pid = reinterpret_cast<const SInt32*> (CFDataGetBytePtr (connections)); for (int i = 0; i < numConnections; ++i, ++pid) { MIDIUniqueID uid = (MIDIUniqueID) ByteOrder::swapIfLittleEndian ((uint32) *pid); MIDIObjectRef connObject; MIDIObjectType connObjectType; OSStatus err = MIDIObjectFindByUniqueID (uid, &connObject, &connObjectType); if (err == noErr) { String s; if (connObjectType == kMIDIObjectType_ExternalSource || connObjectType == kMIDIObjectType_ExternalDestination) { // Connected to an external device's endpoint (10.3 and later). s = getEndpointName (static_cast<MIDIEndpointRef> (connObject), true); } else { // Connected to an external device (10.2) (or something else, catch-all) s = getMidiObjectName (connObject); } if (s.isNotEmpty()) { if (result.isNotEmpty()) result += ", "; result += s; } } } } CFRelease (connections); } if (result.isEmpty()) // Here, either the endpoint had no connections, or we failed to obtain names for them. result = getEndpointName (endpoint, false); return result; }
int prSendSysex(VMGlobals *g, int numArgsPushed) { int err, uid, size; if( !isKindOfSlot(g->sp, s_int8array->u.classobj) ) return errWrongType; PyrInt8Array* packet = slotRawInt8Array(g->sp); size = packet->size; PyrSlot *u = g->sp - 1; err = slotIntVal(u, &uid); if (err) return err; MIDIEndpointRef dest; MIDIObjectType mtype; MIDIObjectFindByUniqueID(uid, (MIDIObjectRef*)&dest, &mtype); if (mtype != kMIDIObjectType_Destination) return errFailed; if (!dest) return errFailed; MIDISysexSendRequest *pk = (MIDISysexSendRequest*) malloc (sizeof(MIDISysexSendRequest) + size); Byte *data = (Byte *)pk + sizeof(MIDISysexSendRequest); memcpy(data,packet->b, size); pk->complete = false; pk -> destination = dest; pk -> data = data; pk -> bytesToSend = size; pk->completionProc = freeSysex; pk->completionRefCon = 0; return ((MIDISendSysex(pk) == (OSStatus)0) ? errNone : errFailed); }
// Obtain the name of an endpoint, following connections. // The result should be released by the caller. static CFStringRef ConnectedEndpointName(MIDIEndpointRef endpoint) { CFMutableStringRef result = CFStringCreateMutable(NULL, 0); CFStringRef str; OSStatus err; // Does the endpoint have connections? CFDataRef connections = NULL; int nConnected = 0; bool anyStrings = false; err = MIDIObjectGetDataProperty(endpoint, kMIDIPropertyConnectionUniqueID, &connections); if (connections != NULL) { // It has connections, follow them // Concatenate the names of all connected devices nConnected = CFDataGetLength(connections) / sizeof(MIDIUniqueID); if (nConnected) { const SInt32 *pid = reinterpret_cast <const SInt32 *>(CFDataGetBytePtr(connections)); for (int i = 0; i < nConnected; ++i, ++pid) { MIDIUniqueID id = EndianS32_BtoN(*pid); MIDIObjectRef connObject; MIDIObjectType connObjectType; err = MIDIObjectFindByUniqueID(id, &connObject, &connObjectType); if (err == noErr) { if (connObjectType == kMIDIObjectType_ExternalSource || connObjectType == kMIDIObjectType_ExternalDestination) { // Connected to an external device's endpoint (10.3 and later). str = EndpointName(static_cast <MIDIEndpointRef>(connObject), true); } else { // Connected to an external device (10.2) (or something else, catch-all) str = NULL; MIDIObjectGetStringProperty(connObject, kMIDIPropertyName, &str); } if (str != NULL) { if (anyStrings) CFStringAppend(result, CFSTR(", ")); else anyStrings = true; CFStringAppend(result, str); CFRelease(str); } } } } CFRelease(connections); } if (anyStrings) return result; // Here, either the endpoint had no connections, or we failed to obtain names for any of them. return EndpointName(endpoint, false); }
int prSendMIDIOut(struct VMGlobals *g, int numArgsPushed) { //port, uid, len, hiStatus, loStatus, a, b, latency //PyrSlot *m = g->sp - 8; PyrSlot *p = g->sp - 7; PyrSlot *u = g->sp - 6; PyrSlot *l = g->sp - 5; PyrSlot *his = g->sp - 4; PyrSlot *los = g->sp - 3; PyrSlot *a = g->sp - 2; PyrSlot *b = g->sp - 1; PyrSlot *plat = g->sp; int err, outputIndex, uid, length, hiStatus, loStatus, aval, bval; float late; err = slotIntVal(p, &outputIndex); if (err) return err; if (outputIndex < 0 || outputIndex >= gNumMIDIInPorts) return errIndexOutOfRange; err = slotIntVal(u, &uid); if (err) return err; err = slotIntVal(l, &length); if (err) return err; err = slotIntVal(his, &hiStatus); if (err) return err; err = slotIntVal(los, &loStatus); if (err) return err; err = slotIntVal(a, &aval); if (err) return err; err = slotIntVal(b, &bval); if (err) return err; err = slotFloatVal(plat, &late); if (err) return err; MIDIEndpointRef dest; MIDIObjectType mtype; MIDIObjectFindByUniqueID(uid, (MIDIObjectRef*)&dest, &mtype); if (mtype != kMIDIObjectType_Destination) return errFailed; if (!dest) return errFailed; sendmidi(outputIndex, dest, length, hiStatus, loStatus, aval, bval, late); return errNone; }
void CAMIDIEndpoints::AddEndpoints(MIDIEndpointRef endpoint, EndpointList &eplist) { Endpoint *ep, *prev; OSStatus err; CFStringRef str; // Add the driver-owned endpoint ep = new Endpoint(endpoint, EndpointName(endpoint, false), NULL); eplist.push_back(ep); prev = ep; // Does the endpoint have connections? CFDataRef connections = NULL; int nConnected = 0; MIDIObjectGetDataProperty(endpoint, kMIDIPropertyConnectionUniqueID, &connections); if (connections != NULL) { // It has connections, follow them nConnected = CFDataGetLength(connections) / sizeof(MIDIUniqueID); if (nConnected) { const SInt32 *pid = reinterpret_cast <const SInt32 *>(CFDataGetBytePtr(connections)); for (int i = 0; i < nConnected; ++i, ++pid) { MIDIUniqueID id = 0;//EndianS32_BtoN(*pid); MIDIObjectRef connObject; MIDIObjectType connObjectType; err = MIDIObjectFindByUniqueID(id, &connObject, &connObjectType); if (err == noErr) { if (connObjectType == kMIDIObjectType_ExternalSource || connObjectType == kMIDIObjectType_ExternalDestination) { // Connected to an external device's endpoint (10.3 and later). str = EndpointName(static_cast <MIDIEndpointRef>(connObject), true); } else { // Connected to an external device (10.2) (or something else, catch-all) str = NULL; MIDIObjectGetStringProperty(connObject, kMIDIPropertyName, &str); } if (str != NULL) { ep = new Endpoint(endpoint, str, connObject); eplist.push_back(ep); prev->SetNext(ep); prev = ep; } } } } } }
// Get the name of an endpoint. extern "C" const char* MidiJackGetEndpointName(uint32_t id) { ResetPluginIfRequired(); MIDIObjectRef object; MIDIObjectType type; MIDIObjectFindByUniqueID(id, &object, &type); assert(type == kMIDIObjectType_Source); CFStringRef name; MIDIObjectGetStringProperty(object, kMIDIPropertyDisplayName, &name); static char buffer[256]; CFStringGetCString(name, buffer, sizeof(buffer), kCFStringEncodingUTF8); return buffer; }
int prDisconnectMIDIIn(struct VMGlobals *g, int numArgsPushed) { PyrSlot *b = g->sp - 1; PyrSlot *c = g->sp; int err, inputIndex, uid; err = slotIntVal(b, &inputIndex); if (err) return err; if (inputIndex < 0 || inputIndex >= gNumMIDIInPorts) return errIndexOutOfRange; err = slotIntVal(c, &uid); if (err) return err; MIDIEndpointRef src=0; MIDIObjectType mtype; MIDIObjectFindByUniqueID(uid, (MIDIObjectRef*)&src, &mtype); if (mtype != kMIDIObjectType_Source) return errFailed; MIDIPortDisconnectSource(gMIDIInPort[inputIndex], src); return errNone; }
const String getConnectedEndpointName (MIDIEndpointRef endpoint) { String result; // Does the endpoint have connections? CFDataRef connections = 0; int numConnections = 0; MIDIObjectGetDataProperty (endpoint, kMIDIPropertyConnectionUniqueID, &connections); if (connections != 0) { numConnections = (int) (CFDataGetLength (connections) / sizeof (MIDIUniqueID)); if (numConnections > 0) { const SInt32* pid = reinterpret_cast <const SInt32*> (CFDataGetBytePtr (connections)); for (int i = 0; i < numConnections; ++i, ++pid) { MIDIUniqueID uid = EndianS32_BtoN (*pid); MIDIObjectRef connObject; MIDIObjectType connObjectType; OSStatus err = MIDIObjectFindByUniqueID (uid, &connObject, &connObjectType); if (err == noErr) { String s; if (connObjectType == kMIDIObjectType_ExternalSource || connObjectType == kMIDIObjectType_ExternalDestination) { // Connected to an external device's endpoint (10.3 and later). s = getEndpointName (static_cast <MIDIEndpointRef> (connObject), true); } else { // Connected to an external device (10.2) (or something else, catch-all) CFStringRef str = 0; MIDIObjectGetStringProperty (connObject, kMIDIPropertyName, &str); if (str != 0) { s = PlatformUtilities::cfStringToJuceString (str); CFRelease (str); } } if (s.isNotEmpty()) { if (result.isNotEmpty()) result += ", "; result += s; } } } } CFRelease (connections); } if (result.isNotEmpty()) return result; // Here, either the endpoint had no connections, or we failed to obtain names for any of them. return getEndpointName (endpoint, false); }