diff options
Diffstat (limited to 'libjack/midiport.c')
-rw-r--r-- | libjack/midiport.c | 220 |
1 files changed, 113 insertions, 107 deletions
diff --git a/libjack/midiport.c b/libjack/midiport.c index b673972..d5e607d 100644 --- a/libjack/midiport.c +++ b/libjack/midiport.c @@ -1,21 +1,21 @@ /* Copyright (C) 2004-2006 Ian Esten Copyright (C) 2006 Dave Robillard - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - + You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software + along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ + */ #include <assert.h> #include <stdio.h> @@ -30,47 +30,49 @@ enum { MIDI_INLINE_MAX = 4 }; /* 4 bytes for default event size */ typedef struct _jack_midi_port_info_private { - jack_nframes_t nframes; /**< Number of frames in buffer */ - uint32_t buffer_size; /**< Size of buffer in bytes */ - uint32_t event_count; /**< Number of events stored in this buffer */ - jack_nframes_t last_write_loc; /**< Used for both writing and mixdown */ - uint32_t events_lost; /**< Number of events lost in this buffer */ + jack_nframes_t nframes; /**< Number of frames in buffer */ + uint32_t buffer_size; /**< Size of buffer in bytes */ + uint32_t event_count; /**< Number of events stored in this buffer */ + jack_nframes_t last_write_loc; /**< Used for both writing and mixdown */ + uint32_t events_lost; /**< Number of events lost in this buffer */ } POST_PACKED_STRUCTURE jack_midi_port_info_private_t; typedef struct _jack_midi_port_internal_event { - uint16_t time; /* offset within buffer limit to 64k */ - uint16_t size; /* event size limited to 64k */ - union { - jack_shmsize_t byte_offset; - jack_midi_data_t inline_data[MIDI_INLINE_MAX]; + uint16_t time; /* offset within buffer limit to 64k */ + uint16_t size; /* event size limited to 64k */ + union { + jack_shmsize_t byte_offset; + jack_midi_data_t inline_data[MIDI_INLINE_MAX]; } POST_PACKED_STRUCTURE; } POST_PACKED_STRUCTURE jack_midi_port_internal_event_t; size_t jack_midi_internal_event_size () { - return sizeof (jack_midi_port_internal_event_t); + return sizeof(jack_midi_port_internal_event_t); } static inline jack_midi_data_t* -jack_midi_event_data(void* port_buffer, - const jack_midi_port_internal_event_t* event) +jack_midi_event_data (void* port_buffer, + const jack_midi_port_internal_event_t* event) { - if (event->size <= MIDI_INLINE_MAX) - return (jack_midi_data_t*) event->inline_data; - else - return ((jack_midi_data_t *)port_buffer) + event->byte_offset; + if (event->size <= MIDI_INLINE_MAX) { + return (jack_midi_data_t*)event->inline_data; + } else { + return ((jack_midi_data_t*)port_buffer) + event->byte_offset; + } } /* jack_midi_port_functions.buffer_init */ static void -jack_midi_buffer_init(void *port_buffer, - size_t buffer_size, +jack_midi_buffer_init (void *port_buffer, + size_t buffer_size, jack_nframes_t nframes) { jack_midi_port_info_private_t *info = - (jack_midi_port_info_private_t *) port_buffer; + (jack_midi_port_info_private_t*)port_buffer; + /* We can also add some magic field to midi buffer to validate client calls */ info->nframes = nframes; info->buffer_size = buffer_size; @@ -81,86 +83,90 @@ jack_midi_buffer_init(void *port_buffer, uint32_t -jack_midi_get_event_count(void *port_buffer) +jack_midi_get_event_count (void *port_buffer) { jack_midi_port_info_private_t *info = - (jack_midi_port_info_private_t *) port_buffer; + (jack_midi_port_info_private_t*)port_buffer; + return info->event_count; } int -jack_midi_event_get(jack_midi_event_t *event, - void *port_buffer, - uint32_t event_idx) +jack_midi_event_get (jack_midi_event_t *event, + void *port_buffer, + uint32_t event_idx) { jack_midi_port_internal_event_t *port_event; jack_midi_port_info_private_t *info = - (jack_midi_port_info_private_t *) port_buffer; - + (jack_midi_port_info_private_t*)port_buffer; + if (event_idx >= info->event_count) #ifdef ENODATA - return ENODATA; + { return ENODATA; } #else - return ENOMSG; + { return ENOMSG; } #endif - - port_event = (jack_midi_port_internal_event_t *) (info + 1); + + port_event = (jack_midi_port_internal_event_t*)(info + 1); port_event += event_idx; event->time = port_event->time; event->size = port_event->size; - event->buffer = jack_midi_event_data(port_buffer, port_event); - + event->buffer = jack_midi_event_data (port_buffer, port_event); + return 0; } size_t -jack_midi_max_event_size(void *port_buffer) +jack_midi_max_event_size (void *port_buffer) { jack_midi_port_info_private_t *info = - (jack_midi_port_info_private_t *) port_buffer; + (jack_midi_port_info_private_t*)port_buffer; size_t buffer_size = info->buffer_size; - + /* (event_count + 1) below accounts for jack_midi_port_internal_event_t * which would be needed to store the next event */ size_t used_size = sizeof(jack_midi_port_info_private_t) - + info->last_write_loc - + ((info->event_count + 1) - * sizeof(jack_midi_port_internal_event_t)); - - if (used_size > buffer_size) + + info->last_write_loc + + ((info->event_count + 1) + * sizeof(jack_midi_port_internal_event_t)); + + if (used_size > buffer_size) { return 0; - else if ((buffer_size - used_size) < MIDI_INLINE_MAX) + } else if ((buffer_size - used_size) < MIDI_INLINE_MAX) { return MIDI_INLINE_MAX; - else - return (buffer_size - used_size); + } else { + return buffer_size - used_size; + } } jack_midi_data_t* -jack_midi_event_reserve(void *port_buffer, - jack_nframes_t time, - size_t data_size) +jack_midi_event_reserve (void *port_buffer, + jack_nframes_t time, + size_t data_size) { - jack_midi_data_t *retbuf = (jack_midi_data_t *) port_buffer; + jack_midi_data_t *retbuf = (jack_midi_data_t*)port_buffer; jack_midi_port_info_private_t *info = - (jack_midi_port_info_private_t *) port_buffer; + (jack_midi_port_info_private_t*)port_buffer; jack_midi_port_internal_event_t *event_buffer = - (jack_midi_port_internal_event_t *) (info + 1); + (jack_midi_port_internal_event_t*)(info + 1); size_t buffer_size = info->buffer_size; - - if (time < 0 || time >= info->nframes) - goto failed; - - if (info->event_count > 0 && time < event_buffer[info->event_count-1].time) - goto failed; + + if (time < 0 || time >= info->nframes) { + goto failed; + } + + if (info->event_count > 0 && time < event_buffer[info->event_count - 1].time) { + goto failed; + } /* Check if data_size is >0 and there is enough space in the buffer for the event. */ - if (data_size <=0) { + if (data_size <= 0) { goto failed; // return NULL? } else if (jack_midi_max_event_size (port_buffer) < data_size) { goto failed; @@ -180,23 +186,23 @@ jack_midi_event_reserve(void *port_buffer, info->event_count += 1; return retbuf; } - failed: - info->events_lost++; +failed: + info->events_lost++; return NULL; } int -jack_midi_event_write(void *port_buffer, - jack_nframes_t time, - const jack_midi_data_t *data, - size_t data_size) +jack_midi_event_write (void *port_buffer, + jack_nframes_t time, + const jack_midi_data_t *data, + size_t data_size) { jack_midi_data_t *retbuf = - jack_midi_event_reserve(port_buffer, time, data_size); + jack_midi_event_reserve (port_buffer, time, data_size); if (retbuf) { - memcpy(retbuf, data, data_size); + memcpy (retbuf, data, data_size); return 0; } else { return ENOBUFS; @@ -210,10 +216,10 @@ jack_midi_event_write(void *port_buffer, * been reset. */ void -jack_midi_clear_buffer(void *port_buffer) +jack_midi_clear_buffer (void *port_buffer) { jack_midi_port_info_private_t *info = - (jack_midi_port_info_private_t *) port_buffer; + (jack_midi_port_info_private_t*)port_buffer; info->event_count = 0; info->last_write_loc = 0; @@ -223,40 +229,40 @@ jack_midi_clear_buffer(void *port_buffer) /* jack_midi_port_functions.mixdown */ static void -jack_midi_port_mixdown(jack_port_t *port, jack_nframes_t nframes) +jack_midi_port_mixdown (jack_port_t *port, jack_nframes_t nframes) { JSList *node; jack_port_t *input; - jack_nframes_t num_events = 0; - jack_nframes_t i = 0; - int err = 0; - jack_nframes_t lost_events = 0; + jack_nframes_t num_events = 0; + jack_nframes_t i = 0; + int err = 0; + jack_nframes_t lost_events = 0; /* The next (single) event to mix in to the buffer */ jack_midi_port_info_private_t *earliest_info; jack_midi_port_internal_event_t *earliest_event; jack_midi_data_t *earliest_buffer; - - jack_midi_port_info_private_t *in_info; /* For finding next event */ - jack_midi_port_internal_event_t *in_events; /* Corresponds to in_info */ - jack_midi_port_info_private_t *out_info; /* Output 'buffer' */ - jack_midi_clear_buffer(port->mix_buffer); - - out_info = (jack_midi_port_info_private_t *) port->mix_buffer; + jack_midi_port_info_private_t *in_info; /* For finding next event */ + jack_midi_port_internal_event_t *in_events; /* Corresponds to in_info */ + jack_midi_port_info_private_t *out_info; /* Output 'buffer' */ + + jack_midi_clear_buffer (port->mix_buffer); + + out_info = (jack_midi_port_info_private_t*)port->mix_buffer; /* This function uses jack_midi_port_info_private_t.last_write_loc of the * source ports to store indices of the last event read from that buffer * so far. This is OK because last_write_loc is used when writing events * to a buffer, which at this stage is already complete so the value * can be safely smashed. */ - + /* Iterate through all connections to see how many events we need to mix, * and initialise their 'last event read' (last_write_loc) to 0 */ - for (node = port->connections; node; node = jack_slist_next(node)) { - input = (jack_port_t *) node->data; + for (node = port->connections; node; node = jack_slist_next (node)) { + input = (jack_port_t*)node->data; in_info = - (jack_midi_port_info_private_t *) jack_output_port_buffer(input); + (jack_midi_port_info_private_t*)jack_output_port_buffer (input); num_events += in_info->event_count; lost_events += in_info->events_lost; in_info->last_write_loc = 0; @@ -270,36 +276,36 @@ jack_midi_port_mixdown(jack_port_t *port, jack_nframes_t nframes) /* Find the earliest unread event, to mix next * (search for an event earlier than earliest_event) */ - for (node = port->connections; node; node = jack_slist_next(node)) { - in_info = (jack_midi_port_info_private_t *) - jack_output_port_buffer(((jack_port_t *) node->data)); - in_events = (jack_midi_port_internal_event_t *) (in_info + 1); + for (node = port->connections; node; node = jack_slist_next (node)) { + in_info = (jack_midi_port_info_private_t*) + jack_output_port_buffer (((jack_port_t*)node->data)); + in_events = (jack_midi_port_internal_event_t*)(in_info + 1); /* If there are unread events left in this port.. */ if (in_info->event_count > in_info->last_write_loc) { /* .. and this event is the new earliest .. */ /* NOTE: that's why we compare time with <, not <= */ if (earliest_info == NULL - || in_events[in_info->last_write_loc].time - < earliest_event->time) { + || in_events[in_info->last_write_loc].time + < earliest_event->time) { /* .. then set this event as the next earliest */ earliest_info = in_info; - earliest_event = (jack_midi_port_internal_event_t *) - (&in_events[in_info->last_write_loc]); + earliest_event = (jack_midi_port_internal_event_t*) + (&in_events[in_info->last_write_loc]); } } } if (earliest_info && earliest_event) { - earliest_buffer = (jack_midi_data_t *) earliest_info; - + earliest_buffer = (jack_midi_data_t*)earliest_info; + /* Write event to output */ - err = jack_midi_event_write( - jack_port_buffer(port), + err = jack_midi_event_write ( + jack_port_buffer (port), earliest_event->time, - jack_midi_event_data(earliest_buffer, earliest_event), + jack_midi_event_data (earliest_buffer, earliest_event), earliest_event->size); - + earliest_info->last_write_loc++; if (err) { @@ -308,7 +314,7 @@ jack_midi_port_mixdown(jack_port_t *port, jack_nframes_t nframes) } } } - assert(out_info->event_count == num_events - out_info->events_lost); + assert (out_info->event_count == num_events - out_info->events_lost); // inherit total lost events count from all connected ports. out_info->events_lost += lost_events; @@ -316,12 +322,12 @@ jack_midi_port_mixdown(jack_port_t *port, jack_nframes_t nframes) uint32_t -jack_midi_get_lost_event_count(void *port_buffer) +jack_midi_get_lost_event_count (void *port_buffer) { - return ((jack_midi_port_info_private_t *) port_buffer)->events_lost; + return ((jack_midi_port_info_private_t*)port_buffer)->events_lost; } jack_port_functions_t jack_builtin_midi_functions = { - .buffer_init = jack_midi_buffer_init, - .mixdown = jack_midi_port_mixdown, + .buffer_init = jack_midi_buffer_init, + .mixdown = jack_midi_port_mixdown, }; |