aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Hanspeter Portner <dev@open-music-kontrollers.ch>2019-07-28 20:54:12 +0200
committerGravatar Hanspeter Portner <dev@open-music-kontrollers.ch>2019-07-28 20:54:12 +0200
commit388bac5ba227b9ba3a71c92570a0d3d6717cca16 (patch)
tree3c0a73868cbb04f5712a6436bf6255a35b22838d
parent4e7ce79573a772f8f3b06fdfcdee45629a9fe4ae (diff)
downloadsynthpod-388bac5ba227b9ba3a71c92570a0d3d6717cca16.zip
synthpod-388bac5ba227b9ba3a71c92570a0d3d6717cca16.tar.gz
synthpod-388bac5ba227b9ba3a71c92570a0d3d6717cca16.tar.bz2
synthpod-388bac5ba227b9ba3a71c92570a0d3d6717cca16.tar.xz
bin: deprecate JACK session, add NSM switch-mode.
-rw-r--r--README.md3
-rw-r--r--VERSION2
-rw-r--r--app/synthpod_app.c6
-rw-r--r--app/synthpod_app_private.h2
-rw-r--r--app/synthpod_app_worker.c44
-rw-r--r--bin/synthpod_alsa.c69
-rw-r--r--bin/synthpod_bin.c46
-rw-r--r--bin/synthpod_bin.h13
-rw-r--r--bin/synthpod_dummy.c61
-rw-r--r--bin/synthpod_jack.c191
-rw-r--r--include/synthpod_app.h8
-rw-r--r--nsmc/nsmc.h39
12 files changed, 216 insertions, 268 deletions
diff --git a/README.md b/README.md
index 8816163..69d7f5f 100644
--- a/README.md
+++ b/README.md
@@ -266,8 +266,7 @@ with support for native JACK audio, MIDI, OSC and CV in/out ports.
The right choice on GNU/Linux for modular setups.
This standalone host supports
-[NON session management](http://non.tuxfamily.org/nsm/API.html) and
-[JACK session management](http://jackaudio.org/files/docs/html/group__SessionClientFunctions.html)
+[NON session management](http://non.tuxfamily.org/nsm/API.html)
to neatly integrate into modular setups.
#### ALSA
diff --git a/VERSION b/VERSION
index 7530e28..98e4da3 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.6039
+0.1.6041
diff --git a/app/synthpod_app.c b/app/synthpod_app.c
index 75e4317..f545f12 100644
--- a/app/synthpod_app.c
+++ b/app/synthpod_app.c
@@ -1492,3 +1492,9 @@ sp_app_set_bundle_path(sp_app_t *app, const char *bundle_path)
app->bundle_path = strdup(bundle_path);
}
+
+void
+sp_app_bundle_reset(sp_app_t *app)
+{
+ _sp_app_reset(app);
+}
diff --git a/app/synthpod_app_private.h b/app/synthpod_app_private.h
index 5d2c156..7cf0359 100644
--- a/app/synthpod_app_private.h
+++ b/app/synthpod_app_private.h
@@ -125,6 +125,8 @@ enum _job_type_request_t {
JOB_TYPE_REQUEST_PRESET_SAVE,
JOB_TYPE_REQUEST_BUNDLE_LOAD,
JOB_TYPE_REQUEST_BUNDLE_SAVE,
+ JOB_TYPE_REQUEST_BUNDLE_LOAD_STATUS,
+ JOB_TYPE_REQUEST_BUNDLE_SAVE_STATUS,
JOB_TYPE_REQUEST_DRAIN
};
diff --git a/app/synthpod_app_worker.c b/app/synthpod_app_worker.c
index e53952c..3656d49 100644
--- a/app/synthpod_app_worker.c
+++ b/app/synthpod_app_worker.c
@@ -247,6 +247,19 @@ sp_app_from_worker(sp_app_t *app, uint32_t len, const void *data)
assert(app->load_bundle == true);
app->load_bundle = false; // for sp_app_bypassed
+ // signal to worker
+ job_t *job1 = _sp_app_to_worker_request(app, sizeof(job_t));
+ if(job1)
+ {
+ job1->reply = JOB_TYPE_REQUEST_BUNDLE_LOAD_STATUS;
+ job1->status = job->status;
+ _sp_app_to_worker_advance(app, sizeof(job_t));
+ }
+ else
+ {
+ sp_app_log_trace(app, "%s: buffer request failed\n", __func__);
+ }
+
#if 0
// signal to UI
size_t size = sizeof(transmit_bundle_load_t)
@@ -270,6 +283,19 @@ sp_app_from_worker(sp_app_t *app, uint32_t len, const void *data)
app->block_state = BLOCKING_STATE_RUN; // release block
assert(app->load_bundle == false);
+ // signal to worker
+ job_t *job1 = _sp_app_to_worker_request(app, sizeof(job_t));
+ if(job1)
+ {
+ job1->reply = JOB_TYPE_REQUEST_BUNDLE_SAVE_STATUS;
+ job1->status = job->status;
+ _sp_app_to_worker_advance(app, sizeof(job_t));
+ }
+ else
+ {
+ sp_app_log_trace(app, "%s: buffer request failed\n", __func__);
+ }
+
#if 0
// signal to UI
size_t size = sizeof(transmit_bundle_save_t)
@@ -441,6 +467,24 @@ sp_worker_from_app(sp_app_t *app, uint32_t len, const void *data)
break;
}
+ case JOB_TYPE_REQUEST_BUNDLE_LOAD_STATUS:
+ {
+ if(app->driver->opened)
+ {
+ app->driver->opened(app->data, job->status);
+ }
+
+ break;
+ }
+ case JOB_TYPE_REQUEST_BUNDLE_SAVE_STATUS:
+ {
+ if(app->driver->saved)
+ {
+ app->driver->saved(app->data, job->status);
+ }
+
+ break;
+ }
case JOB_TYPE_REQUEST_DRAIN:
{
// signal to app
diff --git a/bin/synthpod_alsa.c b/bin/synthpod_alsa.c
index 9caa059..d8c1cd7 100644
--- a/bin/synthpod_alsa.c
+++ b/bin/synthpod_alsa.c
@@ -75,7 +75,6 @@ struct _prog_t {
int queue;
uint8_t m [MIDI_SEQ_SIZE];
- save_state_t save_state;
atomic_int kill;
pthread_t thread;
@@ -690,23 +689,6 @@ _system_port_del(void *data, void *sys_port)
free(chan);
}
-__non_realtime static void
-_saved(bin_t *bin, int status)
-{
- prog_t *handle = (void *)bin - offsetof(prog_t, bin);
-
- if(handle->save_state == SAVE_STATE_NSM)
- {
- nsmc_saved(bin->nsm, status);
- }
- handle->save_state = SAVE_STATE_INTERNAL;
-
- if(atomic_load_explicit(&handle->kill, memory_order_relaxed))
- {
- bin_quit(bin);
- }
-}
-
static int
_alsa_init(prog_t *handle, const char *id)
{
@@ -772,35 +754,39 @@ _open(const char *path, const char *name, const char *id, void *data)
prog_t *handle = (void *)bin - offsetof(prog_t, bin);
(void)name;
+ const bool switch_over = bin->app ? true : false;
+
if(bin->path)
free(bin->path);
bin->path = strdup(path);
- // alsa init
- if(_alsa_init(handle, id))
+ if(!switch_over)
{
- nsmc_opened(bin->nsm, -1);
- return -1;
- }
+ // alsa init
+ if(_alsa_init(handle, id))
+ {
+ nsmc_opened(bin->nsm, -1);
+ return -1;
+ }
- // synthpod init
- bin->app_driver.sample_rate = handle->srate;
- bin->app_driver.update_rate = handle->bin.update_rate;
- bin->app_driver.max_block_size = handle->frsize;
- bin->app_driver.min_block_size = 1;
- bin->app_driver.seq_size = handle->seq_size;
- bin->app_driver.num_periods = handle->nfrags;
-
- // app init
- bin->app = sp_app_new(NULL, &bin->app_driver, bin);
+ // synthpod init
+ bin->app_driver.sample_rate = handle->srate;
+ bin->app_driver.update_rate = handle->bin.update_rate;
+ bin->app_driver.max_block_size = handle->frsize;
+ bin->app_driver.min_block_size = 1;
+ bin->app_driver.seq_size = handle->seq_size;
+ bin->app_driver.num_periods = handle->nfrags;
+
+ // app init
+ bin->app = sp_app_new(NULL, &bin->app_driver, bin);
- // alsa activate
- atomic_init(&handle->kill, 0);
- if(pthread_create(&handle->thread, NULL, _rt_thread, handle))
- bin_log_error(bin, "%s: creation of realtime thread failed\n", __func__);
+ // alsa activate
+ atomic_init(&handle->kill, 0);
+ if(pthread_create(&handle->thread, NULL, _rt_thread, handle))
+ bin_log_error(bin, "%s: creation of realtime thread failed\n", __func__);
+ }
bin_bundle_load(bin, bin->path);
- nsmc_opened(bin->nsm, 0);
return 0; // success
}
@@ -811,9 +797,7 @@ _save(void *data)
bin_t *bin = data;
prog_t *handle = (void *)bin - offsetof(prog_t, bin);
- handle->save_state = SAVE_STATE_NSM;
bin_bundle_save(bin, bin->path);
- _saved(bin, 0);
return 0; // success
}
@@ -838,7 +822,8 @@ static const nsmc_driver_t nsm_driver = {
.open = _open,
.save = _save,
.show = _show,
- .hide = _hide
+ .hide = _hide,
+ .supports_switch = true
};
// rt
@@ -1119,7 +1104,7 @@ main(int argc, char **argv)
bin->app_driver.features |= SP_APP_FEATURE_POWER_OF_2_BLOCK_LENGTH;
// run
- bin_run(bin, argv, &nsm_driver, NULL, NULL);
+ bin_run(bin, "Synthpod-ALSA", argv, &nsm_driver);
// stop
bin_stop(bin);
diff --git a/bin/synthpod_bin.c b/bin/synthpod_bin.c
index cd63080..b780f70 100644
--- a/bin/synthpod_bin.c
+++ b/bin/synthpod_bin.c
@@ -82,6 +82,22 @@ _close_request(void *data)
bin_quit(bin);
}
+__non_realtime static void
+_opened(void *data, int status)
+{
+ bin_t *bin = data;
+
+ nsmc_opened(bin->nsm, status);
+}
+
+__non_realtime static void
+_saved(void *data, int status)
+{
+ bin_t *bin = data;
+
+ nsmc_saved(bin->nsm, status);
+}
+
__realtime static void *
_app_to_ui_request(size_t minimum, size_t *maximum, void *data)
{
@@ -388,6 +404,8 @@ bin_init(bin_t *bin, uint32_t sample_rate)
bin->app_driver.bad_plugins = bin->bad_plugins;
bin->app_driver.cpu_affinity = bin->cpu_affinity;
bin->app_driver.close_request = _close_request;
+ bin->app_driver.opened = _opened;
+ bin->app_driver.saved = _saved;
bin->worker_thread = pthread_self(); // thread ID of UI thread
bin->first = true;
@@ -404,9 +422,12 @@ bin_init(bin_t *bin, uint32_t sample_rate)
signal(SIGQUIT, _sig);
signal(SIGINT, _sig);
- if(bin->has_gui)
+ if(!nsmc_managed())
{
- bin_show(bin);
+ if(bin->has_gui)
+ {
+ bin_show(bin);
+ }
}
cross_clock_init(&bin->clk_mono, CROSS_CLOCK_MONOTONIC);
@@ -414,8 +435,7 @@ bin_init(bin_t *bin, uint32_t sample_rate)
}
__realtime void
-bin_run(bin_t *bin, char **argv, const nsmc_driver_t *nsm_driver,
- void (*idle)(void *data), void *data)
+bin_run(bin_t *bin, const char *name, char **argv, const nsmc_driver_t *nsm_driver)
{
char *fallback_path = NULL;
@@ -435,7 +455,7 @@ bin_run(bin_t *bin, char **argv, const nsmc_driver_t *nsm_driver,
// NSM init
const char *exe = strrchr(argv[0], '/');
exe = exe ? exe + 1 : argv[0]; // we only want the program name without path
- bin->nsm = nsmc_new("Synthpod", exe, fallback_path ? fallback_path : argv[optind],
+ bin->nsm = nsmc_new(name, exe, fallback_path ? fallback_path : argv[optind],
nsm_driver, bin); //TODO check
if(fallback_path)
@@ -498,7 +518,7 @@ bin_run(bin_t *bin, char **argv, const nsmc_driver_t *nsm_driver,
{
bin->child = 0; // invalidate
- if(nsmc_managed(bin->nsm))
+ if(nsmc_managed())
nsmc_hidden(bin->nsm);
if(bin->kill_gui)
@@ -550,15 +570,9 @@ bin_run(bin_t *bin, char **argv, const nsmc_driver_t *nsm_driver,
}
// run NSM
- if(nsmc_managed(bin->nsm))
+ if(nsmc_managed())
nsmc_run(bin->nsm);
- // rund idle callback
- if(idle)
- {
- idle(data);
- }
-
//sched_yield();
}
}
@@ -687,6 +701,12 @@ bin_bundle_load(bin_t *bin, const char *bundle_path)
}
__non_realtime void
+bin_bundle_reset(bin_t *bin)
+{
+ sp_app_bundle_reset(bin->app);
+}
+
+__non_realtime void
bin_bundle_save(bin_t *bin, const char *bundle_path)
{
const LV2_URID urn = bin->map->map(bin->map->handle, bundle_path);
diff --git a/bin/synthpod_bin.h b/bin/synthpod_bin.h
index ba85c12..78ad8a5 100644
--- a/bin/synthpod_bin.h
+++ b/bin/synthpod_bin.h
@@ -53,15 +53,8 @@
#define SEQ_SIZE 0x2000
#define JAN_1970 (uint64_t)0x83aa7e80
-typedef enum _save_state_t save_state_t;
typedef struct _bin_t bin_t;
-enum _save_state_t {
- SAVE_STATE_INTERNAL = 0,
- SAVE_STATE_NSM,
- SAVE_STATE_JACK
-};
-
struct _bin_t {
atomic_bool inject;
lfrtm_t *lfrtm;
@@ -129,8 +122,7 @@ void
bin_init(bin_t *bin, uint32_t sample_rate);
void
-bin_run(bin_t *bin, char **argv, const nsmc_driver_t *nsm_driver,
- void (*idle)(void *data), void *data);
+bin_run(bin_t *bin, const char *name, char **argv, const nsmc_driver_t *nsm_driver);
void
bin_stop(bin_t *bin);
@@ -148,6 +140,9 @@ void
bin_bundle_new(bin_t *bin);
void
+bin_bundle_reset(bin_t *bin);
+
+void
bin_bundle_load(bin_t *bin, const char *bundle_path);
void
diff --git a/bin/synthpod_dummy.c b/bin/synthpod_dummy.c
index 451df05..4179e8e 100644
--- a/bin/synthpod_dummy.c
+++ b/bin/synthpod_dummy.c
@@ -37,7 +37,6 @@ struct _prog_t {
LV2_Atom_Forge forge;
- save_state_t save_state;
atomic_int kill;
pthread_t thread;
@@ -331,23 +330,6 @@ _system_port_del(void *data, void *sys_port)
// unsupported, skip
}
-__non_realtime static void
-_saved(bin_t *bin, int status)
-{
- prog_t *handle = (void *)bin - offsetof(prog_t, bin);
-
- if(handle->save_state == SAVE_STATE_NSM)
- {
- nsmc_saved(bin->nsm, status);
- }
- handle->save_state = SAVE_STATE_INTERNAL;
-
- if(atomic_load_explicit(&handle->kill, memory_order_relaxed))
- {
- bin_quit(bin);
- }
-}
-
__non_realtime static int
_open(const char *path, const char *name, const char *id, void *data)
{
@@ -355,28 +337,32 @@ _open(const char *path, const char *name, const char *id, void *data)
prog_t *handle = (void *)bin - offsetof(prog_t, bin);
(void)name;
+ const bool switch_over = bin->app ? true : false;
+
if(bin->path)
free(bin->path);
bin->path = strdup(path);
- // synthpod init
- bin->app_driver.sample_rate = handle->srate;
- bin->app_driver.update_rate = handle->bin.update_rate;
- bin->app_driver.max_block_size = handle->frsize;
- bin->app_driver.min_block_size = 1;
- bin->app_driver.seq_size = handle->seq_size;
- bin->app_driver.num_periods = handle->nfrags;
-
- // app init
- bin->app = sp_app_new(NULL, &bin->app_driver, bin);
-
- // alsa activate
- atomic_init(&handle->kill, 0);
- if(pthread_create(&handle->thread, NULL, _rt_thread, handle))
- bin_log_error(bin, "%s: creation of realtime thread failed\n", __func__);
+ if(!switch_over)
+ {
+ // synthpod init
+ bin->app_driver.sample_rate = handle->srate;
+ bin->app_driver.update_rate = handle->bin.update_rate;
+ bin->app_driver.max_block_size = handle->frsize;
+ bin->app_driver.min_block_size = 1;
+ bin->app_driver.seq_size = handle->seq_size;
+ bin->app_driver.num_periods = handle->nfrags;
+
+ // app init
+ bin->app = sp_app_new(NULL, &bin->app_driver, bin);
+
+ // dummy activate
+ atomic_init(&handle->kill, 0);
+ if(pthread_create(&handle->thread, NULL, _rt_thread, handle))
+ bin_log_error(bin, "%s: creation of realtime thread failed\n", __func__);
+ }
bin_bundle_load(bin, bin->path);
- nsmc_opened(bin->nsm, 0);
return 0; // success
}
@@ -387,9 +373,7 @@ _save(void *data)
bin_t *bin = data;
prog_t *handle = (void *)bin - offsetof(prog_t, bin);
- handle->save_state = SAVE_STATE_NSM;
bin_bundle_save(bin, bin->path);
- _saved(bin, 0);
return 0; // success
}
@@ -414,7 +398,8 @@ static const nsmc_driver_t nsm_driver = {
.open = _open,
.save = _save,
.show = _show,
- .hide = _hide
+ .hide = _hide,
+ .supports_switch = true
};
// rt
@@ -629,7 +614,7 @@ main(int argc, char **argv)
bin->app_driver.features |= SP_APP_FEATURE_POWER_OF_2_BLOCK_LENGTH;
// run
- bin_run(bin, argv, &nsm_driver, NULL, NULL);
+ bin_run(bin, "Synthpod-DUMMY", argv, &nsm_driver);
// stop
bin_stop(bin);
diff --git a/bin/synthpod_jack.c b/bin/synthpod_jack.c
index 0df0e2e..252d40b 100644
--- a/bin/synthpod_jack.c
+++ b/bin/synthpod_jack.c
@@ -32,7 +32,6 @@ typedef cpuset_t cpu_set_t;
#include <jack/jack.h>
#include <jack/midiport.h>
#include <jack/transport.h>
-#include <jack/session.h>
#if defined(JACK_HAS_METADATA_API)
# include <jack/metadata.h>
# include <jack/uuid.h>
@@ -68,13 +67,10 @@ struct _prog_t {
LV2_URID time_speed;
atomic_int kill;
- save_state_t save_state;
- atomic_uintptr_t async;
char *server_name;
char *session_id;
jack_client_t *client;
- jack_session_event_t *session_event;
uint32_t seq_size;
struct {
@@ -154,35 +150,6 @@ _trans_event(prog_t *prog, LV2_Atom_Forge *forge, int rolling, jack_position_t
return ref;
}
-__non_realtime static void
-_saved(bin_t *bin, int status)
-{
- prog_t *handle = (void *)bin - offsetof(prog_t, bin);
-
- if(handle->save_state == SAVE_STATE_NSM)
- {
- nsmc_saved(bin->nsm, status);
- }
- else if(handle->save_state == SAVE_STATE_JACK)
- {
- jack_session_event_t *ev = handle->session_event;
- if(ev)
- {
- if(status != 0)
- ev->flags |= JackSessionSaveError;
- jack_session_reply(handle->client, ev);
- jack_session_event_free(ev);
- handle->session_event = NULL;
- }
- }
- handle->save_state = SAVE_STATE_INTERNAL;
-
- if(atomic_load_explicit(&handle->kill, memory_order_relaxed))
- {
- bin_quit(bin);
- }
-}
-
// rt
__realtime static int
_process(jack_nframes_t nsamples, void *data)
@@ -191,6 +158,11 @@ _process(jack_nframes_t nsamples, void *data)
bin_t *bin = &handle->bin;
sp_app_t *app = bin->app;
+ if(atomic_load_explicit(&handle->kill, memory_order_relaxed))
+ {
+ return 0;
+ }
+
if(bin->first)
{
bin->dsp_thread = pthread_self();
@@ -549,19 +521,6 @@ _process(jack_nframes_t nsamples, void *data)
return 0;
}
-__non_realtime static void
-_session(jack_session_event_t *ev, void *data)
-{
- prog_t *handle = data;
-
- //printf("_session: %s %s %s\n",
- // ev->session_dir, ev->client_uuid, ev->command_line);
-
- jack_session_event_t *async = (void *)atomic_exchange(&handle->async, (uintptr_t)ev);
- if(async)
- jack_session_event_free(async);
-}
-
// rt, but can do non-rt stuff, as process won't be called
__non_realtime static int
_buffer_size(jack_nframes_t block_size, void *data)
@@ -822,8 +781,6 @@ _jack_init(prog_t *handle, const char *id)
// set client process callback
if(jack_set_process_callback(handle->client, _process, handle))
return -1;
- if(jack_set_session_callback(handle->client, _session, handle))
- return -1;
if(jack_set_sample_rate_callback(handle->client, _sample_rate, handle))
return -1;
if(jack_set_buffer_size_callback(handle->client, _buffer_size, handle))
@@ -839,6 +796,8 @@ _jack_deinit(prog_t *handle)
{
if(handle->client)
{
+ atomic_store_explicit(&handle->kill, 1, memory_order_relaxed);
+
// remove client properties
#if defined(JACK_HAS_METADATA_API)
jack_uuid_t uuid;
@@ -866,10 +825,21 @@ _open(const char *path, const char *name, const char *id, void *data)
prog_t *handle = (void *)bin - offsetof(prog_t, bin);
(void)name;
+ const bool switch_over = bin->app ? true : false;
+
if(bin->path)
free(bin->path);
bin->path = strdup(path);
+ if(switch_over)
+ {
+ // deregister system ports
+ bin_bundle_reset(bin);
+
+ // jack deinit
+ _jack_deinit(handle);
+ }
+
// jack init
if(_jack_init(handle, id))
{
@@ -877,24 +847,31 @@ _open(const char *path, const char *name, const char *id, void *data)
return -1;
}
- // synthpod init
- bin->app_driver.sample_rate = jack_get_sample_rate(handle->client);
- bin->app_driver.update_rate = handle->bin.update_rate;
- bin->app_driver.max_block_size = jack_get_buffer_size(handle->client);
- bin->app_driver.min_block_size = 1;
- bin->app_driver.seq_size = MAX(handle->seq_size,
- jack_port_type_get_buffer_size(handle->client, JACK_DEFAULT_MIDI_TYPE));
- bin->app_driver.num_periods = 1; //FIXME
-
- // app init
- bin->app = sp_app_new(NULL, &bin->app_driver, bin);
+ if(!switch_over)
+ {
+ // synthpod init
+ bin->app_driver.sample_rate = jack_get_sample_rate(handle->client);
+ bin->app_driver.update_rate = handle->bin.update_rate;
+ bin->app_driver.max_block_size = jack_get_buffer_size(handle->client);
+ bin->app_driver.min_block_size = 1;
+ bin->app_driver.seq_size = MAX(handle->seq_size,
+ jack_port_type_get_buffer_size(handle->client, JACK_DEFAULT_MIDI_TYPE));
+ bin->app_driver.num_periods = 1; //FIXME
+
+ // app init
+ bin->app = sp_app_new(NULL, &bin->app_driver, bin);
+
+ // jack activate
+ atomic_init(&handle->kill, 0);
+ }
+ else
+ {
+ atomic_store_explicit(&handle->kill, 0, memory_order_relaxed);
+ }
- // jack activate
- atomic_init(&handle->kill, 0);
jack_activate(handle->client); //TODO check
bin_bundle_load(bin, bin->path);
- nsmc_opened(bin->nsm, 0);
return 0; // success
}
@@ -905,9 +882,7 @@ _save(void *data)
bin_t *bin = data;
prog_t *handle = (void *)bin - offsetof(prog_t, bin);
- handle->save_state = SAVE_STATE_NSM;
bin_bundle_save(bin, bin->path);
- _saved(bin, 0);
return 0; // success
}
@@ -932,7 +907,8 @@ static const nsmc_driver_t nsm_driver = {
.open = _open,
.save = _save,
.show = _show,
- .hide = _hide
+ .hide = _hide,
+ .supports_switch = true
};
// rt
@@ -982,83 +958,6 @@ _osc_schedule_frames2osc(LV2_OSC_Schedule_Handle instance, double frames)
return timestamp;
}
-static void
-_idle(void *data)
-{
- prog_t *handle = data;
- bin_t *bin = &handle->bin;
-
- jack_session_event_t *async = (void *)atomic_exchange(&handle->async, 0);
- if(!async)
- return;
-
- //printf("_session_async: %s %s %s\n",
- // async->session_dir, async->client_uuid, async->command_line);
-
- char path [PATH_MAX];
- const char *resolvedpath = realpath(async->session_dir, path);
- if(!resolvedpath)
- resolvedpath = async->session_dir; // fall-back
-
- // create command line
- char *buf = NULL;
- size_t sz = 0;
- bool ignore = false;
-
- for(int i=0; i<bin->optind; i++)
- {
- const char *arg = (i == 0)
- ? "synthpod_jack"
- : bin->argv[i];
-
- if(ignore)
- {
- ignore = false;
- continue;
- }
-
- if(!strcmp(arg, "-u"))
- {
- ignore = true;
- continue;
- }
-
- const size_t len = strlen(arg);
- buf = realloc(buf, sz + len);
-
- sprintf(&buf[sz], "%s ", arg);
- sz += len + 1;
- }
-
- {
- const size_t len = 32;
- buf = realloc(buf, sz + len);
-
- sprintf(&buf[sz], "-u %s ${SESSION_DIR}", async->client_uuid);
- }
-
- async->command_line = buf;
- handle->session_event = async;
-
- switch(async->type)
- {
- case JackSessionSaveAndQuit:
- atomic_store_explicit(&handle->kill, 1, memory_order_relaxed); // quit after saving
- // fall-through
- case JackSessionSave:
- handle->save_state = SAVE_STATE_JACK;
- bin_bundle_save(bin, resolvedpath);
- _saved(bin, 0);
- break;
- case JackSessionSaveTemplate:
- handle->save_state = SAVE_STATE_JACK;
- bin_bundle_new(bin);
- bin_bundle_save(bin, resolvedpath);
- _saved(bin, 0);
- break;
- }
-}
-
int
main(int argc, char **argv)
{
@@ -1197,8 +1096,6 @@ main(int argc, char **argv)
}
}
- atomic_init(&handle.async, 0);
-
bin_init(bin, 48000); //FIXME
LV2_URID_Map *map = bin->map;
@@ -1229,15 +1126,11 @@ main(int argc, char **argv)
bin->app_driver.features = SP_APP_FEATURE_POWER_OF_2_BLOCK_LENGTH; // always true for JACK
// run
- bin_run(bin, argv, &nsm_driver, _idle, &handle);
+ bin_run(bin, "Synthpod-JACK", argv, &nsm_driver);
// stop
bin_stop(bin);
- jack_session_event_t *async = (void *)atomic_load(&handle.async);
- if(async)
- jack_session_event_free(async);
-
// deinit JACK
_jack_deinit(&handle);
diff --git a/include/synthpod_app.h b/include/synthpod_app.h
index c3e28d3..0de492d 100644
--- a/include/synthpod_app.h
+++ b/include/synthpod_app.h
@@ -51,6 +51,9 @@ typedef void (*sp_system_port_del)(void *data, void *sys_port);
typedef void (*sp_close_request_t)(void *data);
+typedef void (*sp_opened_t)(void *data, int status);
+typedef void (*sp_saved_t)(void *data, int status);
+
enum _sp_app_features_t {
SP_APP_FEATURE_FIXED_BLOCK_LENGTH = (1 << 0),
SP_APP_FEATURE_POWER_OF_2_BLOCK_LENGTH = (1 << 1)
@@ -120,6 +123,8 @@ struct _sp_app_driver_t {
bool cpu_affinity;
sp_close_request_t close_request;
+ sp_opened_t opened;
+ sp_saved_t saved;
};
sp_app_t *
@@ -193,6 +198,9 @@ int
sp_app_com_event(sp_app_t *app, LV2_URID otype);
void
+sp_app_bundle_reset(sp_app_t *app);
+
+void
sp_app_bundle_load(sp_app_t *app, LV2_URID urn, bool via_app);
void
diff --git a/nsmc/nsmc.h b/nsmc/nsmc.h
index 4055574..93e9b4e 100644
--- a/nsmc/nsmc.h
+++ b/nsmc/nsmc.h
@@ -42,6 +42,7 @@ struct _nsmc_driver_t {
nsmc_save_t save;
nsmc_show_t show;
nsmc_hide_t hide;
+ bool supports_switch;
};
NSMC_API nsmc_t *
@@ -67,7 +68,7 @@ NSMC_API void
nsmc_saved(nsmc_t *nsm, int status);
NSMC_API bool
-nsmc_managed(nsmc_t *nsm);
+nsmc_managed();
#ifdef NSMC_IMPLEMENTATION
@@ -91,7 +92,6 @@ struct _osc_msg_t {
};
struct _nsmc_t {
- bool managed;
bool connected;
bool connectionless;
@@ -201,13 +201,22 @@ _client_hide_optional_gui(LV2_OSC_Reader *reader, nsmc_t *nsm)
static void
_announce(nsmc_t *nsm)
{
+ char capabilities [64] = ":message:";
+
// send announce message
pid_t pid = getpid();
- int has_gui = nsm->driver->show && nsm->driver->hide;
- const char *capabilities = has_gui
- ? ":message:optional-gui:"
- : ":message:";
+ const bool has_gui = nsm->driver->show && nsm->driver->hide;
+
+ if(has_gui)
+ {
+ strcat(capabilities, "optional-gui:");
+ }
+
+ if(nsm->driver->supports_switch)
+ {
+ strcat(capabilities, "switch:");
+ }
uint8_t *tx;
size_t max;
@@ -354,7 +363,6 @@ nsmc_new(const char *call, const char *exe, const char *fallback_path,
nsm->url = getenv("NSM_URL");
if(nsm->url)
{
- nsm->managed = true;
nsm->connectionless = !strncmp(nsm->url, "osc.udp", 7) ? true : false;
nsm->url = strdup(nsm->url); //FIXME
@@ -420,7 +428,7 @@ nsmc_free(nsmc_t *nsm)
NSMC_API void
nsmc_run(nsmc_t *nsm)
{
- if(!nsm)
+ if(!nsm || !nsm->tx)
return;
const LV2_OSC_Enum ev = lv2_osc_stream_run(&nsm->stream);
@@ -459,7 +467,7 @@ nsmc_run(nsmc_t *nsm)
NSMC_API void
nsmc_opened(nsmc_t *nsm, int status)
{
- if(!nsm)
+ if(!nsm || !nsm->tx)
return;
uint8_t *tx;
@@ -495,7 +503,7 @@ nsmc_opened(nsmc_t *nsm, int status)
NSMC_API void
nsmc_shown(nsmc_t *nsm)
{
- if(!nsm)
+ if(!nsm || !nsm->tx)
return;
uint8_t *tx;
@@ -522,7 +530,7 @@ nsmc_shown(nsmc_t *nsm)
NSMC_API void
nsmc_hidden(nsmc_t *nsm)
{
- if(!nsm)
+ if(!nsm || !nsm->tx)
return;
uint8_t *tx;
@@ -549,7 +557,7 @@ nsmc_hidden(nsmc_t *nsm)
NSMC_API void
nsmc_saved(nsmc_t *nsm, int status)
{
- if(!nsm)
+ if(!nsm || !nsm->tx)
return;
uint8_t *tx;
@@ -583,9 +591,12 @@ nsmc_saved(nsmc_t *nsm, int status)
}
NSMC_API bool
-nsmc_managed(nsmc_t *nsm)
+nsmc_managed()
{
- return nsm->managed;
+ if(getenv("NSM_URL"))
+ return true;
+
+ return false;
}
#endif /* NSMC_IMPLEMENTATION */