From a96f40b9a943243d488882e16ccec6250c4abf78 Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 3 Feb 2024 04:39:39 +0100 Subject: [PATCH 1/6] Replace EndianS32_BtoN with Core Foundation equivalent --- pm_mac/pmmacosxcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pm_mac/pmmacosxcm.c b/pm_mac/pmmacosxcm.c index 39285ed..2484ce2 100755 --- a/pm_mac/pmmacosxcm.c +++ b/pm_mac/pmmacosxcm.c @@ -1096,7 +1096,7 @@ static CFStringRef ConnectedEndpointName(MIDIEndpointRef endpoint, if (nConnected) { const SInt32 *pid = (const SInt32 *)(CFDataGetBytePtr(connections)); for (i = 0; i < nConnected; ++i, ++pid) { - MIDIUniqueID id = EndianS32_BtoN(*pid); + MIDIUniqueID id = CFSwapInt32BigToHost(*pid); MIDIObjectRef connObject; MIDIObjectType connObjectType; err = MIDIObjectFindByUniqueID(id, &connObject, From ba325d4e83567f777fce334180202f10065e21cc Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 3 Feb 2024 04:44:38 +0100 Subject: [PATCH 2/6] Add drop-in replacements for host time methods in pm_mac --- pm_mac/pmmacosxcm.c | 86 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 18 deletions(-) diff --git a/pm_mac/pmmacosxcm.c b/pm_mac/pmmacosxcm.c index 2484ce2..b9acfc3 100755 --- a/pm_mac/pmmacosxcm.c +++ b/pm_mac/pmmacosxcm.c @@ -82,9 +82,15 @@ #include #include -#include #include #include +#include + +#if TARGET_OS_OSX +#include +#else +#include +#endif #define PACKET_BUFFER_SIZE 1024 /* maximum overall data rate (OS X limits MIDI rate in case there @@ -222,6 +228,10 @@ typedef struct coremidi_info_struct { /* private function declarations */ MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp); // returns host time PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp); // returns ms +static UInt64 current_host_time(void); +static UInt64 nanos_to_host_time(UInt64 nanos); +static UInt64 host_time_to_nanos(UInt64 host_time); +static UInt64 micros_per_host_tick(void); char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint, int *iac_flag); @@ -259,7 +269,7 @@ static PmTimestamp midi_synchronize(PmInternal *midi) { coremidi_info_type info = (coremidi_info_type) midi->api_info; UInt64 pm_stream_time_2 = // current time in ns - AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); + host_time_to_nanos(current_host_time()); PmTimestamp real_time; // in ms UInt64 pm_stream_time; // in ns /* if latency is zero and this is an output, there is no @@ -270,8 +280,7 @@ static PmTimestamp midi_synchronize(PmInternal *midi) /* 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()); + pm_stream_time_2 = host_time_to_nanos(current_host_time()); /* repeat if more than 0.5 ms has elapsed */ } while (pm_stream_time_2 > pm_stream_time + 500000); info->delta = pm_stream_time - ((UInt64) real_time * (UInt64) 1000000); @@ -415,19 +424,19 @@ static void read_callback(const MIDIPacketList *newPackets, PmInternal *midi) */ CM_DEBUG printf("read_callback packet @ %lld ns (host %lld) " "status %x length %d\n", - AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()), - AudioGetCurrentHostTime(), + host_time_to_nanos(current_host_time()), + current_host_time(), packet->data[0], packet->length); for (packetIndex = 0; packetIndex < newPackets->numPackets; packetIndex++) { /* Set the timestamp and dispatch this message */ CM_DEBUG printf(" packet->timeStamp %lld ns %lld host\n", packet->timeStamp, - AudioConvertHostTimeToNanos(packet->timeStamp)); + host_time_to_nanos(packet->timeStamp)); if (packet->timeStamp == 0) { event.timestamp = now; } else { event.timestamp = (PmTimestamp) /* explicit conversion */ ( - (AudioConvertHostTimeToNanos(packet->timeStamp) - info->delta) / + (host_time_to_nanos(packet->timeStamp) - info->delta) / (UInt64) 1000000); } status = packet->data[0]; @@ -505,7 +514,7 @@ static coremidi_info_type create_macosxcm_info(int is_virtual, int is_input) info->last_msg_length = 0; info->min_next_time = 0; info->isIACdevice = FALSE; - info->us_per_host_tick = 1000000.0 / AudioGetHostClockFrequency(); + info->us_per_host_tick = micros_per_host_tick(); info->host_ticks_per_byte = (UInt64) (1000000.0 / (info->us_per_host_tick * MAX_BYTES_PER_S)); info->packetList = (is_input ? NULL : @@ -754,7 +763,7 @@ static PmError midi_write_flush(PmInternal *midi, PmTimestamp timestamp) if (info->packet != NULL) { /* out of space, send the buffer and start refilling it */ /* update min_next_time each flush to support rate limit */ - UInt64 host_now = AudioGetCurrentHostTime(); + UInt64 host_now = current_host_time(); if (host_now > info->min_next_time) info->min_next_time = host_now; if (info->is_virtual) { @@ -780,8 +789,8 @@ static PmError send_packet(PmInternal *midi, Byte *message, CM_DEBUG printf("add %d to packet %p len %d timestamp %lld @ %lld ns " "(host %lld)\n", message[0], info->packet, messageLength, timestamp, - AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()), - AudioGetCurrentHostTime()); + host_time_to_nanos(current_host_time()), + current_host_time()); info->packet = MIDIPacketListAdd(info->packetList, sizeof(info->packetBuffer), info->packet, timestamp, messageLength, message); @@ -842,11 +851,11 @@ static PmError midi_write_short(PmInternal *midi, PmEvent *event) * latency is zero. Both mean no timing and send immediately. */ if (when == 0 || midi->latency == 0) { - timestamp = AudioGetCurrentHostTime(); + timestamp = current_host_time(); } else { /* translate PortMidi time + latency to CoreMIDI time */ timestamp = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + info->delta; - timestamp = AudioConvertNanosToHostTime(timestamp); + timestamp = nanos_to_host_time(timestamp); } message[0] = Pm_MessageStatus(what); @@ -888,10 +897,10 @@ static PmError midi_begin_sysex(PmInternal *midi, PmTimestamp when) when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + info->delta; info->sysex_timestamp = - (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns); + (MIDITimeStamp) nanos_to_host_time(when_ns); UInt64 now; /* only make system time call when writing a virtual port */ if (info->is_virtual && info->sysex_timestamp < - (now = AudioGetCurrentHostTime())) { + (now = current_host_time())) { info->sysex_timestamp = now; } @@ -963,6 +972,47 @@ static unsigned int midi_check_host_error(PmInternal *midi) return FALSE; } +UInt64 current_host_time(void) +{ +#if TARGET_OS_OSX + return AudioGetCurrentHostTime(); +#else + return mach_absolute_time(); +#endif +} + +UInt64 nanos_to_host_time(UInt64 nanos) +{ +#if TARGET_OS_OSX + return AudioConvertNanosToHostTime(nanos); +#else + mach_timebase_info_data_t clock_timebase; + mach_timebase_info(&clock_timebase); + return (nanos * clock_timebase.denom) / clock_timebase.numer; +#endif +} + +UInt64 host_time_to_nanos(UInt64 host_time) +{ +#if TARGET_OS_OSX + return AudioConvertHostTimeToNanos(host_time); +#else + mach_timebase_info_data_t clock_timebase; + mach_timebase_info(&clock_timebase); + return (host_time * clock_timebase.numer) / clock_timebase.denom; +#endif +} + +UInt64 micros_per_host_tick(void) +{ +#if TARGET_OS_OSX + return 1000000.0 / AudioGetHostClockFrequency(); +#else + mach_timebase_info_data_t clock_timebase; + mach_timebase_info(&clock_timebase); + return clock_timebase.numer / (clock_timebase.denom * 1000.0); +#endif +} MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) { @@ -971,7 +1021,7 @@ MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) return (MIDITimeStamp)0; } else { nanos = (UInt64)timestamp * (UInt64)1000000; - return (MIDITimeStamp)AudioConvertNanosToHostTime(nanos); + return (MIDITimeStamp)nanos_to_host_time(nanos); } } @@ -979,7 +1029,7 @@ MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp) { UInt64 nanos; - nanos = AudioConvertHostTimeToNanos(timestamp); + nanos = host_time_to_nanos(timestamp); return (PmTimestamp)(nanos / (UInt64)1000000); } From b14c7297852cd22f13f62386c02e50039c9a70a9 Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 3 Feb 2024 04:55:33 +0100 Subject: [PATCH 3/6] Add drop-in-replacements to porttime too --- porttime/ptmacosx_mach.c | 55 +++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/porttime/ptmacosx_mach.c b/porttime/ptmacosx_mach.c index 1390af8..0cfb605 100755 --- a/porttime/ptmacosx_mach.c +++ b/porttime/ptmacosx_mach.c @@ -2,7 +2,6 @@ #include #include -#include #import #import @@ -10,6 +9,14 @@ #import #include #include +#include +#include + +#if TARGET_OS_OSX +#include +#else +#include +#endif #include "porttime.h" #include "sys/time.h" @@ -32,6 +39,11 @@ static int time_started_flag = FALSE; static UInt64 start_time; static pthread_t pt_thread_pid; +/* private function declarations */ +static UInt64 current_host_time(void); +static UInt64 nanos_to_host_time(UInt64 nanos); +static UInt64 host_time_to_nanos(UInt64 host_time); + /* note that this is static data -- we only need one copy */ typedef struct { int id; @@ -119,8 +131,8 @@ static void *Pt_CallbackProc(void *p) int delay = mytime++ * parameters->resolution - Pt_Time(); PtTimestamp timestamp; if (delay < 0) delay = 0; - wait_time = AudioConvertNanosToHostTime((UInt64)delay * NSEC_PER_MSEC); - wait_time += AudioGetCurrentHostTime(); + wait_time = nanos_to_host_time((UInt64)delay * NSEC_PER_MSEC); + wait_time += current_host_time(); mach_wait_until(wait_time); timestamp = Pt_Time(); (*(parameters->callback))(timestamp, parameters->userData); @@ -133,7 +145,7 @@ static void *Pt_CallbackProc(void *p) PtError Pt_Start(int resolution, PtCallback *callback, void *userData) { if (time_started_flag) return ptAlreadyStarted; - start_time = AudioGetCurrentHostTime(); + start_time = current_host_time(); if (callback) { int res; @@ -192,8 +204,8 @@ int Pt_Started(void) PtTimestamp Pt_Time(void) { UInt64 clock_time, nsec_time; - clock_time = AudioGetCurrentHostTime() - start_time; - nsec_time = AudioConvertHostTimeToNanos(clock_time); + clock_time = current_host_time() - start_time; + nsec_time = host_time_to_nanos(clock_time); return (PtTimestamp)(nsec_time / NSEC_PER_MSEC); } @@ -202,3 +214,34 @@ void Pt_Sleep(int32_t duration) { usleep(duration * 1000); } + +UInt64 current_host_time(void) +{ +#if TARGET_OS_OSX + return AudioGetCurrentHostTime(); +#else + return mach_absolute_time(); +#endif +} + +UInt64 nanos_to_host_time(UInt64 nanos) +{ +#if TARGET_OS_OSX + return AudioConvertNanosToHostTime(nanos); +#else + mach_timebase_info_data_t clock_timebase; + mach_timebase_info(&clock_timebase); + return (nanos * clock_timebase.denom) / clock_timebase.numer; +#endif +} + +UInt64 host_time_to_nanos(UInt64 host_time) +{ +#if TARGET_OS_OSX + return AudioConvertHostTimeToNanos(host_time); +#else + mach_timebase_info_data_t clock_timebase; + mach_timebase_info(&clock_timebase); + return (host_time * clock_timebase.numer) / clock_timebase.denom; +#endif +} From 15ddc24129f5e60808026acf6741719277aed916 Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 10 Feb 2024 22:35:32 +0100 Subject: [PATCH 4/6] Migrate host time conversion to Apple-specific porttime header --- pm_mac/pmmacosxcm.c | 79 +++++++++------------------------------- porttime/ptmacosx.h | 21 +++++++++++ porttime/ptmacosx_mach.c | 34 ++++++++++------- 3 files changed, 58 insertions(+), 76 deletions(-) create mode 100755 porttime/ptmacosx.h diff --git a/pm_mac/pmmacosxcm.c b/pm_mac/pmmacosxcm.c index b9acfc3..8f8576f 100755 --- a/pm_mac/pmmacosxcm.c +++ b/pm_mac/pmmacosxcm.c @@ -75,6 +75,7 @@ #include "pmutil.h" #include "pminternal.h" #include "porttime.h" +#include "ptmacosx.h" #include "pmmacosxcm.h" #include @@ -228,10 +229,6 @@ typedef struct coremidi_info_struct { /* private function declarations */ MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp); // returns host time PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp); // returns ms -static UInt64 current_host_time(void); -static UInt64 nanos_to_host_time(UInt64 nanos); -static UInt64 host_time_to_nanos(UInt64 host_time); -static UInt64 micros_per_host_tick(void); char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint, int *iac_flag); @@ -269,7 +266,7 @@ static PmTimestamp midi_synchronize(PmInternal *midi) { coremidi_info_type info = (coremidi_info_type) midi->api_info; UInt64 pm_stream_time_2 = // current time in ns - host_time_to_nanos(current_host_time()); + Pt_HostTimeToNanos(Pt_CurrentHostTime()); PmTimestamp real_time; // in ms UInt64 pm_stream_time; // in ns /* if latency is zero and this is an output, there is no @@ -280,7 +277,7 @@ static PmTimestamp midi_synchronize(PmInternal *midi) /* 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 = host_time_to_nanos(current_host_time()); + pm_stream_time_2 = Pt_HostTimeToNanos(Pt_CurrentHostTime()); /* repeat if more than 0.5 ms has elapsed */ } while (pm_stream_time_2 > pm_stream_time + 500000); info->delta = pm_stream_time - ((UInt64) real_time * (UInt64) 1000000); @@ -424,19 +421,19 @@ static void read_callback(const MIDIPacketList *newPackets, PmInternal *midi) */ CM_DEBUG printf("read_callback packet @ %lld ns (host %lld) " "status %x length %d\n", - host_time_to_nanos(current_host_time()), - current_host_time(), + Pt_HostTimeToNanos(Pt_CurrentHostTime()), + Pt_CurrentHostTime(), packet->data[0], packet->length); for (packetIndex = 0; packetIndex < newPackets->numPackets; packetIndex++) { /* Set the timestamp and dispatch this message */ CM_DEBUG printf(" packet->timeStamp %lld ns %lld host\n", packet->timeStamp, - host_time_to_nanos(packet->timeStamp)); + Pt_HostTimeToNanos(packet->timeStamp)); if (packet->timeStamp == 0) { event.timestamp = now; } else { event.timestamp = (PmTimestamp) /* explicit conversion */ ( - (host_time_to_nanos(packet->timeStamp) - info->delta) / + (Pt_HostTimeToNanos(packet->timeStamp) - info->delta) / (UInt64) 1000000); } status = packet->data[0]; @@ -514,7 +511,7 @@ static coremidi_info_type create_macosxcm_info(int is_virtual, int is_input) info->last_msg_length = 0; info->min_next_time = 0; info->isIACdevice = FALSE; - info->us_per_host_tick = micros_per_host_tick(); + info->us_per_host_tick = Pt_MicrosPerHostTick(); info->host_ticks_per_byte = (UInt64) (1000000.0 / (info->us_per_host_tick * MAX_BYTES_PER_S)); info->packetList = (is_input ? NULL : @@ -763,7 +760,7 @@ static PmError midi_write_flush(PmInternal *midi, PmTimestamp timestamp) if (info->packet != NULL) { /* out of space, send the buffer and start refilling it */ /* update min_next_time each flush to support rate limit */ - UInt64 host_now = current_host_time(); + UInt64 host_now = Pt_CurrentHostTime(); if (host_now > info->min_next_time) info->min_next_time = host_now; if (info->is_virtual) { @@ -789,8 +786,8 @@ static PmError send_packet(PmInternal *midi, Byte *message, CM_DEBUG printf("add %d to packet %p len %d timestamp %lld @ %lld ns " "(host %lld)\n", message[0], info->packet, messageLength, timestamp, - host_time_to_nanos(current_host_time()), - current_host_time()); + Pt_HostTimeToNanos(Pt_CurrentHostTime()), + Pt_CurrentHostTime()); info->packet = MIDIPacketListAdd(info->packetList, sizeof(info->packetBuffer), info->packet, timestamp, messageLength, message); @@ -851,11 +848,11 @@ static PmError midi_write_short(PmInternal *midi, PmEvent *event) * latency is zero. Both mean no timing and send immediately. */ if (when == 0 || midi->latency == 0) { - timestamp = current_host_time(); + timestamp = Pt_CurrentHostTime(); } else { /* translate PortMidi time + latency to CoreMIDI time */ timestamp = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + info->delta; - timestamp = nanos_to_host_time(timestamp); + timestamp = Pt_NanosToHostTime(timestamp); } message[0] = Pm_MessageStatus(what); @@ -897,10 +894,10 @@ static PmError midi_begin_sysex(PmInternal *midi, PmTimestamp when) when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + info->delta; info->sysex_timestamp = - (MIDITimeStamp) nanos_to_host_time(when_ns); + (MIDITimeStamp) Pt_NanosToHostTime(when_ns); UInt64 now; /* only make system time call when writing a virtual port */ if (info->is_virtual && info->sysex_timestamp < - (now = current_host_time())) { + (now = Pt_CurrentHostTime())) { info->sysex_timestamp = now; } @@ -972,48 +969,6 @@ static unsigned int midi_check_host_error(PmInternal *midi) return FALSE; } -UInt64 current_host_time(void) -{ -#if TARGET_OS_OSX - return AudioGetCurrentHostTime(); -#else - return mach_absolute_time(); -#endif -} - -UInt64 nanos_to_host_time(UInt64 nanos) -{ -#if TARGET_OS_OSX - return AudioConvertNanosToHostTime(nanos); -#else - mach_timebase_info_data_t clock_timebase; - mach_timebase_info(&clock_timebase); - return (nanos * clock_timebase.denom) / clock_timebase.numer; -#endif -} - -UInt64 host_time_to_nanos(UInt64 host_time) -{ -#if TARGET_OS_OSX - return AudioConvertHostTimeToNanos(host_time); -#else - mach_timebase_info_data_t clock_timebase; - mach_timebase_info(&clock_timebase); - return (host_time * clock_timebase.numer) / clock_timebase.denom; -#endif -} - -UInt64 micros_per_host_tick(void) -{ -#if TARGET_OS_OSX - return 1000000.0 / AudioGetHostClockFrequency(); -#else - mach_timebase_info_data_t clock_timebase; - mach_timebase_info(&clock_timebase); - return clock_timebase.numer / (clock_timebase.denom * 1000.0); -#endif -} - MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) { UInt64 nanos; @@ -1021,7 +976,7 @@ MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) return (MIDITimeStamp)0; } else { nanos = (UInt64)timestamp * (UInt64)1000000; - return (MIDITimeStamp)nanos_to_host_time(nanos); + return (MIDITimeStamp)Pt_NanosToHostTime(nanos); } } @@ -1029,7 +984,7 @@ MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp) { UInt64 nanos; - nanos = host_time_to_nanos(timestamp); + nanos = Pt_HostTimeToNanos(timestamp); return (PmTimestamp)(nanos / (UInt64)1000000); } diff --git a/porttime/ptmacosx.h b/porttime/ptmacosx.h new file mode 100755 index 0000000..01d9de1 --- /dev/null +++ b/porttime/ptmacosx.h @@ -0,0 +1,21 @@ +/** @file ptmacosx.h portable timer implementation for mac os x. */ + +#include // needed for UInt64 + +#ifdef __cplusplus +extern "C" { +#endif + +UInt64 Pt_CurrentHostTime(void); + +UInt64 Pt_NanosToHostTime(UInt64 nanos); + +UInt64 Pt_HostTimeToNanos(UInt64 host_time); + +UInt64 Pt_MicrosPerHostTick(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif diff --git a/porttime/ptmacosx_mach.c b/porttime/ptmacosx_mach.c index 0cfb605..0775357 100755 --- a/porttime/ptmacosx_mach.c +++ b/porttime/ptmacosx_mach.c @@ -9,7 +9,6 @@ #import #include #include -#include #include #if TARGET_OS_OSX @@ -19,6 +18,7 @@ #endif #include "porttime.h" +#include "ptmacosx.h" #include "sys/time.h" #include "pthread.h" @@ -39,11 +39,6 @@ static int time_started_flag = FALSE; static UInt64 start_time; static pthread_t pt_thread_pid; -/* private function declarations */ -static UInt64 current_host_time(void); -static UInt64 nanos_to_host_time(UInt64 nanos); -static UInt64 host_time_to_nanos(UInt64 host_time); - /* note that this is static data -- we only need one copy */ typedef struct { int id; @@ -131,8 +126,8 @@ static void *Pt_CallbackProc(void *p) int delay = mytime++ * parameters->resolution - Pt_Time(); PtTimestamp timestamp; if (delay < 0) delay = 0; - wait_time = nanos_to_host_time((UInt64)delay * NSEC_PER_MSEC); - wait_time += current_host_time(); + wait_time = Pt_NanosToHostTime((UInt64)delay * NSEC_PER_MSEC); + wait_time += Pt_CurrentHostTime(); mach_wait_until(wait_time); timestamp = Pt_Time(); (*(parameters->callback))(timestamp, parameters->userData); @@ -145,7 +140,7 @@ static void *Pt_CallbackProc(void *p) PtError Pt_Start(int resolution, PtCallback *callback, void *userData) { if (time_started_flag) return ptAlreadyStarted; - start_time = current_host_time(); + start_time = Pt_CurrentHostTime(); if (callback) { int res; @@ -204,8 +199,8 @@ int Pt_Started(void) PtTimestamp Pt_Time(void) { UInt64 clock_time, nsec_time; - clock_time = current_host_time() - start_time; - nsec_time = host_time_to_nanos(clock_time); + clock_time = Pt_CurrentHostTime() - start_time; + nsec_time = Pt_HostTimeToNanos(clock_time); return (PtTimestamp)(nsec_time / NSEC_PER_MSEC); } @@ -215,7 +210,7 @@ void Pt_Sleep(int32_t duration) usleep(duration * 1000); } -UInt64 current_host_time(void) +uint64_t Pt_CurrentHostTime(void) { #if TARGET_OS_OSX return AudioGetCurrentHostTime(); @@ -224,7 +219,7 @@ UInt64 current_host_time(void) #endif } -UInt64 nanos_to_host_time(UInt64 nanos) +UInt64 Pt_NanosToHostTime(UInt64 nanos) { #if TARGET_OS_OSX return AudioConvertNanosToHostTime(nanos); @@ -235,7 +230,7 @@ UInt64 nanos_to_host_time(UInt64 nanos) #endif } -UInt64 host_time_to_nanos(UInt64 host_time) +UInt64 Pt_HostTimeToNanos(UInt64 host_time) { #if TARGET_OS_OSX return AudioConvertHostTimeToNanos(host_time); @@ -245,3 +240,14 @@ UInt64 host_time_to_nanos(UInt64 host_time) return (host_time * clock_timebase.numer) / clock_timebase.denom; #endif } + +UInt64 Pt_MicrosPerHostTick(void) +{ +#if TARGET_OS_OSX + return 1000000.0 / AudioGetHostClockFrequency(); +#else + mach_timebase_info_data_t clock_timebase; + mach_timebase_info(&clock_timebase); + return clock_timebase.numer / (clock_timebase.denom * 1000.0); +#endif +} From 87724810533d0b0f3e85a3580ab363d6433af3d2 Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 10 Feb 2024 22:40:37 +0100 Subject: [PATCH 5/6] Remove no longer needed includes from pmmacosxcm --- pm_mac/pmmacosxcm.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pm_mac/pmmacosxcm.c b/pm_mac/pmmacosxcm.c index 8f8576f..5f62715 100755 --- a/pm_mac/pmmacosxcm.c +++ b/pm_mac/pmmacosxcm.c @@ -85,13 +85,6 @@ #include #include #include -#include - -#if TARGET_OS_OSX -#include -#else -#include -#endif #define PACKET_BUFFER_SIZE 1024 /* maximum overall data rate (OS X limits MIDI rate in case there From d1219cff56264eb2decd2b068f54b286c764d2e2 Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 10 Feb 2024 23:20:12 +0100 Subject: [PATCH 6/6] Replace UInt and SInt spellings with stdint.h i.e. replace UInt32 -> uint32_t SInt32 -> int32_t UInt64 -> uint64_t SInt64 -> int64_t --- pm_mac/pmmacosxcm.c | 43 ++++++++++++++++++++-------------------- porttime/ptmacosx.h | 10 +++++----- porttime/ptmacosx_mach.c | 15 +++++++------- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/pm_mac/pmmacosxcm.c b/pm_mac/pmmacosxcm.c index 5f62715..6d2980a 100755 --- a/pm_mac/pmmacosxcm.c +++ b/pm_mac/pmmacosxcm.c @@ -78,6 +78,7 @@ #include "ptmacosx.h" #include "pmmacosxcm.h" +#include #include #include @@ -199,7 +200,7 @@ extern pm_fns_node pm_macosx_out_dictionary; typedef struct coremidi_info_struct { int is_virtual; /* virtual device (TRUE) or actual device (FALSE)? */ - UInt64 delta; /* difference between stream time and real time in ns */ + uint64_t delta; /* difference between stream time and real time in ns */ int sysex_mode; /* middle of sending sysex */ uint32_t sysex_word; /* accumulate data when receiving sysex */ uint32_t sysex_byte_count; /* count how many received */ @@ -213,10 +214,10 @@ typedef struct coremidi_info_struct { /* allow for running status (is running status possible here? -rbd): -cpr */ unsigned char last_command; int32_t last_msg_length; - UInt64 min_next_time; /* when can the next send take place? (host time) */ + uint64_t min_next_time; /* when can the next send take place? (host time) */ int isIACdevice; Float64 us_per_host_tick; /* host clock frequency, units of min_next_time */ - UInt64 host_ticks_per_byte; /* host clock units per byte at maximum rate */ + uint64_t host_ticks_per_byte; /* host clock units per byte at maximum rate */ } coremidi_info_node, *coremidi_info_type; /* private function declarations */ @@ -258,10 +259,10 @@ static int midi_length(int32_t msg) static PmTimestamp midi_synchronize(PmInternal *midi) { coremidi_info_type info = (coremidi_info_type) midi->api_info; - UInt64 pm_stream_time_2 = // current time in ns + uint64_t pm_stream_time_2 = // current time in ns Pt_HostTimeToNanos(Pt_CurrentHostTime()); PmTimestamp real_time; // in ms - UInt64 pm_stream_time; // in ns + uint64_t pm_stream_time; // in ns /* 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); @@ -273,7 +274,7 @@ static PmTimestamp midi_synchronize(PmInternal *midi) pm_stream_time_2 = Pt_HostTimeToNanos(Pt_CurrentHostTime()); /* repeat if more than 0.5 ms has elapsed */ } while (pm_stream_time_2 > pm_stream_time + 500000); - info->delta = pm_stream_time - ((UInt64) real_time * (UInt64) 1000000); + info->delta = pm_stream_time - ((uint64_t) real_time * (uint64_t) 1000000); midi->sync_time = real_time; return real_time; } @@ -427,7 +428,7 @@ static void read_callback(const MIDIPacketList *newPackets, PmInternal *midi) } else { event.timestamp = (PmTimestamp) /* explicit conversion */ ( (Pt_HostTimeToNanos(packet->timeStamp) - info->delta) / - (UInt64) 1000000); + (uint64_t) 1000000); } status = packet->data[0]; /* process packet as sysex data if it begins with MIDI_SYSEX, or @@ -473,8 +474,8 @@ static void virtual_read_callback(const MIDIPacketList *newPackets, newPackets->packet[0].length == 8 && /* CoreMIDI declares packets with 4-byte alignment, so we * should be safe to test for 8 0xFF's as 2 32-bit values: */ - *(SInt32 *) &newPackets->packet[0].data[0] == -1 && - *(SInt32 *) &newPackets->packet[0].data[4] == -1) { + *(int32_t *) &newPackets->packet[0].data[0] == -1 && + *(int32_t *) &newPackets->packet[0].data[4] == -1) { CM_DEBUG printf("got close request packet\n"); pm_descriptors[id].pub.opened = FALSE; return; @@ -506,7 +507,7 @@ static coremidi_info_type create_macosxcm_info(int is_virtual, int is_input) info->isIACdevice = FALSE; info->us_per_host_tick = Pt_MicrosPerHostTick(); info->host_ticks_per_byte = - (UInt64) (1000000.0 / (info->us_per_host_tick * MAX_BYTES_PER_S)); + (uint64_t) (1000000.0 / (info->us_per_host_tick * MAX_BYTES_PER_S)); info->packetList = (is_input ? NULL : (MIDIPacketList *) info->packetBuffer); return info; @@ -580,7 +581,7 @@ static PmError midi_in_close(PmInternal *midi) } } else { /* make "close virtual port" message */ - SInt64 close_port_bytes = 0xFFFFFFFFFFFFFFFF; + int64_t close_port_bytes = 0xFFFFFFFFFFFFFFFF; /* memory requirements: packet count (4), timestamp (8), length (2), * data (8). Total: 22, but we allocate plenty more: */ @@ -753,7 +754,7 @@ static PmError midi_write_flush(PmInternal *midi, PmTimestamp timestamp) if (info->packet != NULL) { /* out of space, send the buffer and start refilling it */ /* update min_next_time each flush to support rate limit */ - UInt64 host_now = Pt_CurrentHostTime(); + uint64_t host_now = Pt_CurrentHostTime(); if (host_now > info->min_next_time) info->min_next_time = host_now; if (info->is_virtual) { @@ -843,7 +844,7 @@ static PmError midi_write_short(PmInternal *midi, PmEvent *event) if (when == 0 || midi->latency == 0) { timestamp = Pt_CurrentHostTime(); } else { /* translate PortMidi time + latency to CoreMIDI time */ - timestamp = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + + timestamp = ((uint64_t) (when + midi->latency) * (uint64_t) 1000000) + info->delta; timestamp = Pt_NanosToHostTime(timestamp); } @@ -875,7 +876,7 @@ static PmError midi_write_short(PmInternal *midi, PmEvent *event) static PmError midi_begin_sysex(PmInternal *midi, PmTimestamp when) { - UInt64 when_ns; + uint64_t when_ns; coremidi_info_type info = (coremidi_info_type) midi->api_info; assert(info); info->sysex_byte_count = 0; @@ -884,11 +885,11 @@ static PmError midi_begin_sysex(PmInternal *midi, PmTimestamp when) 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) + + when_ns = ((uint64_t) (when + midi->latency) * (uint64_t) 1000000) + info->delta; info->sysex_timestamp = (MIDITimeStamp) Pt_NanosToHostTime(when_ns); - UInt64 now; /* only make system time call when writing a virtual port */ + uint64_t now; /* only make system time call when writing a virtual port */ if (info->is_virtual && info->sysex_timestamp < (now = Pt_CurrentHostTime())) { info->sysex_timestamp = now; @@ -964,11 +965,11 @@ static unsigned int midi_check_host_error(PmInternal *midi) MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) { - UInt64 nanos; + uint64_t nanos; if (timestamp <= 0) { return (MIDITimeStamp)0; } else { - nanos = (UInt64)timestamp * (UInt64)1000000; + nanos = (uint64_t)timestamp * (uint64_t)1000000; return (MIDITimeStamp)Pt_NanosToHostTime(nanos); } } @@ -976,9 +977,9 @@ MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp) { - UInt64 nanos; + uint64_t nanos; nanos = Pt_HostTimeToNanos(timestamp); - return (PmTimestamp)(nanos / (UInt64)1000000); + return (PmTimestamp)(nanos / (uint64_t)1000000); } @@ -1092,7 +1093,7 @@ static CFStringRef ConnectedEndpointName(MIDIEndpointRef endpoint, nConnected = CFDataGetLength(connections) / (int32_t) sizeof(MIDIUniqueID); if (nConnected) { - const SInt32 *pid = (const SInt32 *)(CFDataGetBytePtr(connections)); + const int32_t *pid = (const int32_t *)(CFDataGetBytePtr(connections)); for (i = 0; i < nConnected; ++i, ++pid) { MIDIUniqueID id = CFSwapInt32BigToHost(*pid); MIDIObjectRef connObject; diff --git a/porttime/ptmacosx.h b/porttime/ptmacosx.h index 01d9de1..4795f62 100755 --- a/porttime/ptmacosx.h +++ b/porttime/ptmacosx.h @@ -1,18 +1,18 @@ /** @file ptmacosx.h portable timer implementation for mac os x. */ -#include // needed for UInt64 +#include // needed for uint64_t #ifdef __cplusplus extern "C" { #endif -UInt64 Pt_CurrentHostTime(void); +uint64_t Pt_CurrentHostTime(void); -UInt64 Pt_NanosToHostTime(UInt64 nanos); +uint64_t Pt_NanosToHostTime(uint64_t nanos); -UInt64 Pt_HostTimeToNanos(UInt64 host_time); +uint64_t Pt_HostTimeToNanos(uint64_t host_time); -UInt64 Pt_MicrosPerHostTick(void); +uint64_t Pt_MicrosPerHostTick(void); /** @} */ diff --git a/porttime/ptmacosx_mach.c b/porttime/ptmacosx_mach.c index 0775357..8d74b56 100755 --- a/porttime/ptmacosx_mach.c +++ b/porttime/ptmacosx_mach.c @@ -1,6 +1,7 @@ /* ptmacosx.c -- portable timer implementation for mac os x */ #include +#include #include #import @@ -36,7 +37,7 @@ #endif static int time_started_flag = FALSE; -static UInt64 start_time; +static uint64_t start_time; static pthread_t pt_thread_pid; /* note that this is static data -- we only need one copy */ @@ -122,11 +123,11 @@ static void *Pt_CallbackProc(void *p) parameters->id); */ while (pt_callback_proc_id == parameters->id) { /* wait for a multiple of resolution ms */ - UInt64 wait_time; + uint64_t wait_time; int delay = mytime++ * parameters->resolution - Pt_Time(); PtTimestamp timestamp; if (delay < 0) delay = 0; - wait_time = Pt_NanosToHostTime((UInt64)delay * NSEC_PER_MSEC); + wait_time = Pt_NanosToHostTime((uint64_t)delay * NSEC_PER_MSEC); wait_time += Pt_CurrentHostTime(); mach_wait_until(wait_time); timestamp = Pt_Time(); @@ -198,7 +199,7 @@ int Pt_Started(void) PtTimestamp Pt_Time(void) { - UInt64 clock_time, nsec_time; + uint64_t clock_time, nsec_time; clock_time = Pt_CurrentHostTime() - start_time; nsec_time = Pt_HostTimeToNanos(clock_time); return (PtTimestamp)(nsec_time / NSEC_PER_MSEC); @@ -219,7 +220,7 @@ uint64_t Pt_CurrentHostTime(void) #endif } -UInt64 Pt_NanosToHostTime(UInt64 nanos) +uint64_t Pt_NanosToHostTime(uint64_t nanos) { #if TARGET_OS_OSX return AudioConvertNanosToHostTime(nanos); @@ -230,7 +231,7 @@ UInt64 Pt_NanosToHostTime(UInt64 nanos) #endif } -UInt64 Pt_HostTimeToNanos(UInt64 host_time) +uint64_t Pt_HostTimeToNanos(uint64_t host_time) { #if TARGET_OS_OSX return AudioConvertHostTimeToNanos(host_time); @@ -241,7 +242,7 @@ UInt64 Pt_HostTimeToNanos(UInt64 host_time) #endif } -UInt64 Pt_MicrosPerHostTick(void) +uint64_t Pt_MicrosPerHostTick(void) { #if TARGET_OS_OSX return 1000000.0 / AudioGetHostClockFrequency();