From ae6b5d89ea93b95c2990895077cf5e8f0bba9ad9 Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Mon, 2 Feb 2004 11:28:02 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r1301, which included commits to RCS files with non-trunk default branches. svn path=/trunk/; revision=1302 --- pd/portmidi_osx/pmdarwin.c | 52 +++++++++- pd/portmidi_osx/pmmacosx.c | 149 +++++++++++++++++++++++----- pd/portmidi_osx/pmtest.c | 12 ++- pd/portmidi_osx/portmidi.c | 7 +- pd/portmidi_osx/portmidi.h | 9 +- pd/portmidi_osx/portmidi_osx_change_log.txt | 70 +++++++++++++ pd/portmidi_osx/porttime.h | 11 +- pd/portmidi_osx/ptdarwin.c | 8 +- 8 files changed, 272 insertions(+), 46 deletions(-) create mode 100644 pd/portmidi_osx/portmidi_osx_change_log.txt (limited to 'pd/portmidi_osx') diff --git a/pd/portmidi_osx/pmdarwin.c b/pd/portmidi_osx/pmdarwin.c index 3ca2c87a..7c1fb712 100644 --- a/pd/portmidi_osx/pmdarwin.c +++ b/pd/portmidi_osx/pmdarwin.c @@ -2,7 +2,15 @@ * PortMidi OS-dependent interface for Darwin (MacOS X) * Jon Parise * - * $Id: pmdarwin.c,v 1.1.1.1 2003-05-09 16:04:00 ggeiger Exp $ + * $Id: pmdarwin.c,v 1.1.1.2 2004-02-02 11:28:02 ggeiger Exp $ + * + * CHANGE LOG: + * 03Jul03 - X. J. Scott (xjs): + * - Pm_GetDefaultInputDeviceID() and Pm_GetDefaultOutputDeviceID() + * now return id of first input and output devices in system, + * rather than returning 0 as before. + * This fix enables valid default port values to be returned. + * 0 is returned if no such device is found. */ /* @@ -17,18 +25,52 @@ #include "portmidi.h" #include "pmmacosx.h" -PmError pm_init() +PmError pm_init(void) // xjs added void { return pm_macosx_init(); } -PmError pm_term() +PmError pm_term(void) // xjs added void { return pm_macosx_term(); } -PmDeviceID Pm_GetDefaultInputDeviceID() { return 0; }; -PmDeviceID Pm_GetDefaultOutputDeviceID() { return 0; }; +/* Pm_GetDefaultInputDeviceID() - return input with lowest id # (xjs) + */ +PmDeviceID Pm_GetDefaultInputDeviceID() +{ + int i; + int device_count; + const PmDeviceInfo *deviceInfo; + + device_count = Pm_CountDevices(); + for (i = 0; i < device_count; i++) { + deviceInfo = Pm_GetDeviceInfo(i); + if (deviceInfo->input) + return i; + } + + return 0; +}; + +/* Pm_GetDefaultOutputDeviceID() - return output with lowest id # (xjs) +*/ +PmDeviceID Pm_GetDefaultOutputDeviceID() +{ + int i; + int device_count; + const PmDeviceInfo *deviceInfo; + + device_count = Pm_CountDevices(); + for (i = 0; i < device_count; i++) { + deviceInfo = Pm_GetDeviceInfo(i); + if (deviceInfo->output) + return i; + } + + return 0; +}; + void *pm_alloc(size_t s) { return malloc(s); } diff --git a/pd/portmidi_osx/pmmacosx.c b/pd/portmidi_osx/pmmacosx.c index 7fe8adc4..9ae0c8ce 100644 --- a/pd/portmidi_osx/pmmacosx.c +++ b/pd/portmidi_osx/pmmacosx.c @@ -3,7 +3,28 @@ * * Jon Parise * - * $Id: pmmacosx.c,v 1.1.1.1 2003-05-09 16:04:00 ggeiger Exp $ + * $Id: pmmacosx.c,v 1.1.1.2 2004-02-02 11:28:02 ggeiger Exp $ + * + * 27Jun02 XJS (X. J. Scott) + * - midi_length(): + * fixed bug that gave bad lengths for system messages + * + * / pm_macosx_init(): + * Now allocates the device names. This fixes bug before where + * it assigned same string buffer on stack to all devices. + * - pm_macosx_term(), deleteDeviceName(): + * devices strings allocated during pm_macosx_init() are deallocated. + * + * + pm_macosx_init(), newDeviceName(): + * registering kMIDIPropertyManufacturer + kMIDIPropertyModel + kMIDIPropertyName + * for name strings instead of just name. + * + * / pm_macosx_init(): unsigned i to quiet compiler griping + * - get_timestamp(): + * no change right here but type of Pt_Time() was altered in porttime.h + * so it matches type PmTimeProcPtr in assignment in this function. + * / midi_write(): + * changed unsigned to signed to stop compiler griping */ #include "portmidi.h" @@ -17,6 +38,8 @@ #include #include +#define PM_DEVICE_NAME_LENGTH 64 + #define PACKET_BUFFER_SIZE 1024 static MIDIClientRef client = NULL; /* Client handle to the MIDI server */ @@ -26,6 +49,9 @@ static MIDIPortRef portOut = NULL; /* Output port handle */ extern pm_fns_node pm_macosx_in_dictionary; extern pm_fns_node pm_macosx_out_dictionary; +static char * newDeviceName(MIDIEndpointRef endpoint); +static void deleteDeviceName(char **szDeviceName_p); + static int midi_length(long msg) { @@ -42,8 +68,8 @@ midi_length(long msg) status = msg & 0xFF; high = status >> 4; low = status & 15; - - return (high != 0xF0) ? high_lengths[high] : low_lengths[low]; +// return (high != 0xF0) ? high_lengths[high] : low_lengths[low]; + return (high != 0x0F) ? high_lengths[high] : low_lengths[low]; // fixed 6/27/03, xjs } static PmTimestamp @@ -171,7 +197,7 @@ midi_write(PmInternal *midi, PmEvent *events, long length) PmTimeProcPtr time_proc; PmEvent event; unsigned int pm_time; - unsigned int eventIndex; + long eventIndex; // xjs: long instead of unsigned int, to match type of 'length' which compares against it unsigned int messageLength; Byte message[3]; @@ -202,7 +228,7 @@ midi_write(PmInternal *midi, PmEvent *events, long length) /* Extract the event data and pack it into the message buffer */ for (eventIndex = 0; eventIndex < length; eventIndex++) { - event = events[eventIndex]; + event = events[eventIndex]; /* Compute the timestamp */ pm_time = (*time_proc)(midi->time_info); @@ -228,6 +254,78 @@ midi_write(PmInternal *midi, PmEvent *events, long length) return pmNoError; } +/* newDeviceName() -- create a string that describes a MIDI endpoint device + * deleteDeviceName() -- dispose of string created. + * + * Concatenates manufacturer, model and name of endpoint and returns + * within freshly allocated space, to be registered in pm_add_device(). + * + * 27Jun03: XJS -- extracted and extended from pm_macosx_init(). + * 11Nov03: XJS -- safely handles cases where any string properties are + * not present, such as is the case with the virtual ports created + * by many programs. + */ + +static char * newDeviceName(MIDIEndpointRef endpoint) +{ + CFStringEncoding defaultEncoding; + CFStringRef deviceCFString; + char manufBuf[PM_DEVICE_NAME_LENGTH]; + char modelBuf[PM_DEVICE_NAME_LENGTH]; + char nameBuf[PM_DEVICE_NAME_LENGTH]; + char manufModelNameBuf[PM_DEVICE_NAME_LENGTH * 3 + 1]; + char *szDeviceName; + size_t length; + OSStatus iErr; + + /* Determine the default system character encording */ + + defaultEncoding = CFStringGetSystemEncoding(); + + /* Get the manufacturer, model and name of this device and combine into one string. */ + + iErr = MIDIObjectGetStringProperty(endpoint, kMIDIPropertyManufacturer, &deviceCFString); + if (noErr == iErr) { + CFStringGetCString(deviceCFString, manufBuf, sizeof(manufBuf), defaultEncoding); + CFRelease(deviceCFString); + } + else + strcpy(manufBuf, ""); + + iErr = MIDIObjectGetStringProperty(endpoint, kMIDIPropertyModel, &deviceCFString); + if (noErr == iErr) { + CFStringGetCString(deviceCFString, modelBuf, sizeof(modelBuf), defaultEncoding); + CFRelease(deviceCFString); + } + else + strcpy(modelBuf, ""); + + iErr = MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &deviceCFString); + if (noErr == iErr) { + CFStringGetCString(deviceCFString, nameBuf, sizeof(nameBuf), defaultEncoding); + CFRelease(deviceCFString); + } + else + strcpy(nameBuf, ""); + + sprintf(manufModelNameBuf, "%s %s: %s", manufBuf, modelBuf, nameBuf); + length = strlen(manufModelNameBuf); + + /* Allocate a new string and return. */ + + szDeviceName = (char *)pm_alloc(length + 1); + strcpy(szDeviceName, manufModelNameBuf); + + return szDeviceName; +} + +static void deleteDeviceName(char **szDeviceName_p) +{ + pm_free(*szDeviceName_p); + *szDeviceName_p = NULL; + return; +} + pm_fns_node pm_macosx_in_dictionary = { none_write, midi_in_open, @@ -248,14 +346,12 @@ pm_macosx_init(void) OSStatus status; ItemCount numDevices, numInputs, numOutputs; MIDIEndpointRef endpoint; - CFStringEncoding defaultEncoding; - CFStringRef deviceName; - char nameBuf[256]; - int i; + unsigned int i; // xjs, unsigned + char *szDeviceName; /* Determine the number of MIDI devices on the system */ numDevices = MIDIGetNumberOfDevices(); - numInputs = MIDIGetNumberOfSources(); + numInputs = MIDIGetNumberOfSources(); numOutputs = MIDIGetNumberOfDestinations(); /* Return prematurely if no devices exist on the system */ @@ -263,8 +359,6 @@ pm_macosx_init(void) return pmHostError; } - /* Determine the default system character encording */ - defaultEncoding = CFStringGetSystemEncoding(); /* Iterate over the MIDI input devices */ for (i = 0; i < numInputs; i++) { @@ -273,13 +367,12 @@ pm_macosx_init(void) continue; } - /* Get the name of this device */ - MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &deviceName); - CFStringGetCString(deviceName, nameBuf, 256, defaultEncoding); - CFRelease(deviceName); + /* Get the manufacturer, model and name of this device and combine into one string. */ + szDeviceName = newDeviceName(endpoint); // xjs /* Register this device with PortMidi */ - pm_add_device("CoreMIDI", nameBuf, TRUE, (void *)endpoint, + // xjs: szDeviceName is allocated memory since each has to be different and is not copied in pm_add_device() + pm_add_device("CoreMIDI", szDeviceName, TRUE, (void *)endpoint, &pm_macosx_in_dictionary); } @@ -290,14 +383,13 @@ pm_macosx_init(void) continue; } - /* Get the name of this device */ - MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &deviceName); - CFStringGetCString(deviceName, nameBuf, 256, defaultEncoding); - CFRelease(deviceName); + /* Get the manufacturer & model of this device */ + szDeviceName = newDeviceName(endpoint); // xjs /* Register this device with PortMidi */ - pm_add_device("CoreMIDI", nameBuf, FALSE, (void *)endpoint, - &pm_macosx_out_dictionary); + pm_add_device("CoreMIDI", szDeviceName, FALSE, (void *)endpoint, // xjs, szDeviceName (as above) + &pm_macosx_out_dictionary); + } /* Initialize the client handle */ @@ -328,6 +420,17 @@ pm_macosx_init(void) PmError pm_macosx_term(void) { + int i; + int device_count; + const PmDeviceInfo *deviceInfo; + + /* release memory allocated for device names */ + device_count = Pm_CountDevices(); + for (i = 0; i < device_count; i++) { + deviceInfo = Pm_GetDeviceInfo(i); + deleteDeviceName((char **)&deviceInfo->name); + } + if (client != NULL) MIDIClientDispose(client); if (portIn != NULL) MIDIPortDispose(portIn); if (portOut != NULL) MIDIPortDispose(portOut); diff --git a/pd/portmidi_osx/pmtest.c b/pd/portmidi_osx/pmtest.c index 5628d25e..6e590fd5 100644 --- a/pd/portmidi_osx/pmtest.c +++ b/pd/portmidi_osx/pmtest.c @@ -25,11 +25,12 @@ main() int statusprefix; - + Pm_Initialize(); // xjs + /* always start the timer before you start midi */ Pt_Start(1, 0, 0); /* start a timer with millisecond accuracy */ - + printf("%d midi ports found...\n", Pm_CountDevices()); // xjs for (i = 0; i < Pm_CountDevices(); i++) { const PmDeviceInfo *info = Pm_GetDeviceInfo(i); printf("%d: %s, %s", i, info->interf, info->name); @@ -86,6 +87,7 @@ main() gets(line); } + printf("delay %d, tranpose %d\n", delay, transpose); // xjs /* loop, echoing input back transposed with multiple taps */ @@ -111,7 +113,7 @@ main() printf("\nReceived key message = %X %X %X, at time %ld\n", status, data1, data2, buffer[0].timestamp); fflush(stdout); - /* immediately send the echoes to PortMIDI */ + /* immediately send the echoes to PortMIDI (note that only the echoes are to be transposed) */ for (i = 1; i < NUM_ECHOES; i++) { buffer[i].message = Pm_Message(status, data1 + transpose, data2 >> i); buffer[i].timestamp = buffer[0].timestamp + (i * delay); @@ -122,12 +124,16 @@ main() printf("Key C2 pressed. Exiting...\n"); fflush(stdout); + Pt_Stop(); // xjs + /* Give the echoes time to finish before quitting. */ sleep(((NUM_ECHOES * delay) / 1000) + 1); Pm_Close(midi_in); Pm_Close(midi_out); + Pm_Terminate(); // xjs + printf("Done.\n"); return 0; } diff --git a/pd/portmidi_osx/portmidi.c b/pd/portmidi_osx/portmidi.c index c2a32ae7..c8883303 100644 --- a/pd/portmidi_osx/portmidi.c +++ b/pd/portmidi_osx/portmidi.c @@ -12,13 +12,15 @@ descriptor_node descriptors[pm_descriptor_max]; /* pm_add_device -- describe interface/device pair to library * - * This is called at intialization time, once for each + * This is called at initialization time, once for each * interface (e.g. DirectSound) and device (e.g. SoundBlaster 1) * The strings are retained but NOT COPIED, so do not destroy them! * * returns pmInvalidDeviceId if device memory is exceeded * otherwise returns pmNoError + * */ + PmError pm_add_device(char *interf, char *name, int input, void *descriptor, pm_fns_type dictionary) { @@ -279,7 +281,6 @@ PmError Pm_Abort( PortMidiStream* stream ) return (*midi->dictionary->abort)(midi); } - PmError Pm_Close( PortMidiStream *stream ) { PmInternal *midi = (PmInternal *) stream; @@ -354,5 +355,3 @@ int pm_queue_full(PmInternal *midi) return tail == midi->head; } - - diff --git a/pd/portmidi_osx/portmidi.h b/pd/portmidi_osx/portmidi.h index 3e648c90..1264b6f5 100644 --- a/pd/portmidi_osx/portmidi.h +++ b/pd/portmidi_osx/portmidi.h @@ -43,6 +43,9 @@ extern "C" { * prevent opening an input as output and vice versa. * Added comments and documentation. * Implemented Pm_Terminate(). + * + * 27Jun03 X. J. Scott (XJS) + * - Adding void arg to Pm_GetHostError() to stop compiler gripe. */ #ifndef FALSE @@ -88,7 +91,7 @@ PmError Pm_Terminate( void ); number, call Pm_GetHostError(). This can be called after a function returns a PmError equal to pmHostError. */ -int Pm_GetHostError(); +int Pm_GetHostError( void ); /* xjs - void param to stop compiler gripe */ /* Translate the error number into a human readable message. @@ -111,8 +114,8 @@ typedef int PmDeviceID; typedef struct { int structVersion; - const char *interf; - const char *name; + char const *interf; + char const *name; int input; /* true iff input is available */ int output; /* true iff output is available */ } PmDeviceInfo; diff --git a/pd/portmidi_osx/portmidi_osx_change_log.txt b/pd/portmidi_osx/portmidi_osx_change_log.txt new file mode 100644 index 00000000..80640c3b --- /dev/null +++ b/pd/portmidi_osx/portmidi_osx_change_log.txt @@ -0,0 +1,70 @@ +PortMIDI changes of 27 June 2003 by X. J. Scott + +pmdarwin.c +---------- +- added void parameter list to pm_init and pm_term + (to remove a compiler warning) +- Pm_GetDefaultInputDeviceID() and Pm_GetDefaultOutputDeviceID() + now return id of first input and output devices in system, + rather than returning 0 as before. + This fix enables valid default port values to be returned. + 0 is returned if no such device is found. + +ptdarwin.c +---------- +- added void parameter list to Pt_Stop and Pt_Started + (to remove a compiler warning) +- added void *time_info parameter list to Pt_time + -> since Pt_Time is assigned in pmmacosx.c:get_timestamp() to + a variable of type PMTimeProcPtr, which requires this signature. + +porttime.h +---------- +- added void parameter list to Pt_Stop and Pt_Started +- added void *time_info parameter list to Pt_time + +pmmacosx.c +---------- +- midi_length(): + fixed bug that gave bad lengths for system messages + [note that the F5 message may be an issue for someone + to deal with later since the MIDITimePiece interface appopriated + the F5 for a two byte long CableSelectID - this usage + and length differ from the MIDI standard.] + +/ pm_macosx_init(): + Now allocates the device names. This fixes bug before where + it assigned same string buffer on stack to all devices. +- pm_macosx_term(), deleteDeviceName(): + devices strings allocated during pm_macosx_init() are deallocated. + ++ pm_macosx_init(), newDeviceName(): + registering kMIDIPropertyManufacturer + kMIDIPropertyModel + + kMIDIPropertyName for name strings instead of just name. + +/ pm_macosx_init(): + unsigned i to quiet compiler griping +- get_timestamp(): + no change right here but type of Pt_Time() was altered in porttime.h + so it matches type PmTimeProcPtr in assignment in this function. +/ midi_write(): + changed unsigned to signed to stop compiler griping + +portmidi.h +---------- +- Added void arg to Pm_GetHostError() to stop compiler gripe. + +pmtest.c +--------- +- Added Initialize and Terminate calls so that it doesn't + fail the 2nd time the test is run. + +----- + +PortMIDI changes of 11 Nov 2003 by X. J. Scott + +pmmacosx.c +---------- +- Handles ports that don't have the full set of property strings. + This fixes bug where crash would occur if a virtual port was present. + diff --git a/pd/portmidi_osx/porttime.h b/pd/portmidi_osx/porttime.h index 8592106d..fb57fe7d 100644 --- a/pd/portmidi_osx/porttime.h +++ b/pd/portmidi_osx/porttime.h @@ -1,4 +1,7 @@ -/* porttime.h -- portable interface to millisecond timer */ +/* porttime.h -- portable interface to millisecond timer + * + * 27Jun02 XJS - altered type of Pt_Time() (in porttime.h & portmidi.c) so it matches PmTimeProcPtr + */ /* Should there be a way to choose the source of time here? */ @@ -21,9 +24,9 @@ typedef int (PtCallback)( PtTimestamp timestamp, void *userData ); PtError Pt_Start(int resolution, PtCallback *callback, void *userData); -PtError Pt_Stop(); -int Pt_Started(); -PtTimestamp Pt_Time(); +PtError Pt_Stop(void); // xjs, added void +int Pt_Started(void); // xjs, added void +PtTimestamp Pt_Time(void *time_info); /* xjs - added void *time_info so this f() is a PmTimeProcPtr, defined in portmidi.h */ #ifdef __cplusplus } diff --git a/pd/portmidi_osx/ptdarwin.c b/pd/portmidi_osx/ptdarwin.c index 7df41b1c..0e2357dd 100644 --- a/pd/portmidi_osx/ptdarwin.c +++ b/pd/portmidi_osx/ptdarwin.c @@ -3,7 +3,7 @@ * * Jon Parise * - * $Id: ptdarwin.c,v 1.1.1.1 2003-05-09 16:04:00 ggeiger Exp $ + * $Id: ptdarwin.c,v 1.1.1.2 2004-02-02 11:28:02 ggeiger Exp $ */ #include @@ -28,20 +28,20 @@ PtError Pt_Start(int resolution, PtCallback *callback, void *userData) } -PtError Pt_Stop() +PtError Pt_Stop(void) // xjs added void { time_started_flag = FALSE; return ptNoError; } -int Pt_Started() +int Pt_Started(void) // xjs added void { return time_started_flag; } -PtTimestamp Pt_Time() +PtTimestamp Pt_Time(void *time_info) // xjs added void *time_info { long seconds, milliseconds; struct timeval now; -- cgit v1.2.1