int rb_write_to_buffer(ring_buffer *buffer, int n, ...) { if (!buffer) return -1; int write_idx = buffer->write_idx; // No need for sync in writer thread. int available = rb_available_to_write(buffer); va_list args; va_start(args, n); int i; for (i = 0; i < n; ++i) { const char* src = va_arg(args, const char*); int len = va_arg(args, int); available -= len; if (len < 0 || available < 0) return -1; if (write_idx + len <= buffer->size) { memcpy(buffer->buf_ptr + write_idx, src, len); } else { int d = buffer->size - write_idx; memcpy(buffer->buf_ptr + write_idx, src, d); memcpy(buffer->buf_ptr, src + d, len - d); } write_idx = (write_idx + len) % buffer->size; } va_end(args); SYNC_COMPARE_AND_SWAP(&(buffer->write_idx), buffer->write_idx, write_idx); // Includes memory barrier. return 0; }
static void internal_listhook(const char *src, int argc, t_atom *argv) { int n = argc * S_ATOM; if (rb_available_to_write(pd_receive_buffer) >= S_PD_PARAMS + n) { pd_params p = {LIBPD_LIST, src, 0.0f, NULL, argc}; rb_write_to_buffer(pd_receive_buffer, (const char *)&p, S_PD_PARAMS); rb_write_to_buffer(pd_receive_buffer, (const char *)argv, n); } }
static void internal_messagehook(const char *src, const char* sym, int argc, t_atom *argv) { int n = argc * S_ATOM; if (rb_available_to_write(pd_receive_buffer) >= S_PD_PARAMS + n) { pd_params p = {LIBPD_MESSAGE, src, 0.0f, sym, argc}; rb_write_to_buffer(pd_receive_buffer, (const char *)&p, S_PD_PARAMS); rb_write_to_buffer(pd_receive_buffer, (const char *)argv, n); } }
static void internal_printhook(const char *s) { static char padding[LIBPD_WORD_ALIGN]; int len = strlen(s) + 1; // remember terminating null char int rest = len % LIBPD_WORD_ALIGN; if (rest) rest = LIBPD_WORD_ALIGN - rest; int total = len + rest; if (rb_available_to_write(pd_receive_buffer) >= S_PD_PARAMS + total) { pd_params p = {LIBPD_PRINT, NULL, 0.0f, NULL, total, 0, 0, 0}; rb_write_to_buffer(pd_receive_buffer, (const char *)&p, S_PD_PARAMS); rb_write_to_buffer(pd_receive_buffer, s, len); rb_write_to_buffer(pd_receive_buffer, padding, rest); } }
static void internal_midibytehook(int port, int byte) { if (rb_available_to_write(midi_receive_buffer) >= S_MIDI_PARAMS) { midi_params p = {LIBPD_MIDIBYTE, port, byte, 0}; rb_write_to_buffer(midi_receive_buffer, (const char *)&p, S_MIDI_PARAMS); } }
static void internal_polyaftertouchhook(int channel, int pitch, int value) { if (rb_available_to_write(midi_receive_buffer) >= S_MIDI_PARAMS) { midi_params p = {LIBPD_POLYAFTERTOUCH, channel, pitch, value}; rb_write_to_buffer(midi_receive_buffer, (const char *)&p, S_MIDI_PARAMS); } }
static void internal_pitchbendhook(int channel, int value) { if (rb_available_to_write(midi_receive_buffer) >= S_MIDI_PARAMS) { midi_params p = {LIBPD_PITCHBEND, channel, value, 0}; rb_write_to_buffer(midi_receive_buffer, (const char *)&p, S_MIDI_PARAMS); } }
static void internal_programchangehook(int channel, int value) { if (rb_available_to_write(midi_receive_buffer) >= S_MIDI_PARAMS) { midi_params p = {LIBPD_PROGRAMCHANGE, channel, value, 0}; rb_write_to_buffer(midi_receive_buffer, (const char *)&p, S_MIDI_PARAMS); } }
static void internal_controlchangehook(int channel, int controller, int value) { if (rb_available_to_write(midi_receive_buffer) >= S_MIDI_PARAMS) { midi_params p = {LIBPD_CONTROLCHANGE, channel, controller, value}; rb_write_to_buffer(midi_receive_buffer, (const char *)&p, S_MIDI_PARAMS); } }
static void internal_noteonhook(int channel, int pitch, int velocity) { if (rb_available_to_write(midi_receive_buffer) >= S_MIDI_PARAMS) { midi_params p = {LIBPD_NOTEON, channel, pitch, velocity}; rb_write_to_buffer(midi_receive_buffer, (const char *)&p, S_MIDI_PARAMS); } }
static void internal_symbolhook(const char *src, const char *sym) { if (rb_available_to_write(pd_receive_buffer) >= S_PD_PARAMS) { pd_params p = {LIBPD_SYMBOL, src, 0.0f, sym, 0}; rb_write_to_buffer(pd_receive_buffer, (const char *)&p, S_PD_PARAMS); } }
static void internal_floathook(const char *src, float x) { if (rb_available_to_write(pd_receive_buffer) >= S_PD_PARAMS) { pd_params p = {LIBPD_FLOAT, src, x, NULL, 0}; rb_write_to_buffer(pd_receive_buffer, (const char *)&p, S_PD_PARAMS); } }
static void internal_banghook(const char *src) { if (rb_available_to_write(pd_receive_buffer) >= S_PD_PARAMS) { pd_params p = {LIBPD_BANG, src, 0.0f, NULL, 0}; rb_write_to_buffer(pd_receive_buffer, (const char *)&p, S_PD_PARAMS); } }