From 3d8a2bef05f69eff154ad350db4be897f6d3edfa Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 9 Feb 2012 06:40:45 +0000 Subject: Add message extension. --- plugins/eg-sampler.lv2/sampler.c | 70 +++++++++++++++++++++++-------------- plugins/eg-sampler.lv2/sampler_ui.c | 27 ++++++++++---- plugins/eg-sampler.lv2/uris.h | 10 +++--- plugins/eg-sampler.lv2/wscript | 6 ++-- 4 files changed, 73 insertions(+), 40 deletions(-) (limited to 'plugins') diff --git a/plugins/eg-sampler.lv2/sampler.c b/plugins/eg-sampler.lv2/sampler.c index ae5434a..5292aee 100644 --- a/plugins/eg-sampler.lv2/sampler.c +++ b/plugins/eg-sampler.lv2/sampler.c @@ -44,6 +44,7 @@ #include #include "lv2/lv2plug.in/ns/ext/atom/atom-helpers.h" +#include "lv2/lv2plug.in/ns/ext/message/message.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" @@ -81,11 +82,13 @@ typedef struct { /* URIs */ struct { + LV2_URID atom_Blank; + LV2_URID atom_Resource; + LV2_URID filename_key; LV2_URID midi_Event; - LV2_URID atom_Object; - LV2_URID set_message; + LV2_URID msg_Set; + LV2_URID msg_body; LV2_URID state_Path; - LV2_URID filename_key; } uris; /* Playback state */ @@ -221,27 +224,27 @@ instantiate(const LV2_Descriptor* descriptor, } /* Scan host features for URID map */ + LV2_URID_Map* map = NULL; for (int i = 0; features[i]; ++i) { if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) { - plugin->map = (LV2_URID_Map*)features[i]->data; - plugin->uris.midi_Event = plugin->map->map( - plugin->map->handle, MIDI_EVENT_URI); - plugin->uris.atom_Object = plugin->map->map( - plugin->map->handle, ATOM_OBJECT_URI); - plugin->uris.set_message = plugin->map->map( - plugin->map->handle, SET_MESSAGE_URI); - plugin->uris.state_Path = plugin->map->map( - plugin->map->handle, LV2_STATE_PATH_URI); - plugin->uris.filename_key = plugin->map->map( - plugin->map->handle, FILENAME_URI); + map = (LV2_URID_Map*)features[i]->data; } } - if (!plugin->map) { + if (!map) { fprintf(stderr, "Host does not support urid:map.\n"); goto fail; } + plugin->map = map; + plugin->uris.atom_Blank = map->map(map->handle, ATOM_BLANK_URI); + plugin->uris.atom_Resource = map->map(map->handle, ATOM_RESOURCE_URI); + plugin->uris.filename_key = map->map(map->handle, FILENAME_URI); + plugin->uris.midi_Event = map->map(map->handle, MIDI_EVENT_URI); + plugin->uris.msg_Set = map->map(map->handle, LV2_MESSAGE_Set); + plugin->uris.msg_body = map->map(map->handle, LV2_MESSAGE_body); + plugin->uris.state_Path = map->map(map->handle, LV2_STATE_PATH_URI); + /* Open the default sample file */ strncpy(plugin->pending_samp->filepath, path, STRING_BUF); strncat(plugin->pending_samp->filepath, @@ -275,28 +278,41 @@ run(LV2_Handle instance, plugin->frame = 0; plugin->play = true; } - } else if (ev->body.type == plugin->uris.atom_Object) { + } else if (ev->body.type == plugin->uris.atom_Resource + || ev->body.type == plugin->uris.atom_Blank) { const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body; - if (obj->type == plugin->uris.set_message) { + if (obj->type == plugin->uris.msg_Set) { + const LV2_Atom_Object* body = NULL; + LV2_Atom_Object_Query q1[] = { + { plugin->uris.msg_body, (const LV2_Atom**)&body }, + LV2_OBJECT_QUERY_END + }; + lv2_object_get(obj, q1); + + if (!body) { // TODO: check type + fprintf(stderr, "Malformed set message with no body.\n"); + continue; + } + const LV2_Atom* filename = NULL; - LV2_Atom_Object_Query q[] = { + LV2_Atom_Object_Query q2[] = { { plugin->uris.filename_key, &filename }, LV2_OBJECT_QUERY_END }; - lv2_object_get(obj, q); - - if (filename) { - char* str = (char*)LV2_ATOM_BODY(filename); - fprintf(stderr, "Request to load %s\n", str); - memcpy(plugin->pending_samp->filepath, str, filename->size); - sem_post(&plugin->signal); - } else { + lv2_object_get((LV2_Atom_Object*)body, q2); + + if (!filename) { fprintf(stderr, "Ignored set message with no filename\n"); + continue; } + + char* str = (char*)LV2_ATOM_BODY(filename); + fprintf(stderr, "Request to load %s\n", str); + memcpy(plugin->pending_samp->filepath, str, filename->size); + sem_post(&plugin->signal); } else { fprintf(stderr, "Unknown message type %d\n", obj->id); } - } else { fprintf(stderr, "Unknown event type %d\n", ev->body.type); } diff --git a/plugins/eg-sampler.lv2/sampler_ui.c b/plugins/eg-sampler.lv2/sampler_ui.c index ea57cc1..b807be9 100644 --- a/plugins/eg-sampler.lv2/sampler_ui.c +++ b/plugins/eg-sampler.lv2/sampler_ui.c @@ -26,6 +26,7 @@ #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/atom/forge.h" +#include "lv2/lv2plug.in/ns/ext/message/message.h" #include "lv2/lv2plug.in/ns/ext/urid/urid.h" #include "lv2/lv2plug.in/ns/extensions/ui/ui.h" @@ -77,15 +78,29 @@ on_load_clicked(GtkWidget* widget, uint8_t obj_buf[OBJ_BUF_SIZE]; lv2_atom_forge_set_buffer(&ui->forge, obj_buf, OBJ_BUF_SIZE); - LV2_Atom* obj = (LV2_Atom*)lv2_atom_forge_object( - &ui->forge, NULL, 0, uri_to_id(ui, SET_MESSAGE_URI)); - lv2_atom_forge_property_head(&ui->forge, obj, + /* Send [ + * a msg:Set ; + * msg:body [ + * eg-sampler:filename "/foo/bar.wav" ; + * ] ; + * ] + */ + LV2_Atom* set = (LV2_Atom*)lv2_atom_forge_blank( + &ui->forge, NULL, 0, uri_to_id(ui, LV2_MESSAGE_Set)); + lv2_atom_forge_property_head(&ui->forge, set, + uri_to_id(ui, LV2_MESSAGE_body), 0); + LV2_Atom* body = (LV2_Atom*)lv2_atom_forge_blank(&ui->forge, set, 0, 0); + lv2_atom_forge_property_head(&ui->forge, body, uri_to_id(ui, FILENAME_URI), 0); - lv2_atom_forge_string(&ui->forge, obj, (uint8_t*)filename, filename_len); + lv2_atom_forge_string(&ui->forge, set, (uint8_t*)filename, filename_len); - ui->write(ui->controller, 0, sizeof(LV2_Atom) + obj->size, + lv2_atom_forge_property_head(&ui->forge, body, + uri_to_id(ui, LV2_MESSAGE_body), 0); + set->size += body->size; + + ui->write(ui->controller, 0, sizeof(LV2_Atom) + set->size, uri_to_id(ui, NS_ATOM "atomTransfer"), - obj); + set); g_free(filename); } diff --git a/plugins/eg-sampler.lv2/uris.h b/plugins/eg-sampler.lv2/uris.h index 5e968ed..87b16cc 100644 --- a/plugins/eg-sampler.lv2/uris.h +++ b/plugins/eg-sampler.lv2/uris.h @@ -18,8 +18,8 @@ #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_OBJECT_URI NS_ATOM "Object" -#define SET_MESSAGE_URI "http: //example.org/set" +#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_BLANK_URI NS_ATOM "Blank" +#define ATOM_RESOURCE_URI NS_ATOM "Resource" diff --git a/plugins/eg-sampler.lv2/wscript b/plugins/eg-sampler.lv2/wscript index 8050e72..e5988ed 100644 --- a/plugins/eg-sampler.lv2/wscript +++ b/plugins/eg-sampler.lv2/wscript @@ -30,6 +30,8 @@ def configure(conf): uselib_store='LV2_ATOM') autowaf.check_pkg(conf, 'lv2-lv2plug.in-ns-ext-state', uselib_store='LV2_STATE') + autowaf.check_pkg(conf, 'lv2-lv2plug.in-ns-ext-message', + uselib_store='LV2_MESSAGE') autowaf.check_pkg(conf, 'sndfile', uselib_store='SNDFILE', atleast_version='1.0.0', mandatory=True) @@ -76,7 +78,7 @@ def build(bld): name = 'sampler', target = '%s/sampler' % bundle, install_path = '${LV2DIR}/%s' % bundle, - use = 'SNDFILE', + use = 'SNDFILE LV2CORE LV2_URID LV2_ATOM LV2_STATE LV2_MESSAGE', includes = includes) # Build UI library @@ -87,6 +89,6 @@ def build(bld): name = 'sampler_ui', target = '%s/sampler_ui' % bundle, install_path = '${LV2DIR}/%s' % bundle, - use = 'GTK2', + use = 'GTK2 LV2CORE LV2_URID LV2_ATOM LV2_STATE LV2_MESSAGE', includes = includes) -- cgit v1.2.1