aboutsummaryrefslogtreecommitdiff
path: root/pd/portmidi_osx
diff options
context:
space:
mode:
Diffstat (limited to 'pd/portmidi_osx')
-rw-r--r--pd/portmidi_osx/pmdarwin.c52
-rw-r--r--pd/portmidi_osx/pmmacosx.c149
-rw-r--r--pd/portmidi_osx/pmtest.c12
-rw-r--r--pd/portmidi_osx/portmidi.c7
-rw-r--r--pd/portmidi_osx/portmidi.h9
-rw-r--r--pd/portmidi_osx/portmidi_osx_change_log.txt70
-rw-r--r--pd/portmidi_osx/porttime.h11
-rw-r--r--pd/portmidi_osx/ptdarwin.c8
8 files changed, 272 insertions, 46 deletions
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 <jparise@cmu.edu>
*
- * $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 <jparise@cmu.edu>
*
- * $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 <CoreServices/CoreServices.h>
#include <CoreMIDI/MIDIServices.h>
+#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, "<undef. manuf>");
+
+ iErr = MIDIObjectGetStringProperty(endpoint, kMIDIPropertyModel, &deviceCFString);
+ if (noErr == iErr) {
+ CFStringGetCString(deviceCFString, modelBuf, sizeof(modelBuf), defaultEncoding);
+ CFRelease(deviceCFString);
+ }
+ else
+ strcpy(modelBuf, "<undef. model>");
+
+ iErr = MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &deviceCFString);
+ if (noErr == iErr) {
+ CFStringGetCString(deviceCFString, nameBuf, sizeof(nameBuf), defaultEncoding);
+ CFRelease(deviceCFString);
+ }
+ else
+ strcpy(nameBuf, "<undef. name>");
+
+ 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 <jparise@cmu.edu>
*
- * $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 <stdio.h>
@@ -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;