aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-01-03 23:36:19 +0000
committerDavid Robillard <d@drobilla.net>2012-01-03 23:36:19 +0000
commit8eaf389a6aaa4234651e9d568cb7ded6ffe27b09 (patch)
tree288678dafc4d4c6dc4b5f378514dd900b00949e2
parent8d726ac166de79a30e2abad4f4c3a36c23a3fe83 (diff)
downloadjalv-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.c24
-rw-r--r--src/jalv_internal.h8
-rw-r--r--src/state.c5
3 files changed, 37 insertions, 0 deletions
diff --git a/src/jalv.c b/src/jalv.c
index 2bd6266..b79c561 100644
--- a/src/jalv.c
+++ b/src/jalv.c
@@ -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;
}
}