From 248d355b98c1977d2882aa2dd6add86a782dad67 Mon Sep 17 00:00:00 2001 From: Jim Snavely Date: Sun, 4 Aug 2024 10:18:41 -0400 Subject: [PATCH 1/2] fix clang errors --- portmidi/pm_mac/pmmacosxcm.c | 777 +++++++++++++++++++---------------- 1 file changed, 422 insertions(+), 355 deletions(-) diff --git a/portmidi/pm_mac/pmmacosxcm.c b/portmidi/pm_mac/pmmacosxcm.c index 999e41c..bf381ba 100644 --- a/portmidi/pm_mac/pmmacosxcm.c +++ b/portmidi/pm_mac/pmmacosxcm.c @@ -1,13 +1,13 @@ /* * Platform interface to the MacOS X CoreMIDI framework - * + * * Jon Parise * and subsequent work by Andrew Zeldis and Zico Kolter * and Roger B. Dannenberg * * $Id: pmmacosx.c,v 1.17 2002/01/27 02:40:40 jon Exp $ */ - + /* Notes: since the input and output streams are represented by MIDIEndpointRef values and almost no other state, we store the MIDIEndpointRef on @@ -16,14 +16,14 @@ the error text. We use a structure with two kinds of host error: "error" and "callback_error". That way, asynchronous callbacks do not interfere with other error information. - + OS X does not seem to have an error-code-to-text function, so we will just use text messages instead of error codes. */ #include -//#define CM_DEBUG 1 +// #define CM_DEBUG 1 #include "portmidi.h" #include "pmutil.h" @@ -41,7 +41,7 @@ #define PACKET_BUFFER_SIZE 1024 -/* this is very strange: if I put in a reasonable +/* this is very strange: if I put in a reasonable number here, e.g. 128, which would allow sysex data to be sent 128 bytes at a time, then I lose sysex data in my loopback test. With a buffer size of 4, @@ -53,24 +53,27 @@ #define VERBOSE_ON 1 #define VERBOSE if (VERBOSE_ON) -#define MIDI_SYSEX 0xf0 -#define MIDI_EOX 0xf7 +#define MIDI_SYSEX 0xf0 +#define MIDI_EOX 0xf7 #define MIDI_STATUS_MASK 0x80 +#define MIDI_NULL 0 +#define INT2VOIDP(i) (void *)(uintptr_t)(i) -static MIDIClientRef client = NULL; /* Client handle to the MIDI server */ -static MIDIPortRef portIn = NULL; /* Input port handle */ -static MIDIPortRef portOut = NULL; /* Output port handle */ +static MIDIClientRef client = MIDI_NULL; /* Client handle to the MIDI server */ +static MIDIPortRef portIn = MIDI_NULL; /* Input port handle */ +static MIDIPortRef portOut = MIDI_NULL; /* Output port handle */ extern pm_fns_node pm_macosx_in_dictionary; extern pm_fns_node pm_macosx_out_dictionary; -typedef struct midi_macosxcm_struct { - unsigned long sync_time; /* when did we last determine delta? */ - UInt64 delta; /* difference between stream time and real time in ns */ - UInt64 last_time; /* last output time */ - int first_message; /* tells midi_write to sychronize timestamps */ - int sysex_mode; /* middle of sending sysex */ - unsigned long sysex_word; /* accumulate data when receiving sysex */ +typedef struct midi_macosxcm_struct +{ + unsigned long sync_time; /* when did we last determine delta? */ + UInt64 delta; /* difference between stream time and real time in ns */ + UInt64 last_time; /* last output time */ + int first_message; /* tells midi_write to sychronize timestamps */ + int sysex_mode; /* middle of sending sysex */ + unsigned long sysex_word; /* accumulate data when receiving sysex */ unsigned int sysex_byte_count; /* count how many received */ char error[PM_HOST_ERROR_MSG_LEN]; char callback_error[PM_HOST_ERROR_MSG_LEN]; @@ -78,9 +81,9 @@ typedef struct midi_macosxcm_struct { MIDIPacketList *packetList; /* a pointer to packetBuffer */ MIDIPacket *packet; Byte sysex_buffer[SYSEX_BUFFER_SIZE]; /* temp storage for sysex data */ - MIDITimeStamp sysex_timestamp; /* timestamp to use with sysex data */ + MIDITimeStamp sysex_timestamp; /* timestamp to use with sysex data */ /* allow for running status (is running status possible here? -rbd): -cpr */ - unsigned char last_command; + unsigned char last_command; long last_msg_length; } midi_macosxcm_node, *midi_macosxcm_type; @@ -88,20 +91,19 @@ typedef struct midi_macosxcm_struct { MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp); PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp); -char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint); - +char *cm_get_full_endpoint_name(MIDIEndpointRef endpoint); static int midi_length(long msg) { int status, high, low; static int high_lengths[] = { - 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 through 0x70 */ - 3, 3, 3, 3, 2, 2, 3, 1 /* 0x80 through 0xf0 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 through 0x70 */ + 3, 3, 3, 3, 2, 2, 3, 1 /* 0x80 through 0xf0 */ }; static int low_lengths[] = { - 1, 2, 3, 2, 1, 1, 1, 1, /* 0xf0 through 0xf8 */ - 1, 1, 1, 1, 1, 1, 1, 1 /* 0xf9 through 0xff */ + 1, 2, 3, 2, 1, 1, 1, 1, /* 0xf0 through 0xf8 */ + 1, 1, 1, 1, 1, 1, 1, 1 /* 0xf9 through 0xff */ }; status = msg & 0xFF; @@ -113,119 +115,130 @@ midi_length(long msg) static PmTimestamp midi_synchronize(PmInternal *midi) { - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - UInt64 pm_stream_time_2 = - AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + UInt64 pm_stream_time_2 = + AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); PmTimestamp real_time; UInt64 pm_stream_time; - /* if latency is zero and this is an output, there is no + /* if latency is zero and this is an output, there is no time reference and midi_synchronize should never be called */ assert(midi->time_proc); assert(!(midi->write_flag && midi->latency == 0)); - do { - /* read real_time between two reads of stream time */ - pm_stream_time = pm_stream_time_2; - real_time = (*midi->time_proc)(midi->time_info); - pm_stream_time_2 = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); - /* repeat if more than 0.5 ms has elapsed */ + do + { + /* read real_time between two reads of stream time */ + pm_stream_time = pm_stream_time_2; + real_time = (*midi->time_proc)(midi->time_info); + pm_stream_time_2 = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); + /* repeat if more than 0.5 ms has elapsed */ } while (pm_stream_time_2 > pm_stream_time + 500000); - m->delta = pm_stream_time - ((UInt64) real_time * (UInt64) 1000000); + m->delta = pm_stream_time - ((UInt64)real_time * (UInt64)1000000); m->sync_time = real_time; return real_time; } - static void -process_packet(MIDIPacket *packet, PmEvent *event, - PmInternal *midi, midi_macosxcm_type m) +process_packet(MIDIPacket *packet, PmEvent *event, + PmInternal *midi, midi_macosxcm_type m) { /* handle a packet of MIDI messages from CoreMIDI */ /* there may be multiple short messages in one packet (!) */ unsigned int remaining_length = packet->length; unsigned char *cur_packet_data = packet->data; - while (remaining_length > 0) { + while (remaining_length > 0) + { if (cur_packet_data[0] == MIDI_SYSEX || /* are we in the middle of a sysex message? */ (m->last_command == 0 && - !(cur_packet_data[0] & MIDI_STATUS_MASK))) { + !(cur_packet_data[0] & MIDI_STATUS_MASK))) + { m->last_command = 0; /* no running status */ - unsigned int amt = pm_read_bytes(midi, cur_packet_data, - remaining_length, + unsigned int amt = pm_read_bytes(midi, cur_packet_data, + remaining_length, event->timestamp); remaining_length -= amt; cur_packet_data += amt; - } else if (cur_packet_data[0] == MIDI_EOX) { + } + else if (cur_packet_data[0] == MIDI_EOX) + { /* this should never happen, because pm_read_bytes should * get and read all EOX bytes*/ midi->sysex_in_progress = FALSE; m->last_command = 0; - } else if (cur_packet_data[0] & MIDI_STATUS_MASK) { + } + else if (cur_packet_data[0] & MIDI_STATUS_MASK) + { /* compute the length of the next (short) msg in packet */ - unsigned int cur_message_length = midi_length(cur_packet_data[0]); - if (cur_message_length > remaining_length) { + unsigned int cur_message_length = midi_length(cur_packet_data[0]); + if (cur_message_length > remaining_length) + { #ifdef DEBUG printf("PortMidi debug msg: not enough data"); #endif - /* since there's no more data, we're done */ - return; - } - m->last_msg_length = cur_message_length; - m->last_command = cur_packet_data[0]; - switch (cur_message_length) { - case 1: - event->message = Pm_Message(cur_packet_data[0], 0, 0); - break; - case 2: - event->message = Pm_Message(cur_packet_data[0], - cur_packet_data[1], 0); - break; - case 3: - event->message = Pm_Message(cur_packet_data[0], - cur_packet_data[1], - cur_packet_data[2]); - break; - default: + /* since there's no more data, we're done */ + return; + } + m->last_msg_length = cur_message_length; + m->last_command = cur_packet_data[0]; + switch (cur_message_length) + { + case 1: + event->message = Pm_Message(cur_packet_data[0], 0, 0); + break; + case 2: + event->message = Pm_Message(cur_packet_data[0], + cur_packet_data[1], 0); + break; + case 3: + event->message = Pm_Message(cur_packet_data[0], + cur_packet_data[1], + cur_packet_data[2]); + break; + default: /* PortMIDI internal error; should never happen */ assert(cur_message_length == 1); - return; /* give up on packet if continued after assert */ - } - pm_read_short(midi, event); - remaining_length -= m->last_msg_length; - cur_packet_data += m->last_msg_length; - } else if (m->last_msg_length > remaining_length + 1) { - /* we have running status, but not enough data */ + return; /* give up on packet if continued after assert */ + } + pm_read_short(midi, event); + remaining_length -= m->last_msg_length; + cur_packet_data += m->last_msg_length; + } + else if (m->last_msg_length > remaining_length + 1) + { + /* we have running status, but not enough data */ #ifdef DEBUG - printf("PortMidi debug msg: not enough data in CoreMIDI packet"); + printf("PortMidi debug msg: not enough data in CoreMIDI packet"); #endif - /* since there's no more data, we're done */ - return; - } else { /* output message using running status */ - switch (m->last_msg_length) { - case 1: - event->message = Pm_Message(m->last_command, 0, 0); - break; - case 2: - event->message = Pm_Message(m->last_command, - cur_packet_data[0], 0); - break; - case 3: - event->message = Pm_Message(m->last_command, - cur_packet_data[0], - cur_packet_data[1]); - break; - default: - /* last_msg_length is invalid -- internal PortMIDI error */ - assert(m->last_msg_length == 1); - } - pm_read_short(midi, event); - remaining_length -= (m->last_msg_length - 1); - cur_packet_data += (m->last_msg_length - 1); - } + /* since there's no more data, we're done */ + return; + } + else + { /* output message using running status */ + switch (m->last_msg_length) + { + case 1: + event->message = Pm_Message(m->last_command, 0, 0); + break; + case 2: + event->message = Pm_Message(m->last_command, + cur_packet_data[0], 0); + break; + case 3: + event->message = Pm_Message(m->last_command, + cur_packet_data[0], + cur_packet_data[1]); + break; + default: + /* last_msg_length is invalid -- internal PortMIDI error */ + assert(m->last_msg_length == 1); + } + pm_read_short(midi, event); + remaining_length -= (m->last_msg_length - 1); + cur_packet_data += (m->last_msg_length - 1); + } } } - - /* called when MIDI packets are received */ static void readProc(const MIDIPacketList *newPackets, void *refCon, void *connRefCon) @@ -237,51 +250,56 @@ readProc(const MIDIPacketList *newPackets, void *refCon, void *connRefCon) unsigned int packetIndex; unsigned long now; unsigned int status; - + #ifdef CM_DEBUG printf("readProc: numPackets %d: ", newPackets->numPackets); #endif /* Retrieve the context for this connection */ - midi = (PmInternal *) connRefCon; - m = (midi_macosxcm_type) midi->descriptor; + midi = (PmInternal *)connRefCon; + m = (midi_macosxcm_type)midi->descriptor; assert(m); - + /* synchronize time references every 100ms */ now = (*midi->time_proc)(midi->time_info); - if (m->first_message || m->sync_time + 100 /*ms*/ < now) { + if (m->first_message || m->sync_time + 100 /*ms*/ < now) + { /* time to resync */ now = midi_synchronize(midi); m->first_message = FALSE; } - - packet = (MIDIPacket *) &newPackets->packet[0]; - /* printf("readproc packet status %x length %d\n", packet->data[0], + + packet = (MIDIPacket *)&newPackets->packet[0]; + /* printf("readproc packet status %x length %d\n", packet->data[0], packet->length); */ - for (packetIndex = 0; packetIndex < newPackets->numPackets; packetIndex++) { + for (packetIndex = 0; packetIndex < newPackets->numPackets; packetIndex++) + { /* Set the timestamp and dispatch this message */ - event.timestamp = - (AudioConvertHostTimeToNanos(packet->timeStamp) - m->delta) / - (UInt64) 1000000; + event.timestamp = + (AudioConvertHostTimeToNanos(packet->timeStamp) - m->delta) / + (UInt64)1000000; status = packet->data[0]; /* process packet as sysex data if it begins with MIDI_SYSEX, or MIDI_EOX or non-status byte with no running status */ #ifdef CM_DEBUG printf(" %d", packet->length); #endif - if (status == MIDI_SYSEX || status == MIDI_EOX || - ((!(status & MIDI_STATUS_MASK)) && !m->last_command)) { - /* previously was: !(status & MIDI_STATUS_MASK)) { + if (status == MIDI_SYSEX || status == MIDI_EOX || + ((!(status & MIDI_STATUS_MASK)) && !m->last_command)) + { + /* previously was: !(status & MIDI_STATUS_MASK)) { * but this could mistake running status for sysex data */ /* reset running status data -cpr */ - m->last_command = 0; - m->last_msg_length = 0; + m->last_command = 0; + m->last_msg_length = 0; /* printf("sysex packet length: %d\n", packet->length); */ pm_read_bytes(midi, packet->data, packet->length, event.timestamp); - } else { + } + else + { process_packet(packet, &event, midi, m); - } + } packet = MIDIPacketNext(packet); } #ifdef CM_DEBUG @@ -295,23 +313,26 @@ midi_in_open(PmInternal *midi, void *driverInfo) MIDIEndpointRef endpoint; midi_macosxcm_type m; OSStatus macHostError; - + /* insure that we have a time_proc for timing */ - if (midi->time_proc == NULL) { - if (!Pt_Started()) + if (midi->time_proc == MIDI_NULL) + { + if (!Pt_Started()) Pt_Start(1, 0, 0); /* time_get does not take a parameter, so coerce */ - midi->time_proc = (PmTimeProcPtr) Pt_Time; + midi->time_proc = (PmTimeProcPtr)Pt_Time; } - - endpoint = (MIDIEndpointRef) descriptors[midi->device_id].descriptor; - if (endpoint == NULL) { + + endpoint = (MIDIEndpointRef)descriptors[midi->device_id].descriptor; + if (endpoint == MIDI_NULL) + { return pmInvalidDeviceId; } - m = (midi_macosxcm_type) pm_alloc(sizeof(midi_macosxcm_node)); /* create */ + m = (midi_macosxcm_type)pm_alloc(sizeof(midi_macosxcm_node)); /* create */ midi->descriptor = m; - if (!m) { + if (!m) + { return pmInsufficientMemory; } m->error[0] = 0; @@ -329,16 +350,17 @@ midi_in_open(PmInternal *midi, void *driverInfo) m->last_msg_length = 0; macHostError = MIDIPortConnectSource(portIn, endpoint, midi); - if (macHostError != noErr) { + if (macHostError != noErr) + { pm_hosterror = macHostError; - sprintf(pm_hosterror_text, + sprintf(pm_hosterror_text, "Host error %ld: MIDIPortConnectSource() in midi_in_open()", macHostError); midi->descriptor = NULL; pm_free(m); return pmHostError; } - + return pmNoError; } @@ -348,41 +370,44 @@ midi_in_close(PmInternal *midi) MIDIEndpointRef endpoint; OSStatus macHostError; PmError err = pmNoError; - - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - - if (!m) return pmBadPtr; - endpoint = (MIDIEndpointRef) descriptors[midi->device_id].descriptor; - if (endpoint == NULL) { + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + + if (!m) + return pmBadPtr; + + endpoint = (MIDIEndpointRef)descriptors[midi->device_id].descriptor; + if (endpoint == NULL) + { pm_hosterror = pmBadPtr; } - + /* shut off the incoming messages before freeing data structures */ macHostError = MIDIPortDisconnectSource(portIn, endpoint); - if (macHostError != noErr) { + if (macHostError != noErr) + { pm_hosterror = macHostError; - sprintf(pm_hosterror_text, + sprintf(pm_hosterror_text, "Host error %ld: MIDIPortDisconnectSource() in midi_in_close()", macHostError); err = pmHostError; } - + midi->descriptor = NULL; pm_free(midi->descriptor); - + return err; } - static PmError midi_out_open(PmInternal *midi, void *driverInfo) { midi_macosxcm_type m; - m = (midi_macosxcm_type) pm_alloc(sizeof(midi_macosxcm_node)); /* create */ + m = (midi_macosxcm_type)pm_alloc(sizeof(midi_macosxcm_node)); /* create */ midi->descriptor = m; - if (!m) { + if (!m) + { return pmInsufficientMemory; } m->error[0] = 0; @@ -394,7 +419,7 @@ midi_out_open(PmInternal *midi, void *driverInfo) m->sysex_mode = FALSE; m->sysex_word = 0; m->sysex_byte_count = 0; - m->packetList = (MIDIPacketList *) m->packetBuffer; + m->packetList = (MIDIPacketList *)m->packetBuffer; m->packet = NULL; m->last_command = 0; m->last_msg_length = 0; @@ -402,16 +427,16 @@ midi_out_open(PmInternal *midi, void *driverInfo) return pmNoError; } - static PmError midi_out_close(PmInternal *midi) { - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - if (!m) return pmBadPtr; - + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + if (!m) + return pmBadPtr; + midi->descriptor = NULL; pm_free(midi->descriptor); - + return pmNoError; } @@ -421,61 +446,61 @@ midi_abort(PmInternal *midi) return pmNoError; } - static PmError midi_write_flush(PmInternal *midi, PmTimestamp timestamp) { OSStatus macHostError; - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - MIDIEndpointRef endpoint = - (MIDIEndpointRef) descriptors[midi->device_id].descriptor; + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + MIDIEndpointRef endpoint = + (MIDIEndpointRef)descriptors[midi->device_id].descriptor; assert(m); assert(endpoint); - if (m->packet != NULL) { + if (m->packet != NULL) + { /* out of space, send the buffer and start refilling it */ macHostError = MIDISend(portOut, endpoint, m->packetList); m->packet = NULL; /* indicate no data in packetList now */ - if (macHostError != noErr) goto send_packet_error; + if (macHostError != noErr) + goto send_packet_error; } return pmNoError; - + send_packet_error: pm_hosterror = macHostError; - sprintf(pm_hosterror_text, + sprintf(pm_hosterror_text, "Host error %ld: MIDISend() in midi_write()", macHostError); return pmHostError; - } - static PmError -send_packet(PmInternal *midi, Byte *message, unsigned int messageLength, +send_packet(PmInternal *midi, Byte *message, unsigned int messageLength, MIDITimeStamp timestamp) { PmError err; - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; assert(m); - + /* printf("add %d to packet %lx len %d\n", message[0], m->packet, messageLength); */ - m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), - m->packet, timestamp, messageLength, + m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), + m->packet, timestamp, messageLength, message); - if (m->packet == NULL) { + if (m->packet == NULL) + { /* out of space, send the buffer and start refilling it */ /* make midi->packet non-null to fool midi_write_flush into sending */ - m->packet = (MIDIPacket *) 4; - if ((err = midi_write_flush(midi, timestamp)) != pmNoError) return err; + m->packet = (MIDIPacket *)4; + if ((err = midi_write_flush(midi, timestamp)) != pmNoError) + return err; m->packet = MIDIPacketListInit(m->packetList); assert(m->packet); /* if this fails, it's a programming error */ m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), - m->packet, timestamp, messageLength, + m->packet, timestamp, messageLength, message); - assert(m->packet); /* can't run out of space on first message */ + assert(m->packet); /* can't run out of space on first message */ } return pmNoError; -} - +} static PmError midi_write_short(PmInternal *midi, PmEvent *event) @@ -484,125 +509,136 @@ midi_write_short(PmInternal *midi, PmEvent *event) long what = event->message; MIDITimeStamp timestamp; UInt64 when_ns; - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; Byte message[4]; unsigned int messageLength; - if (m->packet == NULL) { + if (m->packet == NULL) + { m->packet = MIDIPacketListInit(m->packetList); - /* this can never fail, right? failure would indicate something + /* this can never fail, right? failure would indicate something unrecoverable */ assert(m->packet); } - + /* compute timestamp */ - if (when == 0) when = midi->now; + if (when == 0) + when = midi->now; /* if latency == 0, midi->now is not valid. We will just set it to zero */ - if (midi->latency == 0) when = 0; - when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + m->delta; + if (midi->latency == 0) + when = 0; + when_ns = ((UInt64)(when + midi->latency) * (UInt64)1000000) + m->delta; /* make sure we don't go backward in time */ - if (when_ns < m->last_time) when_ns = m->last_time; + if (when_ns < m->last_time) + when_ns = m->last_time; m->last_time = when_ns; - timestamp = (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns); + timestamp = (MIDITimeStamp)AudioConvertNanosToHostTime(when_ns); message[0] = Pm_MessageStatus(what); message[1] = Pm_MessageData1(what); message[2] = Pm_MessageData2(what); messageLength = midi_length(what); - + /* Add this message to the packet list */ return send_packet(midi, message, messageLength, timestamp); } - -static PmError +static PmError midi_begin_sysex(PmInternal *midi, PmTimestamp when) { UInt64 when_ns; - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; assert(m); m->sysex_byte_count = 0; - + /* compute timestamp */ - if (when == 0) when = midi->now; + if (when == 0) + when = midi->now; /* if latency == 0, midi->now is not valid. We will just set it to zero */ - if (midi->latency == 0) when = 0; - when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + m->delta; - m->sysex_timestamp = (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns); + if (midi->latency == 0) + when = 0; + when_ns = ((UInt64)(when + midi->latency) * (UInt64)1000000) + m->delta; + m->sysex_timestamp = (MIDITimeStamp)AudioConvertNanosToHostTime(when_ns); - if (m->packet == NULL) { + if (m->packet == NULL) + { m->packet = MIDIPacketListInit(m->packetList); - /* this can never fail, right? failure would indicate something + /* this can never fail, right? failure would indicate something unrecoverable */ assert(m->packet); } return pmNoError; } - static PmError midi_end_sysex(PmInternal *midi, PmTimestamp when) { PmError err; - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; assert(m); - + /* make sure we don't go backward in time */ - if (m->sysex_timestamp < m->last_time) m->sysex_timestamp = m->last_time; - + if (m->sysex_timestamp < m->last_time) + m->sysex_timestamp = m->last_time; + /* now send what's in the buffer */ err = send_packet(midi, m->sysex_buffer, m->sysex_byte_count, m->sysex_timestamp); m->sysex_byte_count = 0; - if (err != pmNoError) { + if (err != pmNoError) + { m->packet = NULL; /* flush everything in the packet list */ return err; } return pmNoError; } - static PmError midi_write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp) { - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; assert(m); - if (m->sysex_byte_count >= SYSEX_BUFFER_SIZE) { + if (m->sysex_byte_count >= SYSEX_BUFFER_SIZE) + { PmError err = midi_end_sysex(midi, timestamp); - if (err != pmNoError) return err; + if (err != pmNoError) + return err; } m->sysex_buffer[m->sysex_byte_count++] = byte; return pmNoError; } - static PmError midi_write_realtime(PmInternal *midi, PmEvent *event) { /* to send a realtime message during a sysex message, first flush all pending sysex bytes into packet list */ PmError err = midi_end_sysex(midi, 0); - if (err != pmNoError) return err; + if (err != pmNoError) + return err; /* then we can just do a normal midi_write_short */ return midi_write_short(midi, event); } static unsigned int midi_has_host_error(PmInternal *midi) { - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; return (m->callback_error[0] != 0) || (m->error[0] != 0); } - static void midi_get_host_error(PmInternal *midi, char *msg, unsigned int len) { - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; msg[0] = 0; /* initialize to empty string */ - if (m) { /* make sure there is an open device to examine */ - if (m->error[0]) { + if (m) + { /* make sure there is an open device to examine */ + if (m->error[0]) + { strncpy(msg, m->error, len); m->error[0] = 0; /* clear the error */ - } else if (m->callback_error[0]) { + } + else if (m->callback_error[0]) + { strncpy(msg, m->callback_error, len); m->callback_error[0] = 0; /* clear the error */ } @@ -610,13 +646,15 @@ static void midi_get_host_error(PmInternal *midi, char *msg, unsigned int len) } } - MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) { UInt64 nanos; - if (timestamp <= 0) { + if (timestamp <= 0) + { return (MIDITimeStamp)0; - } else { + } + else + { nanos = (UInt64)timestamp * (UInt64)1000000; return (MIDITimeStamp)AudioConvertNanosToHostTime(nanos); } @@ -629,7 +667,6 @@ PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp) return (PmTimestamp)(nanos / (UInt64)1000000); } - // // Code taken from http://developer.apple.com/qa/qa2004/qa1374.html ////////////////////////////////////// @@ -637,129 +674,146 @@ PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp) // The result should be released by the caller. 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 + CFMutableStringRef result = CFStringCreateMutable(NULL, 0); + CFStringRef str; + + // begin with the endpoint's name 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 (CFStringGetLength(result) == 0) { - CFRelease(result); - return 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 { - if (CFStringGetLength(str) == 0) { + MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &str); + if (str != NULL) + { + CFStringAppend(result, str); CFRelease(str); + } + + MIDIEntityRef entity = MIDI_NULL; + MIDIEndpointGetEntity(endpoint, &entity); + if (INT2VOIDP(entity) == NULL) + // probably virtual return result; - } - // 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( result, /* endpoint name */ - str /* device 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; -} + 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 = MIDI_NULL; + MIDIEntityGetDevice(entity, &device); + if (device == MIDI_NULL) + return result; + + str = NULL; + MIDIObjectGetStringProperty(device, kMIDIPropertyName, &str); + if (CFStringGetLength(result) == 0) + { + CFRelease(result); + return 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 + { + if (CFStringGetLength(str) == 0) + { + CFRelease(str); + return result; + } + // 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(result, /* endpoint name */ + str /* device 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; +} // 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; - int i; - - // 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 = (const SInt32 *)(CFDataGetBytePtr(connections)); - for (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((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); - } + CFMutableStringRef result = CFStringCreateMutable(NULL, 0); + CFStringRef str; + OSStatus err; + int i; + + // 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 = (const SInt32 *)(CFDataGetBytePtr(connections)); + for (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((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); } - 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); -} + 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); +} -char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint) +char *cm_get_full_endpoint_name(MIDIEndpointRef endpoint) { #ifdef OLDCODE MIDIEntityRef entity; @@ -770,13 +824,13 @@ char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint) #endif CFStringRef fullName = NULL; CFStringEncoding defaultEncoding; - char* newName; + char *newName; /* get the default string encoding */ defaultEncoding = CFStringGetSystemEncoding(); fullName = ConnectedEndpointName(endpoint); - + #ifdef OLDCODE /* get the entity and device info */ MIDIEndpointGetEntity(endpoint, &entity); @@ -785,30 +839,34 @@ char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint) /* create the nicely formated name */ MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &endpointName); MIDIObjectGetStringProperty(device, kMIDIPropertyName, &deviceName); - if (deviceName != NULL) { + if (deviceName != NULL) + { fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@: %@"), deviceName, endpointName); - } else { + } + else + { fullName = endpointName; } -#endif +#endif /* copy the string into our buffer */ - newName = (char *) malloc(CFStringGetLength(fullName) + 1); + newName = (char *)malloc(CFStringGetLength(fullName) + 1); CFStringGetCString(fullName, newName, CFStringGetLength(fullName) + 1, defaultEncoding); /* clean up */ #ifdef OLDCODE - if (endpointName) CFRelease(endpointName); - if (deviceName) CFRelease(deviceName); + if (endpointName) + CFRelease(endpointName); + if (deviceName) + CFRelease(deviceName); #endif - if (fullName) CFRelease(fullName); + if (fullName) + CFRelease(fullName); return newName; } - - pm_fns_node pm_macosx_in_dictionary = { none_write_short, none_sysex, @@ -841,7 +899,6 @@ pm_fns_node pm_macosx_out_dictionary = { midi_get_host_error, }; - PmError pm_macosxcm_init(void) { ItemCount numInputs, numOutputs, numDevices; @@ -860,53 +917,60 @@ PmError pm_macosxcm_init(void) Pm_CountDevices() will return zero, which is correct and useful information */ - if (numDevices <= 0) { + if (numDevices <= 0) + { return pmNoError; } - /* Initialize the client handle */ macHostError = MIDIClientCreate(CFSTR("PortMidi"), NULL, NULL, &client); - if (macHostError != noErr) { + if (macHostError != noErr) + { error_text = "MIDIClientCreate() in pm_macosxcm_init()"; goto error_return; } /* Create the input port */ macHostError = MIDIInputPortCreate(client, CFSTR("Input port"), readProc, - NULL, &portIn); - if (macHostError != noErr) { + NULL, &portIn); + if (macHostError != noErr) + { error_text = "MIDIInputPortCreate() in pm_macosxcm_init()"; goto error_return; } - + /* Create the output port */ macHostError = MIDIOutputPortCreate(client, CFSTR("Output port"), &portOut); - if (macHostError != noErr) { + if (macHostError != noErr) + { error_text = "MIDIOutputPortCreate() in pm_macosxcm_init()"; goto error_return; } /* Iterate over the MIDI input devices */ - for (i = 0; i < numInputs; i++) { + for (i = 0; i < numInputs; i++) + { endpoint = MIDIGetSource(i); - if (endpoint == NULL) { + if (endpoint == MIDI_NULL) + { continue; } /* set the first input we see to the default */ if (pm_default_input_device_id == -1) pm_default_input_device_id = pm_descriptor_index; - + /* Register this device with PortMidi */ pm_add_device("CoreMIDI", cm_get_full_endpoint_name(endpoint), - TRUE, (void*)endpoint, &pm_macosx_in_dictionary); + TRUE, (void *)INT2VOIDP(endpoint), &pm_macosx_in_dictionary); } /* Iterate over the MIDI output devices */ - for (i = 0; i < numOutputs; i++) { + for (i = 0; i < numOutputs; i++) + { endpoint = MIDIGetDestination(i); - if (endpoint == NULL) { + if (endpoint == MIDI_NULL) + { continue; } @@ -916,10 +980,10 @@ PmError pm_macosxcm_init(void) /* Register this device with PortMidi */ pm_add_device("CoreMIDI", cm_get_full_endpoint_name(endpoint), - FALSE, (void*)endpoint, &pm_macosx_out_dictionary); + FALSE, (void *)INT2VOIDP(endpoint), &pm_macosx_out_dictionary); } return pmNoError; - + error_return: pm_hosterror = macHostError; sprintf(pm_hosterror_text, "Host error %ld: %s\n", macHostError, error_text); @@ -929,7 +993,10 @@ PmError pm_macosxcm_init(void) void pm_macosxcm_term(void) { - if (client != NULL) MIDIClientDispose(client); - if (portIn != NULL) MIDIPortDispose(portIn); - if (portOut != NULL) MIDIPortDispose(portOut); + if (client != MIDI_NULL) + MIDIClientDispose(client); + if (portIn != MIDI_NULL) + MIDIPortDispose(portIn); + if (portOut != MIDI_NULL) + MIDIPortDispose(portOut); } From ea55f3022ff59c7c9e2321224587e29c72e80721 Mon Sep 17 00:00:00 2001 From: Jim Snavely Date: Tue, 6 Aug 2024 19:26:21 -0400 Subject: [PATCH 2/2] remove formatting changes --- portmidi/pm_mac/pmmacosxcm.c | 769 ++++++++++++++++------------------- 1 file changed, 352 insertions(+), 417 deletions(-) diff --git a/portmidi/pm_mac/pmmacosxcm.c b/portmidi/pm_mac/pmmacosxcm.c index bf381ba..b5d76aa 100644 --- a/portmidi/pm_mac/pmmacosxcm.c +++ b/portmidi/pm_mac/pmmacosxcm.c @@ -1,13 +1,13 @@ /* * Platform interface to the MacOS X CoreMIDI framework - * + * * Jon Parise * and subsequent work by Andrew Zeldis and Zico Kolter * and Roger B. Dannenberg * * $Id: pmmacosx.c,v 1.17 2002/01/27 02:40:40 jon Exp $ */ - + /* Notes: since the input and output streams are represented by MIDIEndpointRef values and almost no other state, we store the MIDIEndpointRef on @@ -16,14 +16,14 @@ the error text. We use a structure with two kinds of host error: "error" and "callback_error". That way, asynchronous callbacks do not interfere with other error information. - + OS X does not seem to have an error-code-to-text function, so we will just use text messages instead of error codes. */ #include -// #define CM_DEBUG 1 +//#define CM_DEBUG 1 #include "portmidi.h" #include "pmutil.h" @@ -41,7 +41,7 @@ #define PACKET_BUFFER_SIZE 1024 -/* this is very strange: if I put in a reasonable +/* this is very strange: if I put in a reasonable number here, e.g. 128, which would allow sysex data to be sent 128 bytes at a time, then I lose sysex data in my loopback test. With a buffer size of 4, @@ -53,8 +53,8 @@ #define VERBOSE_ON 1 #define VERBOSE if (VERBOSE_ON) -#define MIDI_SYSEX 0xf0 -#define MIDI_EOX 0xf7 +#define MIDI_SYSEX 0xf0 +#define MIDI_EOX 0xf7 #define MIDI_STATUS_MASK 0x80 #define MIDI_NULL 0 #define INT2VOIDP(i) (void *)(uintptr_t)(i) @@ -66,14 +66,13 @@ static MIDIPortRef portOut = MIDI_NULL; /* Output port handle */ extern pm_fns_node pm_macosx_in_dictionary; extern pm_fns_node pm_macosx_out_dictionary; -typedef struct midi_macosxcm_struct -{ - unsigned long sync_time; /* when did we last determine delta? */ - UInt64 delta; /* difference between stream time and real time in ns */ - UInt64 last_time; /* last output time */ - int first_message; /* tells midi_write to sychronize timestamps */ - int sysex_mode; /* middle of sending sysex */ - unsigned long sysex_word; /* accumulate data when receiving sysex */ +typedef struct midi_macosxcm_struct { + unsigned long sync_time; /* when did we last determine delta? */ + UInt64 delta; /* difference between stream time and real time in ns */ + UInt64 last_time; /* last output time */ + int first_message; /* tells midi_write to sychronize timestamps */ + int sysex_mode; /* middle of sending sysex */ + unsigned long sysex_word; /* accumulate data when receiving sysex */ unsigned int sysex_byte_count; /* count how many received */ char error[PM_HOST_ERROR_MSG_LEN]; char callback_error[PM_HOST_ERROR_MSG_LEN]; @@ -81,9 +80,9 @@ typedef struct midi_macosxcm_struct MIDIPacketList *packetList; /* a pointer to packetBuffer */ MIDIPacket *packet; Byte sysex_buffer[SYSEX_BUFFER_SIZE]; /* temp storage for sysex data */ - MIDITimeStamp sysex_timestamp; /* timestamp to use with sysex data */ + MIDITimeStamp sysex_timestamp; /* timestamp to use with sysex data */ /* allow for running status (is running status possible here? -rbd): -cpr */ - unsigned char last_command; + unsigned char last_command; long last_msg_length; } midi_macosxcm_node, *midi_macosxcm_type; @@ -91,19 +90,20 @@ typedef struct midi_macosxcm_struct MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp); PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp); -char *cm_get_full_endpoint_name(MIDIEndpointRef endpoint); +char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint); + static int midi_length(long msg) { int status, high, low; static int high_lengths[] = { - 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 through 0x70 */ - 3, 3, 3, 3, 2, 2, 3, 1 /* 0x80 through 0xf0 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 through 0x70 */ + 3, 3, 3, 3, 2, 2, 3, 1 /* 0x80 through 0xf0 */ }; static int low_lengths[] = { - 1, 2, 3, 2, 1, 1, 1, 1, /* 0xf0 through 0xf8 */ - 1, 1, 1, 1, 1, 1, 1, 1 /* 0xf9 through 0xff */ + 1, 2, 3, 2, 1, 1, 1, 1, /* 0xf0 through 0xf8 */ + 1, 1, 1, 1, 1, 1, 1, 1 /* 0xf9 through 0xff */ }; status = msg & 0xFF; @@ -115,130 +115,119 @@ midi_length(long msg) static PmTimestamp midi_synchronize(PmInternal *midi) { - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; - UInt64 pm_stream_time_2 = - AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + UInt64 pm_stream_time_2 = + AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); PmTimestamp real_time; UInt64 pm_stream_time; - /* if latency is zero and this is an output, there is no + /* if latency is zero and this is an output, there is no time reference and midi_synchronize should never be called */ assert(midi->time_proc); assert(!(midi->write_flag && midi->latency == 0)); - do - { - /* read real_time between two reads of stream time */ - pm_stream_time = pm_stream_time_2; - real_time = (*midi->time_proc)(midi->time_info); - pm_stream_time_2 = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); - /* repeat if more than 0.5 ms has elapsed */ + do { + /* read real_time between two reads of stream time */ + pm_stream_time = pm_stream_time_2; + real_time = (*midi->time_proc)(midi->time_info); + pm_stream_time_2 = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); + /* repeat if more than 0.5 ms has elapsed */ } while (pm_stream_time_2 > pm_stream_time + 500000); - m->delta = pm_stream_time - ((UInt64)real_time * (UInt64)1000000); + m->delta = pm_stream_time - ((UInt64) real_time * (UInt64) 1000000); m->sync_time = real_time; return real_time; } + static void -process_packet(MIDIPacket *packet, PmEvent *event, - PmInternal *midi, midi_macosxcm_type m) +process_packet(MIDIPacket *packet, PmEvent *event, + PmInternal *midi, midi_macosxcm_type m) { /* handle a packet of MIDI messages from CoreMIDI */ /* there may be multiple short messages in one packet (!) */ unsigned int remaining_length = packet->length; unsigned char *cur_packet_data = packet->data; - while (remaining_length > 0) - { + while (remaining_length > 0) { if (cur_packet_data[0] == MIDI_SYSEX || /* are we in the middle of a sysex message? */ (m->last_command == 0 && - !(cur_packet_data[0] & MIDI_STATUS_MASK))) - { + !(cur_packet_data[0] & MIDI_STATUS_MASK))) { m->last_command = 0; /* no running status */ - unsigned int amt = pm_read_bytes(midi, cur_packet_data, - remaining_length, + unsigned int amt = pm_read_bytes(midi, cur_packet_data, + remaining_length, event->timestamp); remaining_length -= amt; cur_packet_data += amt; - } - else if (cur_packet_data[0] == MIDI_EOX) - { + } else if (cur_packet_data[0] == MIDI_EOX) { /* this should never happen, because pm_read_bytes should * get and read all EOX bytes*/ midi->sysex_in_progress = FALSE; m->last_command = 0; - } - else if (cur_packet_data[0] & MIDI_STATUS_MASK) - { + } else if (cur_packet_data[0] & MIDI_STATUS_MASK) { /* compute the length of the next (short) msg in packet */ - unsigned int cur_message_length = midi_length(cur_packet_data[0]); - if (cur_message_length > remaining_length) - { + unsigned int cur_message_length = midi_length(cur_packet_data[0]); + if (cur_message_length > remaining_length) { #ifdef DEBUG printf("PortMidi debug msg: not enough data"); #endif - /* since there's no more data, we're done */ - return; - } - m->last_msg_length = cur_message_length; - m->last_command = cur_packet_data[0]; - switch (cur_message_length) - { - case 1: - event->message = Pm_Message(cur_packet_data[0], 0, 0); - break; - case 2: - event->message = Pm_Message(cur_packet_data[0], - cur_packet_data[1], 0); - break; - case 3: - event->message = Pm_Message(cur_packet_data[0], - cur_packet_data[1], - cur_packet_data[2]); - break; - default: + /* since there's no more data, we're done */ + return; + } + m->last_msg_length = cur_message_length; + m->last_command = cur_packet_data[0]; + switch (cur_message_length) { + case 1: + event->message = Pm_Message(cur_packet_data[0], 0, 0); + break; + case 2: + event->message = Pm_Message(cur_packet_data[0], + cur_packet_data[1], 0); + break; + case 3: + event->message = Pm_Message(cur_packet_data[0], + cur_packet_data[1], + cur_packet_data[2]); + break; + default: /* PortMIDI internal error; should never happen */ assert(cur_message_length == 1); - return; /* give up on packet if continued after assert */ - } - pm_read_short(midi, event); - remaining_length -= m->last_msg_length; - cur_packet_data += m->last_msg_length; - } - else if (m->last_msg_length > remaining_length + 1) - { - /* we have running status, but not enough data */ + return; /* give up on packet if continued after assert */ + } + pm_read_short(midi, event); + remaining_length -= m->last_msg_length; + cur_packet_data += m->last_msg_length; + } else if (m->last_msg_length > remaining_length + 1) { + /* we have running status, but not enough data */ #ifdef DEBUG - printf("PortMidi debug msg: not enough data in CoreMIDI packet"); + printf("PortMidi debug msg: not enough data in CoreMIDI packet"); #endif - /* since there's no more data, we're done */ - return; - } - else - { /* output message using running status */ - switch (m->last_msg_length) - { - case 1: - event->message = Pm_Message(m->last_command, 0, 0); - break; - case 2: - event->message = Pm_Message(m->last_command, - cur_packet_data[0], 0); - break; - case 3: - event->message = Pm_Message(m->last_command, - cur_packet_data[0], - cur_packet_data[1]); - break; - default: - /* last_msg_length is invalid -- internal PortMIDI error */ - assert(m->last_msg_length == 1); - } - pm_read_short(midi, event); - remaining_length -= (m->last_msg_length - 1); - cur_packet_data += (m->last_msg_length - 1); - } + /* since there's no more data, we're done */ + return; + } else { /* output message using running status */ + switch (m->last_msg_length) { + case 1: + event->message = Pm_Message(m->last_command, 0, 0); + break; + case 2: + event->message = Pm_Message(m->last_command, + cur_packet_data[0], 0); + break; + case 3: + event->message = Pm_Message(m->last_command, + cur_packet_data[0], + cur_packet_data[1]); + break; + default: + /* last_msg_length is invalid -- internal PortMIDI error */ + assert(m->last_msg_length == 1); + } + pm_read_short(midi, event); + remaining_length -= (m->last_msg_length - 1); + cur_packet_data += (m->last_msg_length - 1); + } } } + + /* called when MIDI packets are received */ static void readProc(const MIDIPacketList *newPackets, void *refCon, void *connRefCon) @@ -250,56 +239,51 @@ readProc(const MIDIPacketList *newPackets, void *refCon, void *connRefCon) unsigned int packetIndex; unsigned long now; unsigned int status; - + #ifdef CM_DEBUG printf("readProc: numPackets %d: ", newPackets->numPackets); #endif /* Retrieve the context for this connection */ - midi = (PmInternal *)connRefCon; - m = (midi_macosxcm_type)midi->descriptor; + midi = (PmInternal *) connRefCon; + m = (midi_macosxcm_type) midi->descriptor; assert(m); - + /* synchronize time references every 100ms */ now = (*midi->time_proc)(midi->time_info); - if (m->first_message || m->sync_time + 100 /*ms*/ < now) - { + if (m->first_message || m->sync_time + 100 /*ms*/ < now) { /* time to resync */ now = midi_synchronize(midi); m->first_message = FALSE; } - - packet = (MIDIPacket *)&newPackets->packet[0]; - /* printf("readproc packet status %x length %d\n", packet->data[0], + + packet = (MIDIPacket *) &newPackets->packet[0]; + /* printf("readproc packet status %x length %d\n", packet->data[0], packet->length); */ - for (packetIndex = 0; packetIndex < newPackets->numPackets; packetIndex++) - { + for (packetIndex = 0; packetIndex < newPackets->numPackets; packetIndex++) { /* Set the timestamp and dispatch this message */ - event.timestamp = - (AudioConvertHostTimeToNanos(packet->timeStamp) - m->delta) / - (UInt64)1000000; + event.timestamp = + (AudioConvertHostTimeToNanos(packet->timeStamp) - m->delta) / + (UInt64) 1000000; status = packet->data[0]; /* process packet as sysex data if it begins with MIDI_SYSEX, or MIDI_EOX or non-status byte with no running status */ #ifdef CM_DEBUG printf(" %d", packet->length); #endif - if (status == MIDI_SYSEX || status == MIDI_EOX || - ((!(status & MIDI_STATUS_MASK)) && !m->last_command)) - { - /* previously was: !(status & MIDI_STATUS_MASK)) { + if (status == MIDI_SYSEX || status == MIDI_EOX || + ((!(status & MIDI_STATUS_MASK)) && !m->last_command)) { + /* previously was: !(status & MIDI_STATUS_MASK)) { * but this could mistake running status for sysex data */ /* reset running status data -cpr */ - m->last_command = 0; - m->last_msg_length = 0; + m->last_command = 0; + m->last_msg_length = 0; /* printf("sysex packet length: %d\n", packet->length); */ pm_read_bytes(midi, packet->data, packet->length, event.timestamp); - } - else - { + } else { process_packet(packet, &event, midi, m); - } + } packet = MIDIPacketNext(packet); } #ifdef CM_DEBUG @@ -313,26 +297,23 @@ midi_in_open(PmInternal *midi, void *driverInfo) MIDIEndpointRef endpoint; midi_macosxcm_type m; OSStatus macHostError; - + /* insure that we have a time_proc for timing */ - if (midi->time_proc == MIDI_NULL) - { - if (!Pt_Started()) + if (midi->time_proc == NULL) { + if (!Pt_Started()) Pt_Start(1, 0, 0); /* time_get does not take a parameter, so coerce */ - midi->time_proc = (PmTimeProcPtr)Pt_Time; + midi->time_proc = (PmTimeProcPtr) Pt_Time; } - - endpoint = (MIDIEndpointRef)descriptors[midi->device_id].descriptor; - if (endpoint == MIDI_NULL) - { + + endpoint = (MIDIEndpointRef) descriptors[midi->device_id].descriptor; + if (endpoint == NULL) { return pmInvalidDeviceId; } - m = (midi_macosxcm_type)pm_alloc(sizeof(midi_macosxcm_node)); /* create */ + m = (midi_macosxcm_type) pm_alloc(sizeof(midi_macosxcm_node)); /* create */ midi->descriptor = m; - if (!m) - { + if (!m) { return pmInsufficientMemory; } m->error[0] = 0; @@ -350,17 +331,16 @@ midi_in_open(PmInternal *midi, void *driverInfo) m->last_msg_length = 0; macHostError = MIDIPortConnectSource(portIn, endpoint, midi); - if (macHostError != noErr) - { + if (macHostError != noErr) { pm_hosterror = macHostError; - sprintf(pm_hosterror_text, + sprintf(pm_hosterror_text, "Host error %ld: MIDIPortConnectSource() in midi_in_open()", macHostError); midi->descriptor = NULL; pm_free(m); return pmHostError; } - + return pmNoError; } @@ -370,44 +350,41 @@ midi_in_close(PmInternal *midi) MIDIEndpointRef endpoint; OSStatus macHostError; PmError err = pmNoError; + + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + + if (!m) return pmBadPtr; - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; - - if (!m) - return pmBadPtr; - - endpoint = (MIDIEndpointRef)descriptors[midi->device_id].descriptor; - if (endpoint == NULL) - { + endpoint = (MIDIEndpointRef) descriptors[midi->device_id].descriptor; + if (endpoint == NULL) { pm_hosterror = pmBadPtr; } - + /* shut off the incoming messages before freeing data structures */ macHostError = MIDIPortDisconnectSource(portIn, endpoint); - if (macHostError != noErr) - { + if (macHostError != noErr) { pm_hosterror = macHostError; - sprintf(pm_hosterror_text, + sprintf(pm_hosterror_text, "Host error %ld: MIDIPortDisconnectSource() in midi_in_close()", macHostError); err = pmHostError; } - + midi->descriptor = NULL; pm_free(midi->descriptor); - + return err; } + static PmError midi_out_open(PmInternal *midi, void *driverInfo) { midi_macosxcm_type m; - m = (midi_macosxcm_type)pm_alloc(sizeof(midi_macosxcm_node)); /* create */ + m = (midi_macosxcm_type) pm_alloc(sizeof(midi_macosxcm_node)); /* create */ midi->descriptor = m; - if (!m) - { + if (!m) { return pmInsufficientMemory; } m->error[0] = 0; @@ -419,7 +396,7 @@ midi_out_open(PmInternal *midi, void *driverInfo) m->sysex_mode = FALSE; m->sysex_word = 0; m->sysex_byte_count = 0; - m->packetList = (MIDIPacketList *)m->packetBuffer; + m->packetList = (MIDIPacketList *) m->packetBuffer; m->packet = NULL; m->last_command = 0; m->last_msg_length = 0; @@ -427,16 +404,16 @@ midi_out_open(PmInternal *midi, void *driverInfo) return pmNoError; } + static PmError midi_out_close(PmInternal *midi) { - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; - if (!m) - return pmBadPtr; - + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + if (!m) return pmBadPtr; + midi->descriptor = NULL; pm_free(midi->descriptor); - + return pmNoError; } @@ -446,61 +423,61 @@ midi_abort(PmInternal *midi) return pmNoError; } + static PmError midi_write_flush(PmInternal *midi, PmTimestamp timestamp) { OSStatus macHostError; - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; - MIDIEndpointRef endpoint = - (MIDIEndpointRef)descriptors[midi->device_id].descriptor; + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; + MIDIEndpointRef endpoint = + (MIDIEndpointRef) descriptors[midi->device_id].descriptor; assert(m); assert(endpoint); - if (m->packet != NULL) - { + if (m->packet != NULL) { /* out of space, send the buffer and start refilling it */ macHostError = MIDISend(portOut, endpoint, m->packetList); m->packet = NULL; /* indicate no data in packetList now */ - if (macHostError != noErr) - goto send_packet_error; + if (macHostError != noErr) goto send_packet_error; } return pmNoError; - + send_packet_error: pm_hosterror = macHostError; - sprintf(pm_hosterror_text, + sprintf(pm_hosterror_text, "Host error %ld: MIDISend() in midi_write()", macHostError); return pmHostError; + } + static PmError -send_packet(PmInternal *midi, Byte *message, unsigned int messageLength, +send_packet(PmInternal *midi, Byte *message, unsigned int messageLength, MIDITimeStamp timestamp) { PmError err; - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; assert(m); - + /* printf("add %d to packet %lx len %d\n", message[0], m->packet, messageLength); */ - m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), - m->packet, timestamp, messageLength, + m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), + m->packet, timestamp, messageLength, message); - if (m->packet == NULL) - { + if (m->packet == NULL) { /* out of space, send the buffer and start refilling it */ /* make midi->packet non-null to fool midi_write_flush into sending */ - m->packet = (MIDIPacket *)4; - if ((err = midi_write_flush(midi, timestamp)) != pmNoError) - return err; + m->packet = (MIDIPacket *) 4; + if ((err = midi_write_flush(midi, timestamp)) != pmNoError) return err; m->packet = MIDIPacketListInit(m->packetList); assert(m->packet); /* if this fails, it's a programming error */ m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), - m->packet, timestamp, messageLength, + m->packet, timestamp, messageLength, message); - assert(m->packet); /* can't run out of space on first message */ + assert(m->packet); /* can't run out of space on first message */ } return pmNoError; -} +} + static PmError midi_write_short(PmInternal *midi, PmEvent *event) @@ -509,136 +486,125 @@ midi_write_short(PmInternal *midi, PmEvent *event) long what = event->message; MIDITimeStamp timestamp; UInt64 when_ns; - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; Byte message[4]; unsigned int messageLength; - if (m->packet == NULL) - { + if (m->packet == NULL) { m->packet = MIDIPacketListInit(m->packetList); - /* this can never fail, right? failure would indicate something + /* this can never fail, right? failure would indicate something unrecoverable */ assert(m->packet); } - + /* compute timestamp */ - if (when == 0) - when = midi->now; + if (when == 0) when = midi->now; /* if latency == 0, midi->now is not valid. We will just set it to zero */ - if (midi->latency == 0) - when = 0; - when_ns = ((UInt64)(when + midi->latency) * (UInt64)1000000) + m->delta; + if (midi->latency == 0) when = 0; + when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + m->delta; /* make sure we don't go backward in time */ - if (when_ns < m->last_time) - when_ns = m->last_time; + if (when_ns < m->last_time) when_ns = m->last_time; m->last_time = when_ns; - timestamp = (MIDITimeStamp)AudioConvertNanosToHostTime(when_ns); + timestamp = (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns); message[0] = Pm_MessageStatus(what); message[1] = Pm_MessageData1(what); message[2] = Pm_MessageData2(what); messageLength = midi_length(what); - + /* Add this message to the packet list */ return send_packet(midi, message, messageLength, timestamp); } -static PmError + +static PmError midi_begin_sysex(PmInternal *midi, PmTimestamp when) { UInt64 when_ns; - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; assert(m); m->sysex_byte_count = 0; - + /* compute timestamp */ - if (when == 0) - when = midi->now; + if (when == 0) when = midi->now; /* if latency == 0, midi->now is not valid. We will just set it to zero */ - if (midi->latency == 0) - when = 0; - when_ns = ((UInt64)(when + midi->latency) * (UInt64)1000000) + m->delta; - m->sysex_timestamp = (MIDITimeStamp)AudioConvertNanosToHostTime(when_ns); + if (midi->latency == 0) when = 0; + when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + m->delta; + m->sysex_timestamp = (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns); - if (m->packet == NULL) - { + if (m->packet == NULL) { m->packet = MIDIPacketListInit(m->packetList); - /* this can never fail, right? failure would indicate something + /* this can never fail, right? failure would indicate something unrecoverable */ assert(m->packet); } return pmNoError; } + static PmError midi_end_sysex(PmInternal *midi, PmTimestamp when) { PmError err; - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; assert(m); - + /* make sure we don't go backward in time */ - if (m->sysex_timestamp < m->last_time) - m->sysex_timestamp = m->last_time; - + if (m->sysex_timestamp < m->last_time) m->sysex_timestamp = m->last_time; + /* now send what's in the buffer */ err = send_packet(midi, m->sysex_buffer, m->sysex_byte_count, m->sysex_timestamp); m->sysex_byte_count = 0; - if (err != pmNoError) - { + if (err != pmNoError) { m->packet = NULL; /* flush everything in the packet list */ return err; } return pmNoError; } + static PmError midi_write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp) { - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; assert(m); - if (m->sysex_byte_count >= SYSEX_BUFFER_SIZE) - { + if (m->sysex_byte_count >= SYSEX_BUFFER_SIZE) { PmError err = midi_end_sysex(midi, timestamp); - if (err != pmNoError) - return err; + if (err != pmNoError) return err; } m->sysex_buffer[m->sysex_byte_count++] = byte; return pmNoError; } + static PmError midi_write_realtime(PmInternal *midi, PmEvent *event) { /* to send a realtime message during a sysex message, first flush all pending sysex bytes into packet list */ PmError err = midi_end_sysex(midi, 0); - if (err != pmNoError) - return err; + if (err != pmNoError) return err; /* then we can just do a normal midi_write_short */ return midi_write_short(midi, event); } static unsigned int midi_has_host_error(PmInternal *midi) { - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; return (m->callback_error[0] != 0) || (m->error[0] != 0); } + static void midi_get_host_error(PmInternal *midi, char *msg, unsigned int len) { - midi_macosxcm_type m = (midi_macosxcm_type)midi->descriptor; + midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; msg[0] = 0; /* initialize to empty string */ - if (m) - { /* make sure there is an open device to examine */ - if (m->error[0]) - { + if (m) { /* make sure there is an open device to examine */ + if (m->error[0]) { strncpy(msg, m->error, len); m->error[0] = 0; /* clear the error */ - } - else if (m->callback_error[0]) - { + } else if (m->callback_error[0]) { strncpy(msg, m->callback_error, len); m->callback_error[0] = 0; /* clear the error */ } @@ -646,15 +612,13 @@ static void midi_get_host_error(PmInternal *midi, char *msg, unsigned int len) } } + MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) { UInt64 nanos; - if (timestamp <= 0) - { + if (timestamp <= 0) { return (MIDITimeStamp)0; - } - else - { + } else { nanos = (UInt64)timestamp * (UInt64)1000000; return (MIDITimeStamp)AudioConvertNanosToHostTime(nanos); } @@ -667,6 +631,7 @@ PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp) return (PmTimestamp)(nanos / (UInt64)1000000); } + // // Code taken from http://developer.apple.com/qa/qa2004/qa1374.html ////////////////////////////////////// @@ -674,146 +639,129 @@ PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp) // The result should be released by the caller. CFStringRef EndpointName(MIDIEndpointRef endpoint, bool isExternal) { - CFMutableStringRef result = CFStringCreateMutable(NULL, 0); - CFStringRef str; - - // begin with the endpoint's name + 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 = MIDI_NULL; + MIDIEndpointGetEntity(endpoint, &entity); + if (entity == MIDI_NULL) + // probably virtual + return result; + + if (CFStringGetLength(result) == 0) { + // endpoint name has zero length -- try the entity str = NULL; - MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &str); - if (str != NULL) - { - CFStringAppend(result, str); + MIDIObjectGetStringProperty(entity, kMIDIPropertyName, &str); + if (str != NULL) { + CFStringAppend(result, str); + CFRelease(str); + } + } + // now consider the device's name + MIDIDeviceRef device = MIDI_NULL; + MIDIEntityGetDevice(entity, &device); + if (device == MIDI_NULL) + return result; + + str = NULL; + MIDIObjectGetStringProperty(device, kMIDIPropertyName, &str); + if (CFStringGetLength(result) == 0) { + CFRelease(result); + return 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 { + if (CFStringGetLength(str) == 0) { CFRelease(str); - } - - MIDIEntityRef entity = MIDI_NULL; - MIDIEndpointGetEntity(endpoint, &entity); - if (INT2VOIDP(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 = MIDI_NULL; - MIDIEntityGetDevice(entity, &device); - if (device == MIDI_NULL) - return result; - - str = NULL; - MIDIObjectGetStringProperty(device, kMIDIPropertyName, &str); - if (CFStringGetLength(result) == 0) - { - CFRelease(result); - return 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 - { - if (CFStringGetLength(str) == 0) - { - CFRelease(str); - return result; - } - // 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(result, /* endpoint name */ - str /* device 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; + } + // 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( result, /* endpoint name */ + str /* device 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; } + // 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; - int i; - - // 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 = (const SInt32 *)(CFDataGetBytePtr(connections)); - for (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((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); - } - } - } + CFMutableStringRef result = CFStringCreateMutable(NULL, 0); + CFStringRef str; + OSStatus err; + int i; + + // 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 = (const SInt32 *)(CFDataGetBytePtr(connections)); + for (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((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); + 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); } -char *cm_get_full_endpoint_name(MIDIEndpointRef endpoint) + +char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint) { #ifdef OLDCODE MIDIEntityRef entity; @@ -824,13 +772,13 @@ char *cm_get_full_endpoint_name(MIDIEndpointRef endpoint) #endif CFStringRef fullName = NULL; CFStringEncoding defaultEncoding; - char *newName; + char* newName; /* get the default string encoding */ defaultEncoding = CFStringGetSystemEncoding(); fullName = ConnectedEndpointName(endpoint); - + #ifdef OLDCODE /* get the entity and device info */ MIDIEndpointGetEntity(endpoint, &entity); @@ -839,34 +787,30 @@ char *cm_get_full_endpoint_name(MIDIEndpointRef endpoint) /* create the nicely formated name */ MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &endpointName); MIDIObjectGetStringProperty(device, kMIDIPropertyName, &deviceName); - if (deviceName != NULL) - { + if (deviceName != NULL) { fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@: %@"), deviceName, endpointName); - } - else - { + } else { fullName = endpointName; } -#endif +#endif /* copy the string into our buffer */ - newName = (char *)malloc(CFStringGetLength(fullName) + 1); + newName = (char *) malloc(CFStringGetLength(fullName) + 1); CFStringGetCString(fullName, newName, CFStringGetLength(fullName) + 1, defaultEncoding); /* clean up */ #ifdef OLDCODE - if (endpointName) - CFRelease(endpointName); - if (deviceName) - CFRelease(deviceName); + if (endpointName) CFRelease(endpointName); + if (deviceName) CFRelease(deviceName); #endif - if (fullName) - CFRelease(fullName); + if (fullName) CFRelease(fullName); return newName; } + + pm_fns_node pm_macosx_in_dictionary = { none_write_short, none_sysex, @@ -899,6 +843,7 @@ pm_fns_node pm_macosx_out_dictionary = { midi_get_host_error, }; + PmError pm_macosxcm_init(void) { ItemCount numInputs, numOutputs, numDevices; @@ -917,60 +862,53 @@ PmError pm_macosxcm_init(void) Pm_CountDevices() will return zero, which is correct and useful information */ - if (numDevices <= 0) - { + if (numDevices <= 0) { return pmNoError; } + /* Initialize the client handle */ macHostError = MIDIClientCreate(CFSTR("PortMidi"), NULL, NULL, &client); - if (macHostError != noErr) - { + if (macHostError != noErr) { error_text = "MIDIClientCreate() in pm_macosxcm_init()"; goto error_return; } /* Create the input port */ macHostError = MIDIInputPortCreate(client, CFSTR("Input port"), readProc, - NULL, &portIn); - if (macHostError != noErr) - { + NULL, &portIn); + if (macHostError != noErr) { error_text = "MIDIInputPortCreate() in pm_macosxcm_init()"; goto error_return; } - + /* Create the output port */ macHostError = MIDIOutputPortCreate(client, CFSTR("Output port"), &portOut); - if (macHostError != noErr) - { + if (macHostError != noErr) { error_text = "MIDIOutputPortCreate() in pm_macosxcm_init()"; goto error_return; } /* Iterate over the MIDI input devices */ - for (i = 0; i < numInputs; i++) - { + for (i = 0; i < numInputs; i++) { endpoint = MIDIGetSource(i); - if (endpoint == MIDI_NULL) - { + if (endpoint == MIDI_NULL) { continue; } /* set the first input we see to the default */ if (pm_default_input_device_id == -1) pm_default_input_device_id = pm_descriptor_index; - + /* Register this device with PortMidi */ pm_add_device("CoreMIDI", cm_get_full_endpoint_name(endpoint), - TRUE, (void *)INT2VOIDP(endpoint), &pm_macosx_in_dictionary); + TRUE, INT2VOIDP(endpoint), &pm_macosx_in_dictionary); } /* Iterate over the MIDI output devices */ - for (i = 0; i < numOutputs; i++) - { + for (i = 0; i < numOutputs; i++) { endpoint = MIDIGetDestination(i); - if (endpoint == MIDI_NULL) - { + if (endpoint == MIDI_NULL) { continue; } @@ -980,10 +918,10 @@ PmError pm_macosxcm_init(void) /* Register this device with PortMidi */ pm_add_device("CoreMIDI", cm_get_full_endpoint_name(endpoint), - FALSE, (void *)INT2VOIDP(endpoint), &pm_macosx_out_dictionary); + FALSE, INT2VOIDP(endpoint), &pm_macosx_out_dictionary); } return pmNoError; - + error_return: pm_hosterror = macHostError; sprintf(pm_hosterror_text, "Host error %ld: %s\n", macHostError, error_text); @@ -993,10 +931,7 @@ PmError pm_macosxcm_init(void) void pm_macosxcm_term(void) { - if (client != MIDI_NULL) - MIDIClientDispose(client); - if (portIn != MIDI_NULL) - MIDIPortDispose(portIn); - if (portOut != MIDI_NULL) - MIDIPortDispose(portOut); + if (client != MIDI_NULL) MIDIClientDispose(client); + if (portIn != MIDI_NULL) MIDIPortDispose(portIn); + if (portOut != MIDI_NULL) MIDIPortDispose(portOut); }