aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2015-12-09 11:15:25 +0100
committerHanspeter Portner <dev@open-music-kontrollers.ch>2015-12-09 11:15:25 +0100
commit4149f55d01fa516f267c0fdca3ebaa766b5b09c3 (patch)
tree68602f826b2f510ea2f26a43938f602809a8a0d1
parenta1bca1680e6dfcde9c85ec890f5d67f4cb236a8d (diff)
downloadsynthpod-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.c21
-rw-r--r--bin/synthpod_bin.h29
-rw-r--r--bin/synthpod_jack.c21
-rw-r--r--plugins/synthpod_stereo.c143
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();
}