aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/jalv.c40
-rw-r--r--src/jalv_gtk2.c1
-rw-r--r--src/jalv_internal.h10
-rw-r--r--src/state.c42
4 files changed, 73 insertions, 20 deletions
diff --git a/src/jalv.c b/src/jalv.c
index b79c561..e68b508 100644
--- a/src/jalv.c
+++ b/src/jalv.c
@@ -14,6 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#define _POSIX_C_SOURCE 200809L /* for mkdtemp */
+
#include <math.h>
#include <signal.h>
#include <stdbool.h>
@@ -83,11 +85,12 @@ uri_to_id(LV2_URI_Map_Callback_Data callback_data,
#define NS_EXT "http://lv2plug.in/ns/ext/"
-static LV2_URI_Map_Feature uri_map = { NULL, &uri_to_id };
-static LV2_Feature uri_map_feature = { NS_EXT "uri-map", &uri_map };
-static LV2_Feature map_feature = { NS_EXT "urid#map", NULL };
-static LV2_Feature unmap_feature = { NS_EXT "urid#unmap", NULL };
-static LV2_Feature instance_feature = { NS_EXT "instance-access", NULL };
+static LV2_URI_Map_Feature uri_map = { NULL, &uri_to_id };
+static LV2_Feature uri_map_feature = { NS_EXT "uri-map", &uri_map };
+static LV2_Feature map_feature = { NS_EXT "urid#map", NULL };
+static LV2_Feature unmap_feature = { NS_EXT "urid#unmap", NULL };
+static LV2_Feature instance_feature = { NS_EXT "instance-access", NULL };
+static LV2_Feature make_path_feature = { LV2_STATE_MAKE_PATH_URI, NULL };
#ifdef HAVE_LV2_UI_RESIZE
static int
@@ -102,12 +105,19 @@ lv2_ui_resize(LV2_UI_Resize_Feature_Data data, int width, int height)
LV2_UI_Resize_Feature ui_resize = { NULL, &lv2_ui_resize };
static const LV2_Feature ui_resize_feature = { NS_EXT "ui-resize#UIResize", &ui_resize };
-const LV2_Feature* features[5] = {
- &uri_map_feature, &map_feature, &instance_feature, &ui_resize_feature
+const LV2_Feature* features[8] = {
+ &uri_map_feature, &map_feature, &unmap_feature,
+ &instance_feature,
+ &make_path_feature,
+ &ui_resize_feature,
+ NULL
};
#else
-const LV2_Feature* features[4] = {
- &uri_map_feature, &map_feature, &instance_feature, NULL
+const LV2_Feature* features[7] = {
+ &uri_map_feature, &map_feature, &unmap_feature,
+ &instance_feature,
+ &make_path_feature,
+ NULL
};
#endif
@@ -528,6 +538,7 @@ main(int argc, char** argv)
memset(&host, '\0', sizeof(Jalv));
host.prog_name = argv[0];
host.midi_buf_size = 1024; // Should be set by jack_buffer_size_cb
+ host.play_state = JALV_PAUSED;
if (jalv_init(&argc, &argv, &host.opts)) {
return EXIT_FAILURE;
@@ -553,6 +564,13 @@ main(int argc, char** argv)
NS_MIDI "MidiEvent");
host.atom_prot_id = symap_map(host.symap, NS_ATOM "atomTransfer");
+ char* template = jalv_strdup("/tmp/jalv-XXXXXX");
+ host.temp_dir = jalv_strjoin(mkdtemp(template), "/");
+ free(template);
+
+ LV2_State_Make_Path make_path = { &host, jalv_make_path };
+ make_path_feature.data = &make_path;
+
#ifdef HAVE_LV2_UI_RESIZE
ui_resize.data = &host;
#endif
@@ -723,6 +741,7 @@ main(int argc, char** argv)
/* Activate Jack */
jack_activate(host.jack_client);
host.sample_rate = jack_get_sample_rate(host.jack_client);
+ host.play_state = JALV_RUNNING;
SuilHost* ui_host = NULL;
if (host.ui) {
@@ -798,5 +817,8 @@ main(int argc, char** argv)
sem_destroy(&exit_sem);
+ remove(host.temp_dir);
+ free(host.temp_dir);
+
return 0;
}
diff --git a/src/jalv_gtk2.c b/src/jalv_gtk2.c
index 1ddeb95..3307211 100644
--- a/src/jalv_gtk2.c
+++ b/src/jalv_gtk2.c
@@ -72,7 +72,6 @@ on_save_activate(GtkWidget* widget, void* ptr)
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
char* base = g_build_filename(filename, "/", NULL);
- fprintf(stderr, "SAVE TO %s\n", base);
jalv_save(jalv, base);
g_free(filename);
g_free(base);
diff --git a/src/jalv_internal.h b/src/jalv_internal.h
index 5a78c1d..fd625d4 100644
--- a/src/jalv_internal.h
+++ b/src/jalv_internal.h
@@ -29,6 +29,7 @@
#include "suil/suil.h"
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
+#include "lv2/lv2plug.in/ns/ext/state/state.h"
#include "lv2_evbuf.h"
#include "symap.h"
@@ -90,8 +91,8 @@ typedef struct {
LilvWorld* world; /**< Lilv World */
int ui_width; /**< Requested UI width */
int ui_height; /**< Requested UI height */
- LV2_URID_Map map;
- LV2_URID_Unmap unmap;
+ LV2_URID_Map map; /**< URI => Int map */
+ LV2_URID_Unmap unmap; /**< Int => URI map */
Symap* symap; /**< Symbol (URI) map */
jack_client_t* jack_client; /**< Jack client */
jack_ringbuffer_t* ui_events; /**< Port events from UI */
@@ -99,6 +100,8 @@ typedef struct {
sem_t* done; /**< Exit semaphore */
sem_t paused; /**< Paused signal from process thread */
JalvPlayState play_state; /**< Current play state */
+ char* temp_dir; /**< Temporary plugin state directory */
+ char* save_dir; /**< Plugin save directory */
const LilvPlugin* plugin; /**< Plugin class (RDF data) */
const LilvUI* ui; /**< Plugin UI (RDF data) */
LilvInstance* instance; /**< Plugin instance (shared library) */
@@ -175,6 +178,9 @@ void
jalv_save_port_values(Jalv* jalv,
SerdWriter* writer,
const SerdNode* subject);
+char*
+jalv_make_path(LV2_State_Make_Path_Handle handle,
+ const char* path);
void
jalv_apply_state(Jalv* jalv, LilvState* state);
diff --git a/src/state.c b/src/state.c
index d7a3d5b..e5c6933 100644
--- a/src/state.c
+++ b/src/state.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -45,6 +46,21 @@
#define USTR(s) ((const uint8_t*)s)
+char*
+jalv_make_path(LV2_State_Make_Path_Handle handle,
+ const char* path)
+{
+ Jalv* jalv = (Jalv*)handle;
+
+ // Create in save directory if saving, otherwise use temp directory
+ const char* dir = (jalv->save_dir) ? jalv->save_dir : jalv->temp_dir;
+
+ char* fullpath = jalv_strjoin(dir, path);
+ fprintf(stderr, "MAKE PATH `%s' => `%s'\n", path, fullpath);
+
+ return fullpath;
+}
+
LilvNode*
get_port_value(const char* port_symbol,
void* user_data)
@@ -60,15 +76,20 @@ get_port_value(const char* port_symbol,
void
jalv_save(Jalv* jalv, const char* dir)
{
- char* const path = jalv_strjoin(dir, "/state.ttl");
+ jalv->save_dir = jalv_strjoin(dir, "/");
+
LilvState* const state = lilv_state_new_from_instance(
- jalv->plugin, jalv->instance,
+ jalv->plugin, jalv->instance, &jalv->map, jalv->temp_dir,
get_port_value, jalv,
LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, NULL);
- lilv_state_save(jalv->world, &jalv->unmap, state, NULL, path, NULL);
+ lilv_state_save(jalv->world, &jalv->unmap, state, NULL,
+ dir, "state.ttl", NULL);
lilv_state_free(state);
+
+ free(jalv->save_dir);
+ jalv->save_dir = NULL;
}
int
@@ -132,13 +153,18 @@ void
jalv_apply_state(Jalv* jalv, LilvState* state)
{
if (state) {
- jalv->play_state = JALV_PAUSE_REQUESTED;
- sem_wait(&jalv->paused);
+ const bool must_pause = (jalv->play_state == JALV_RUNNING);
+ if (must_pause) {
+ 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;
+ if (must_pause) {
+ jalv->play_state = JALV_RUNNING;
+ }
}
}
@@ -156,13 +182,13 @@ int
jalv_save_preset(Jalv* jalv, const char* label)
{
LilvState* const state = lilv_state_new_from_instance(
- jalv->plugin, jalv->instance,
+ jalv->plugin, jalv->instance, &jalv->map, jalv->temp_dir,
get_port_value, jalv,
LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, NULL);
lilv_state_set_label(state, label);
int ret = lilv_state_save(jalv->world, &jalv->unmap, state,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
lilv_state_free(state);
return ret;