diff options
author | David Robillard <d@drobilla.net> | 2012-01-03 23:36:19 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2012-01-03 23:36:19 +0000 |
commit | 8eaf389a6aaa4234651e9d568cb7ded6ffe27b09 (patch) | |
tree | 288678dafc4d4c6dc4b5f378514dd900b00949e2 | |
parent | 8d726ac166de79a30e2abad4f4c3a36c23a3fe83 (diff) | |
download | jalv-8eaf389a6aaa4234651e9d568cb7ded6ffe27b09.tar.gz jalv-8eaf389a6aaa4234651e9d568cb7ded6ffe27b09.tar.bz2 jalv-8eaf389a6aaa4234651e9d568cb7ded6ffe27b09.zip |
Don't run plugin while setting state (which violates threading rules).
git-svn-id: http://svn.drobilla.net/lad/trunk/jalv@3913 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r-- | src/jalv.c | 24 | ||||
-rw-r--r-- | src/jalv_internal.h | 8 | ||||
-rw-r--r-- | src/state.c | 5 |
3 files changed, 37 insertions, 0 deletions
@@ -299,6 +299,28 @@ jack_process_cb(jack_nframes_t nframes, void* data) { Jalv* const host = (Jalv*)data; + switch (host->play_state) { + case JALV_PAUSE_REQUESTED: + host->play_state = JALV_PAUSED; + sem_post(&host->paused); + break; + case JALV_PAUSED: + for (uint32_t p = 0; p < host->num_ports; ++p) { + jack_port_t* jport = host->ports[p].jack_port; + if (jport && host->ports[p].flow == FLOW_OUTPUT) { + void* buf = jack_port_get_buffer(jport, nframes); + if (host->ports[p].type == TYPE_EVENT) { + jack_midi_clear_buffer(buf); + } else { + memset(buf, '\0', nframes * sizeof(float)); + } + } + } + return 0; + default: + break; + } + /* Prepare port buffers */ for (uint32_t p = 0; p < host->num_ports; ++p) { if (!host->ports[p].jack_port) @@ -540,6 +562,8 @@ main(int argc, char** argv) sem_init(&exit_sem, 0, 0); host.done = &exit_sem; + sem_init(&host.paused, 0, 0); + signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); diff --git a/src/jalv_internal.h b/src/jalv_internal.h index e4f65ec..5a78c1d 100644 --- a/src/jalv_internal.h +++ b/src/jalv_internal.h @@ -78,6 +78,12 @@ typedef struct { char* load; } JalvOptions; +typedef enum { + JALV_RUNNING, + JALV_PAUSE_REQUESTED, + JALV_PAUSED +} JalvPlayState; + typedef struct { JalvOptions opts; /**< Command-line options */ const char* prog_name; /**< Program name (argv[0]) */ @@ -91,6 +97,8 @@ typedef struct { jack_ringbuffer_t* ui_events; /**< Port events from UI */ jack_ringbuffer_t* plugin_events; /**< Port events from plugin */ sem_t* done; /**< Exit semaphore */ + sem_t paused; /**< Paused signal from process thread */ + JalvPlayState play_state; /**< Current play state */ const LilvPlugin* plugin; /**< Plugin class (RDF data) */ const LilvUI* ui; /**< Plugin UI (RDF data) */ LilvInstance* instance; /**< Plugin instance (shared library) */ diff --git a/src/state.c b/src/state.c index 5edab41..d7a3d5b 100644 --- a/src/state.c +++ b/src/state.c @@ -132,8 +132,13 @@ void jalv_apply_state(Jalv* jalv, LilvState* state) { if (state) { + jalv->play_state = JALV_PAUSE_REQUESTED; + sem_wait(&jalv->paused); + lilv_state_restore( state, jalv->instance, set_port_value, jalv, 0, NULL); + + jalv->play_state = JALV_RUNNING; } } |