diff options
author | Hanspeter Portner <dev@open-music-kontrollers.ch> | 2015-12-09 11:15:25 +0100 |
---|---|---|
committer | Hanspeter Portner <dev@open-music-kontrollers.ch> | 2015-12-09 11:15:25 +0100 |
commit | 4149f55d01fa516f267c0fdca3ebaa766b5b09c3 (patch) | |
tree | 68602f826b2f510ea2f26a43938f602809a8a0d1 | |
parent | a1bca1680e6dfcde9c85ec890f5d67f4cb236a8d (diff) | |
download | synthpod-4149f55d01fa516f267c0fdca3ebaa766b5b09c3.tar.xz |
add feedback ringbuffers for com ports.
* queue events on feedback ringbuffers when app in blocking mode.
-rw-r--r-- | bin/synthpod_alsa.c | 21 | ||||
-rw-r--r-- | bin/synthpod_bin.h | 29 | ||||
-rw-r--r-- | bin/synthpod_jack.c | 21 | ||||
-rw-r--r-- | plugins/synthpod_stereo.c | 143 |
4 files changed, 147 insertions, 67 deletions
diff --git a/bin/synthpod_alsa.c b/bin/synthpod_alsa.c index ca741d8b..abefc94e 100644 --- a/bin/synthpod_alsa.c +++ b/bin/synthpod_alsa.c @@ -418,8 +418,25 @@ _rt_thread(void *data, Eina_Thread thread) { const LV2_Atom *atom = &ev->body; - //FIXME is this the right place? - bool advance = sp_app_from_ui(bin->app, atom); //FIXME solve this differently + // try do process events directly + bin->advance_ui = sp_app_from_ui(bin->app, atom); + if(!bin->advance_ui) // queue event in ringbuffer instead + { + //fprintf(stderr, "plugin ui direct is blocked\n"); + + void *ptr; + size_t size = lv2_atom_total_size(atom); + if((ptr = varchunk_write_request(bin->app_from_app, size))) + { + memcpy(ptr, atom, size); + varchunk_write_advance(bin->app_from_app, size); + } + else + { + //fprintf(stderr, "app_from_ui ringbuffer full\n"); + //FIXME + } + } } break; } diff --git a/bin/synthpod_bin.h b/bin/synthpod_bin.h index 4b3607d2..cfa7da55 100644 --- a/bin/synthpod_bin.h +++ b/bin/synthpod_bin.h @@ -69,6 +69,9 @@ struct _bin_t { varchunk_t *app_from_com; + bool advance_ui; + varchunk_t *app_from_app; + char *path; synthpod_nsm_t *nsm; @@ -362,6 +365,7 @@ bin_init(bin_t *bin) bin->app_from_worker = varchunk_new(CHUNK_SIZE); bin->app_to_log = varchunk_new(CHUNK_SIZE); bin->app_from_com = varchunk_new(CHUNK_SIZE); + bin->app_from_app = varchunk_new(CHUNK_SIZE); bin->ext_urid = ext_urid_new(); LV2_URID_Map *map = ext_urid_map_get(bin->ext_urid); @@ -478,6 +482,7 @@ bin_deinit(bin_t *bin) varchunk_free(bin->app_to_worker); varchunk_free(bin->app_from_worker); varchunk_free(bin->app_from_com); + varchunk_free(bin->app_from_app); } static inline void @@ -504,7 +509,7 @@ bin_process_pre(bin_t *bin, uint32_t nsamples) // run synthpod app pre sp_app_run_pre(bin->app, nsamples); - // read events from UI + // read events from UI ringbuffer { size_t size; const LV2_Atom *atom; @@ -512,8 +517,8 @@ bin_process_pre(bin_t *bin, uint32_t nsamples) while((atom = varchunk_read_request(bin->app_from_ui, &size)) && (n++ < MAX_MSGS) ) { - bool advance = sp_app_from_ui(bin->app, atom); - if(!advance) + bin->advance_ui = sp_app_from_ui(bin->app, atom); + if(!bin->advance_ui) { //fprintf(stderr, "ui is blocked\n"); break; @@ -521,6 +526,24 @@ bin_process_pre(bin_t *bin, uint32_t nsamples) varchunk_read_advance(bin->app_from_ui); } } + + // read events from feedback ringbuffer + { + size_t size; + const LV2_Atom *atom; + unsigned n = 0; + while((atom = varchunk_read_request(bin->app_from_app, &size)) + && (n++ < MAX_MSGS) ) + { + bin->advance_ui = sp_app_from_ui(bin->app, atom); + if(!bin->advance_ui) + { + //fprintf(stderr, "ui is blocked\n"); + break; + } + varchunk_read_advance(bin->app_from_app); + } + } // run synthpod app post sp_app_run_post(bin->app, nsamples); diff --git a/bin/synthpod_jack.c b/bin/synthpod_jack.c index 634c7381..4a254703 100644 --- a/bin/synthpod_jack.c +++ b/bin/synthpod_jack.c @@ -660,8 +660,25 @@ _process(jack_nframes_t nsamples, void *data) { const LV2_Atom *atom = (const LV2_Atom *)&ev->body; - //FIXME is this the right place? - bool advance = sp_app_from_ui(bin->app, atom); //FIXME solve this differently + // try do process events directly + bin->advance_ui = sp_app_from_ui(bin->app, atom); + if(!bin->advance_ui) // queue event in ringbuffer instead + { + //fprintf(stderr, "plugin ui direct is blocked\n"); + + void *ptr; + size_t size = lv2_atom_total_size(atom); + if((ptr = varchunk_write_request(bin->app_from_app, size))) + { + memcpy(ptr, atom, size); + varchunk_write_advance(bin->app_from_app, size); + } + else + { + //fprintf(stderr, "app_from_ui ringbuffer full\n"); + //FIXME + } + } } break; } diff --git a/plugins/synthpod_stereo.c b/plugins/synthpod_stereo.c index 5a31f812..9297abb2 100644 --- a/plugins/synthpod_stereo.c +++ b/plugins/synthpod_stereo.c @@ -114,6 +114,7 @@ struct _plughandle_t { varchunk_t *app_to_worker; varchunk_t *app_from_worker; varchunk_t *app_from_ui; + varchunk_t *app_from_app; }; static int @@ -463,6 +464,7 @@ instantiate(const LV2_Descriptor* descriptor, double rate, handle->app_to_worker = varchunk_new(CHUNK_SIZE); handle->app_from_worker = varchunk_new(CHUNK_SIZE); handle->app_from_ui = varchunk_new(CHUNK_SIZE); + handle->app_from_app = varchunk_new(CHUNK_SIZE); handle->driver.to_ui_request = _to_ui_request; handle->driver.to_ui_advance = _to_ui_advance; @@ -606,6 +608,24 @@ _process_pre(plughandle_t *handle, uint32_t nsamples) } } + // drain events from feedback ringbuffer + { + const LV2_Atom *atom; + size_t size; + unsigned n = 0; + while((atom = varchunk_read_request(handle->app_from_app, &size)) + && (n++ < MAX_MSGS) ) + { + handle->advance_ui = sp_app_from_ui(app, atom); + if(!handle->advance_ui) + { + //fprintf(stderr, "plugin feedback is blocked\n"); + break; + } + varchunk_read_advance(handle->app_from_app); + } + } + //FIXME drain event from separate feedback ringbuffer // handle events from UI @@ -649,6 +669,27 @@ _process_pre(plughandle_t *handle, uint32_t nsamples) // run app post sp_app_run_post(app, nsamples); + + // write com events to feedback buffer + if(handle->sink.com_out) + { + LV2_ATOM_SEQUENCE_FOREACH(handle->sink.com_out, ev) + { + const LV2_Atom *atom = &ev->body; + + void *ptr; + size_t size = lv2_atom_total_size(atom); + if((ptr = varchunk_write_request(handle->app_from_app, size))) + { + memcpy(ptr, atom, size); + varchunk_write_advance(handle->app_from_app, size); + } + else + { + //FIXME + } + } + } } static inline void @@ -689,6 +730,7 @@ run(LV2_Handle instance, uint32_t nsamples) const size_t sample_buf_size = sizeof(float) * nsamples; + // get input buffers handle->source.event_in = NULL; handle->source.audio_in[0] = NULL; handle->source.audio_in[1] = NULL; @@ -744,6 +786,46 @@ run(LV2_Handle instance, uint32_t nsamples) if(handle->source.input[3]) *handle->source.input[3] = *handle->port.input[3]; + // get output buffers + const sp_app_system_sink_t *sinks = sp_app_get_system_sinks(app); + + // fill output buffers + handle->sink.event_out = NULL; + handle->sink.audio_out[0] = NULL; + handle->sink.audio_out[1] = NULL; + handle->sink.output[0] = NULL; + handle->sink.output[1] = NULL; + handle->sink.output[2] = NULL; + handle->sink.output[3] = NULL; + + audio_ptr = 0; + control_ptr = 0; + for(const sp_app_system_sink_t *sink=sinks; + sink->type != SYSTEM_PORT_NONE; + sink++) + { + switch(sink->type) + { + case SYSTEM_PORT_MIDI: + handle->sink.event_out = sink->buf; + break; + case SYSTEM_PORT_AUDIO: + handle->sink.audio_out[audio_ptr++] = sink->buf; + break; + case SYSTEM_PORT_CONTROL: + handle->sink.output[control_ptr++] = sink->buf; + break; + case SYSTEM_PORT_COM: + handle->sink.com_out = sink->buf; + break; + + case SYSTEM_PORT_CV: + case SYSTEM_PORT_OSC: + case SYSTEM_PORT_NONE: + break; + } + } + if(handle->dirty_in) { //printf("dirty\n"); @@ -800,45 +882,6 @@ run(LV2_Handle instance, uint32_t nsamples) lv2_atom_forge_pop(&handle->forge.event_out, &frame.event_out); lv2_atom_forge_pop(&handle->forge.com_in, &frame.com_in); lv2_atom_forge_pop(&handle->forge.notify, &frame.notify); - - const sp_app_system_sink_t *sinks = sp_app_get_system_sinks(app); - - // fill output buffers - handle->sink.event_out = NULL; - handle->sink.audio_out[0] = NULL; - handle->sink.audio_out[1] = NULL; - handle->sink.output[0] = NULL; - handle->sink.output[1] = NULL; - handle->sink.output[2] = NULL; - handle->sink.output[3] = NULL; - - audio_ptr = 0; - control_ptr = 0; - for(const sp_app_system_sink_t *sink=sinks; - sink->type != SYSTEM_PORT_NONE; - sink++) - { - switch(sink->type) - { - case SYSTEM_PORT_MIDI: - handle->sink.event_out = sink->buf; - break; - case SYSTEM_PORT_AUDIO: - handle->sink.audio_out[audio_ptr++] = sink->buf; - break; - case SYSTEM_PORT_CONTROL: - handle->sink.output[control_ptr++] = sink->buf; - break; - case SYSTEM_PORT_COM: - handle->sink.com_out = sink->buf; - break; - - case SYSTEM_PORT_CV: - case SYSTEM_PORT_OSC: - case SYSTEM_PORT_NONE: - break; - } - } if(handle->sink.event_out) memcpy(handle->port.event_out, handle->sink.event_out, SEQ_SIZE); @@ -859,27 +902,6 @@ run(LV2_Handle instance, uint32_t nsamples) *handle->port.output[1] = handle->sink.output[1] ? *handle->sink.output[1] : 0.f; *handle->port.output[2] = handle->sink.output[2] ? *handle->sink.output[2] : 0.f; *handle->port.output[3] = handle->sink.output[3] ? *handle->sink.output[3] : 0.f; - - //FIXME use separate feedback ringbuffer - if(handle->sink.com_out) - { - LV2_ATOM_SEQUENCE_FOREACH(handle->sink.com_out, ev) - { - const LV2_Atom *atom = &ev->body; - - void *ptr; - size_t size = lv2_atom_total_size(atom); - if((ptr = varchunk_write_request(handle->app_from_ui, size))) - { - memcpy(ptr, atom, size); - varchunk_write_advance(handle->app_from_ui, size); - } - else - { - //FIXME - } - } - } } static void @@ -901,6 +923,7 @@ cleanup(LV2_Handle instance) varchunk_free(handle->app_to_worker); varchunk_free(handle->app_from_worker); varchunk_free(handle->app_from_ui); + varchunk_free(handle->app_from_app); eina_shutdown(); } |