aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-11-09 01:19:29 +0000
committerDavid Robillard <d@drobilla.net>2011-11-09 01:19:29 +0000
commitc43aed97c6b874a80fd5a9f759e651953bcec1f9 (patch)
treeb52b703474edafed6d80080076f55af8de27d5cd
parent836ecd0b091d70fc689fab1fcc94e5b165d33c2c (diff)
downloadlv2-c43aed97c6b874a80fd5a9f759e651953bcec1f9.tar.xz
Implement file name changing from UI.
-rw-r--r--plugins/eg-sampler.lv2/sampler.c62
-rw-r--r--plugins/eg-sampler.lv2/sampler.ttl1
-rw-r--r--plugins/eg-sampler.lv2/sampler_ui.c78
-rw-r--r--plugins/eg-sampler.lv2/uris.h25
4 files changed, 104 insertions, 62 deletions
diff --git a/plugins/eg-sampler.lv2/sampler.c b/plugins/eg-sampler.lv2/sampler.c
index 449aad1..5a00e64 100644
--- a/plugins/eg-sampler.lv2/sampler.c
+++ b/plugins/eg-sampler.lv2/sampler.c
@@ -42,16 +42,14 @@
#include <sndfile.h>
#include "lv2/lv2plug.in/ns/ext/atom/atom-buffer.h"
+#include "lv2/lv2plug.in/ns/ext/atom/atom-helpers.h"
#include "lv2/lv2plug.in/ns/ext/state/state.h"
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
-#define NS_ATOM "http://lv2plug.in/ns/ext/atom#"
+#include "./uris.h"
-#define SAMPLER_URI "http://lv2plug.in/plugins/eg-sampler"
-#define MIDI_EVENT_URI "http://lv2plug.in/ns/ext/midi#MidiEvent"
-#define FILENAME_URI SAMPLER_URI "#filename"
-#define STRING_BUF 8192
+#define STRING_BUF 8192
enum {
SAMPLER_CONTROL = 0,
@@ -81,6 +79,9 @@ typedef struct {
float* output_port;
LV2_Atom_Buffer* event_port;
LV2_URID midi_event_id;
+ LV2_URID atom_message_id;
+ LV2_URID set_message_id;
+ LV2_URID filename_key_id;
/* Playback state */
bool play;
@@ -95,6 +96,7 @@ handle_load_sample(Sampler* plugin)
{
plugin->pending_sample_ready = 0;
+ printf("Loading sample %s\n", plugin->pending_samp->filepath);
SF_INFO* const info = &plugin->pending_samp->info;
SNDFILE* const sample = sf_open(plugin->pending_samp->filepath,
SFM_READ,
@@ -199,7 +201,10 @@ instantiate(const LV2_Descriptor* descriptor,
memset(plugin->samp, 0, sizeof(SampleFile));
memset(plugin->pending_samp, 0, sizeof(SampleFile));
- plugin->midi_event_id = -1;
+ plugin->midi_event_id = -1;
+ plugin->atom_message_id = -1;
+ plugin->set_message_id = -1;
+ plugin->filename_key_id = -1;
/* Initialise mutexes and conditions for the worker thread */
if (pthread_mutex_init(&plugin->pending_samp_mutex, 0)) {
@@ -221,6 +226,12 @@ instantiate(const LV2_Descriptor* descriptor,
plugin->mapper = (LV2_URID_Mapper*)features[i]->data;
plugin->midi_event_id = plugin->mapper->map_uri(
plugin->mapper->handle, MIDI_EVENT_URI);
+ plugin->atom_message_id = plugin->mapper->map_uri(
+ plugin->mapper->handle, ATOM_MESSAGE_URI);
+ plugin->set_message_id = plugin->mapper->map_uri(
+ plugin->mapper->handle, SET_MESSAGE_URI);
+ plugin->filename_key_id = plugin->mapper->map_uri(
+ plugin->mapper->handle, FILENAME_URI);
}
}
@@ -265,18 +276,31 @@ run(LV2_Handle instance,
plugin->frame = 0;
plugin->play = true;
}
- }
- /***************************************************
- * XXX TODO: *
- * ADD CODE HERE TO DETECT AN INCOMING MESSAGE TO *
- * DYNAMICALLY LOAD A SAMPLE *
- ***************************************************
- */
- else if (0) {
- /* message to load a sample comes in */
- /* write filename to plugin->pending_samp->filepath */
- /* strncpy(plugin->pending_samp->filepath, some_src_string, STRING_BUF); */
- pthread_cond_signal(&plugin->pending_samp_cond);
+ } else if (ev->body.type == plugin->atom_message_id) {
+ const LV2_Object* msg = (LV2_Object*)&ev->body;
+ if (msg->id == plugin->set_message_id) {
+ const LV2_Atom* filename = NULL;
+ LV2_Object_Query q[] = {
+ { plugin->filename_key_id, &filename },
+ LV2_OBJECT_QUERY_END
+ };
+ lv2_object_query(msg, q);
+
+ if (filename) {
+ memcpy(plugin->pending_samp->filepath,
+ filename->body,
+ filename->size);
+ pthread_cond_signal(&plugin->pending_samp_cond);
+
+ } else {
+ fprintf(stderr, "Ignored set message with no filename\n");
+ }
+ } else {
+ fprintf(stderr, "Unknown message type %d\n", msg->id);
+ }
+
+ } else {
+ fprintf(stderr, "Unknown event type %d\n", ev->body.type);
}
}
@@ -310,7 +334,7 @@ run(LV2_Handle instance,
plugin->samp = plugin->pending_samp;
plugin->pending_samp = tmp;
plugin->pending_sample_ready = 0;
- free(plugin->pending_samp->data);
+ free(plugin->pending_samp->data); // FIXME: non-realtime!
pthread_mutex_unlock(&plugin->pending_samp_mutex);
}
diff --git a/plugins/eg-sampler.lv2/sampler.ttl b/plugins/eg-sampler.lv2/sampler.ttl
index 51c6c28..9dd512f 100644
--- a/plugins/eg-sampler.lv2/sampler.ttl
+++ b/plugins/eg-sampler.lv2/sampler.ttl
@@ -46,4 +46,5 @@
<http://lv2plug.in/plugins/eg-sampler#ui>
a ui:GtkUI ;
+ lv2:requiredFeature <http://lv2plug.in/ns/ext/urid#Mapper> ;
ui:binary <sampler_ui.so> .
diff --git a/plugins/eg-sampler.lv2/sampler_ui.c b/plugins/eg-sampler.lv2/sampler_ui.c
index 1895f22..24a79aa 100644
--- a/plugins/eg-sampler.lv2/sampler_ui.c
+++ b/plugins/eg-sampler.lv2/sampler_ui.c
@@ -25,19 +25,17 @@
#include "lv2/lv2plug.in/ns/ext/atom/atom-helpers.h"
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
-#include "lv2/lv2plug.in/ns/ext/uri-map/uri-map.h"
+#include "lv2/lv2plug.in/ns/ext/atom/forge.h"
+#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
-#define NS_ATOM "http://lv2plug.in/ns/ext/atom#"
+#include "./uris.h"
-#define SAMPLER_URI "http://lv2plug.in/plugins/eg-sampler"
#define SAMPLER_UI_URI "http://lv2plug.in/plugins/eg-sampler#ui"
-#define MIDI_EVENT_URI "http://lv2plug.in/ns/ext/midi#MidiEvent"
-#define FILENAME_URI SAMPLER_URI "#filename"
-#define STRING_BUF 8192
typedef struct {
- LV2_URI_Map_Feature* uri_map;
+ LV2_URID_Mapper* mapper;
+ LV2_Atom_Forge* forge;
LV2UI_Write_Function write;
LV2UI_Controller controller;
@@ -45,11 +43,10 @@ typedef struct {
GtkWidget* button;
} SamplerUI;
-static uint32_t
+static LV2_URID
uri_to_id(SamplerUI* ui, const char* uri)
{
- return ui->uri_map->uri_to_id(ui->uri_map->callback_data,
- NULL, uri);
+ return ui->mapper->map_uri(ui->mapper->handle, uri);
}
static void
@@ -66,36 +63,29 @@ on_load_clicked(GtkWidget* widget,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
- char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
- const size_t filename_len = strlen(filename);
- fprintf(stderr, "LOAD SAMPLE %s\n", filename);
- const size_t msg_size = sizeof(LV2_Atom)
- + sizeof(LV2_Object)
- + sizeof(LV2_Atom_Property)
- + filename_len + 1;;
-
- uint8_t buf[msg_size];
- LV2_Atom* msg = (LV2_Atom*)buf;
-
- msg->type = uri_to_id(ui, NS_ATOM "Blank");
- msg->size = 0;
- LV2_Object* obj = (LV2_Object*)msg->body;
- obj->context = 0;
- obj->id = 0;
-
- lv2_atom_append_property(msg,
- uri_to_id(ui, FILENAME_URI),
- uri_to_id(ui, NS_ATOM "String"),
- filename_len + 1,
- (const uint8_t*)filename);
-
- //ui->write(ui->controller,
- // 0,
-
-
-
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
+ gtk_widget_destroy(dialog);
+ return;
}
+
+ char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ const size_t filename_len = strlen(filename);
+ gtk_widget_destroy(dialog);
+
+ uint8_t msg_buf[4096];
+ LV2_Object* msg = (LV2_Object*)msg_buf;
+ lv2_atom_forge_set_message(ui->forge, msg, uri_to_id(ui, SET_MESSAGE_URI));
+ lv2_object_append(msg,
+ uri_to_id(ui, FILENAME_URI),
+ uri_to_id(ui, NS_ATOM "String"),
+ filename_len,
+ filename);
+
+ ui->write(ui->controller, 0, sizeof(LV2_Atom) + msg->size,
+ uri_to_id(ui, NS_ATOM "atomTransfer"),
+ msg);
+
+ g_free(filename);
}
static LV2UI_Handle
@@ -108,7 +98,7 @@ instantiate(const LV2UI_Descriptor* descriptor,
const LV2_Feature* const* features)
{
SamplerUI* ui = (SamplerUI*)malloc(sizeof(SamplerUI));
- ui->uri_map = NULL;
+ ui->mapper = NULL;
ui->write = write_function;
ui->controller = controller;
ui->button = NULL;
@@ -116,17 +106,19 @@ instantiate(const LV2UI_Descriptor* descriptor,
*widget = NULL;
for (int i = 0; features[i]; ++i) {
- if (strcmp(features[i]->URI, LV2_URI_MAP_URI) == 0) {
- ui->uri_map = (LV2_URI_Map_Feature*)features[i]->data;
+ if (!strcmp(features[i]->URI, LV2_URID_URI "#Mapper")) {
+ ui->mapper = (LV2_URID_Mapper*)features[i]->data;
}
}
- if (!ui->uri_map) {
+ if (!ui->mapper) {
fprintf(stderr, "sampler_ui: Host does not support uri-map\n");
free(ui);
return NULL;
}
+ ui->forge = lv2_atom_forge_new(ui->mapper);
+
ui->button = gtk_button_new_with_label("Load Sample");
g_signal_connect(ui->button, "clicked",
G_CALLBACK(on_load_clicked),
diff --git a/plugins/eg-sampler.lv2/uris.h b/plugins/eg-sampler.lv2/uris.h
new file mode 100644
index 0000000..d4df237
--- /dev/null
+++ b/plugins/eg-sampler.lv2/uris.h
@@ -0,0 +1,25 @@
+/*
+ LV2 Sampler Example Plugin
+ Copyright 2011 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#define NS_ATOM "http://lv2plug.in/ns/ext/atom#"
+#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+
+#define SAMPLER_URI "http://lv2plug.in/plugins/eg-sampler"
+#define MIDI_EVENT_URI "http://lv2plug.in/ns/ext/midi#MidiEvent"
+#define FILENAME_URI SAMPLER_URI "#filename"
+#define ATOM_MESSAGE_URI "http://lv2plug.in/ns/ext/atom#Message"
+#define SET_MESSAGE_URI "http: //example.org/set"