aboutsummaryrefslogtreecommitdiff
path: root/pd/portmidi/pm_common/pminternal.h
diff options
context:
space:
mode:
Diffstat (limited to 'pd/portmidi/pm_common/pminternal.h')
-rw-r--r--pd/portmidi/pm_common/pminternal.h75
1 files changed, 42 insertions, 33 deletions
diff --git a/pd/portmidi/pm_common/pminternal.h b/pd/portmidi/pm_common/pminternal.h
index 20677308..b8c03232 100644
--- a/pd/portmidi/pm_common/pminternal.h
+++ b/pd/portmidi/pm_common/pminternal.h
@@ -28,11 +28,11 @@ void pm_free(void *ptr);
/* if an error occurs while opening or closing a midi stream, set these: */
extern int pm_hosterror;
extern char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN];
-
+
struct pm_internal_struct;
/* these do not use PmInternal because it is not defined yet... */
-typedef PmError (*pm_write_short_fn)(struct pm_internal_struct *midi,
+typedef PmError (*pm_write_short_fn)(struct pm_internal_struct *midi,
PmEvent *buffer);
typedef PmError (*pm_begin_sysex_fn)(struct pm_internal_struct *midi,
PmTimestamp timestamp);
@@ -42,7 +42,8 @@ typedef PmError (*pm_write_byte_fn)(struct pm_internal_struct *midi,
unsigned char byte, PmTimestamp timestamp);
typedef PmError (*pm_write_realtime_fn)(struct pm_internal_struct *midi,
PmEvent *buffer);
-typedef PmError (*pm_write_flush_fn)(struct pm_internal_struct *midi);
+typedef PmError (*pm_write_flush_fn)(struct pm_internal_struct *midi,
+ PmTimestamp timestamp);
typedef PmTimestamp (*pm_synchronize_fn)(struct pm_internal_struct *midi);
/* pm_open_fn should clean up all memory and close the device if any part
of the open fails */
@@ -69,7 +70,7 @@ typedef struct {
pm_abort_fn abort; /* abort */
pm_close_fn close; /* close device */
pm_poll_fn poll; /* read pending midi events into portmidi buffer */
- pm_has_host_error_fn has_host_error; /* true when device has had host
+ pm_has_host_error_fn has_host_error; /* true when device has had host
error message */
pm_host_error_fn host_error; /* provide text readable host error message
for device (clears and resets) */
@@ -83,7 +84,7 @@ typedef struct {
PmDeviceInfo pub; /* some portmidi state also saved in here (for autmatic
device closing (see PmDeviceInfo struct) */
void *descriptor; /* ID number passed to win32 multimedia API open */
- void *internalDescriptor; /* points to PmInternal device, allows automatic
+ void *internalDescriptor; /* points to PmInternal device, allows automatic
device closing */
pm_fns_type dictionary;
} descriptor_node, *descriptor_type;
@@ -97,69 +98,77 @@ typedef unsigned long (*time_get_proc_type)(void *time_info);
typedef struct pm_internal_struct {
int device_id; /* which device is open (index to descriptors) */
short write_flag; /* MIDI_IN, or MIDI_OUT */
-
+
PmTimeProcPtr time_proc; /* where to get the time */
void *time_info; /* pass this to get_time() */
-
- long buffer_len; /* how big is the buffer */
- PmEvent *buffer; /* storage for:
- - midi input
+ long buffer_len; /* how big is the buffer or queue? */
+#ifdef NEWBUFFER
+ PmQueue *queue;
+#else
+ PmEvent *buffer; /* storage for:
+ - midi input
- midi output w/latency != 0 */
long head;
long tail;
-
+ int overflow; /* set to non-zero if input is dropped */
+#endif
long latency; /* time delay in ms between timestamps and actual output */
/* set to zero to get immediate, simple blocking output */
/* if latency is zero, timestamps will be ignored; */
/* if midi input device, this field ignored */
-
- int overflow; /* set to non-zero if input is dropped */
- int flush; /* flag to drop incoming sysex data because of overflow */
- int sysex_in_progress; /* use for overflow management */
+
+ int sysex_in_progress; /* when sysex status is seen, this flag becomes
+ * true until EOX is seen. When true, new data is appended to the
+ * stream of outgoing bytes. When overflow occurs, sysex data is
+ * dropped (until an EOX or non-real-timei status byte is seen) so
+ * that, if the overflow condition is cleared, we don't start
+ * sending data from the middle of a sysex message. If a sysex
+ * message is filtered, sysex_in_progress is false, causing the
+ * message to be dropped. */
PmMessage sysex_message; /* buffer for 4 bytes of sysex data */
int sysex_message_count; /* how many bytes in sysex_message so far */
long filters; /* flags that filter incoming message classes */
- int channel_mask; /* filter incoming messages based on channel */
+ int channel_mask; /* flter incoming messages based on channel */
PmTimestamp last_msg_time; /* timestamp of last message */
PmTimestamp sync_time; /* time of last synchronization */
PmTimestamp now; /* set by PmWrite to current time */
int first_message; /* initially true, used to run first synchronization */
pm_fns_type dictionary; /* implementation functions */
void *descriptor; /* system-dependent state */
-
+ /* the following are used to expedite sysex data */
+ /* on windows, in debug mode, based on some profiling, these optimizations
+ * cut the time to process sysex bytes from about 7.5 to 0.26 usec/byte,
+ * but this does not count time in the driver, so I don't know if it is
+ * important
+ */
+ unsigned char *fill_base; /* addr of ptr to sysex data */
+ int *fill_offset_ptr; /* offset of next sysex byte */
+ int fill_length; /* how many sysex bytes to write */
} PmInternal;
-typedef struct {
- long head;
- long tail;
- long len;
- long msg_size;
- long overflow;
- char *buffer;
-} PmQueueRep;
/* defined by system specific implementation, e.g. pmwinmm, used by PortMidi */
-void pm_init(void);
-void pm_term(void);
+void pm_init(void);
+void pm_term(void);
/* defined by portMidi, used by pmwinmm */
PmError none_write_short(PmInternal *midi, PmEvent *buffer);
-PmError none_sysex(PmInternal *midi, PmTimestamp timestamp);
-PmError none_write_byte(PmInternal *midi, unsigned char byte,
+PmError none_write_byte(PmInternal *midi, unsigned char byte,
PmTimestamp timestamp);
PmTimestamp none_synchronize(PmInternal *midi);
PmError pm_fail_fn(PmInternal *midi);
+PmError pm_fail_timestamp_fn(PmInternal *midi, PmTimestamp timestamp);
PmError pm_success_fn(PmInternal *midi);
PmError pm_add_device(char *interf, char *name, int input, void *descriptor,
pm_fns_type dictionary);
-void pm_read_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp);
-void pm_begin_sysex(PmInternal *midi);
-void pm_end_sysex(PmInternal *midi);
+unsigned int pm_read_bytes(PmInternal *midi, unsigned char *data, int len,
+ PmTimestamp timestamp);
void pm_read_short(PmInternal *midi, PmEvent *event);
-#define none_write_flush pm_fail_fn
+#define none_write_flush pm_fail_timestamp_fn
+#define none_sysex pm_fail_timestamp_fn
#define none_poll pm_fail_fn
#define success_poll pm_success_fn