aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-02-09 06:40:45 +0000
committerDavid Robillard <d@drobilla.net>2012-02-09 06:40:45 +0000
commit3d8a2bef05f69eff154ad350db4be897f6d3edfa (patch)
tree7de4fecf06fe7b247bee97ff2d235a417c7d16da
parent4c3618b8bd6983886f0049f3204552e3a4152bdb (diff)
downloadlv2-3d8a2bef05f69eff154ad350db4be897f6d3edfa.tar.xz
Add message extension.
-rw-r--r--doc/reference.doxygen.in3
l---------lv2/lv2plug.in/ns/ext/message/ext.pc.in1
-rw-r--r--lv2/lv2plug.in/ns/ext/message/manifest.ttl9
-rw-r--r--lv2/lv2plug.in/ns/ext/message/message.h47
-rw-r--r--lv2/lv2plug.in/ns/ext/message/message.ttl334
l---------lv2/lv2plug.in/ns/ext/message/waf1
l---------lv2/lv2plug.in/ns/ext/message/wscript1
-rw-r--r--plugins/eg-sampler.lv2/sampler.c70
-rw-r--r--plugins/eg-sampler.lv2/sampler_ui.c27
-rw-r--r--plugins/eg-sampler.lv2/uris.h10
-rw-r--r--plugins/eg-sampler.lv2/wscript6
11 files changed, 468 insertions, 41 deletions
diff --git a/doc/reference.doxygen.in b/doc/reference.doxygen.in
index 3e35029..16a35c4 100644
--- a/doc/reference.doxygen.in
+++ b/doc/reference.doxygen.in
@@ -576,6 +576,7 @@ INPUT = \
@LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/event/event.h \
@LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/instance-access/instance-access.h \
@LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/log/log.h \
+ @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/message/message.h \
@LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/osc/osc-print.h \
@LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/osc/osc.h \
@LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/pui/pui.h \
@@ -611,7 +612,7 @@ FILE_PATTERNS =
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
-RECURSIVE = YES
+RECURSIVE = NO
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
diff --git a/lv2/lv2plug.in/ns/ext/message/ext.pc.in b/lv2/lv2plug.in/ns/ext/message/ext.pc.in
new file mode 120000
index 0000000..03dd044
--- /dev/null
+++ b/lv2/lv2plug.in/ns/ext/message/ext.pc.in
@@ -0,0 +1 @@
+../../../../../ext.pc.in \ No newline at end of file
diff --git a/lv2/lv2plug.in/ns/ext/message/manifest.ttl b/lv2/lv2plug.in/ns/ext/message/manifest.ttl
new file mode 100644
index 0000000..3708bd9
--- /dev/null
+++ b/lv2/lv2plug.in/ns/ext/message/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/message>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <message.ttl> .
+
diff --git a/lv2/lv2plug.in/ns/ext/message/message.h b/lv2/lv2plug.in/ns/ext/message/message.h
new file mode 100644
index 0000000..9c03713
--- /dev/null
+++ b/lv2/lv2plug.in/ns/ext/message/message.h
@@ -0,0 +1,47 @@
+/*
+ Copyright 2012 David Robillard <http://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.
+*/
+
+/**
+ @file message.h C header for the LV2 Message extension
+ <http://lv2plug.in/ns/ext/message>.
+
+ The message extension is purely data, this header merely defines URIs
+ for convenience.
+*/
+
+#ifndef LV2_MESSAGE_H
+#define LV2_MESSAGE_H
+
+#define LV2_MESSAGE_URI "http://lv2plug.in/ns/ext/message"
+
+#define LV2_MESSAGE_Ack LV2_MESSAGE_URI "#Ack"
+#define LV2_MESSAGE_Delete LV2_MESSAGE_URI "#Delete"
+#define LV2_MESSAGE_Error LV2_MESSAGE_URI "#Error"
+#define LV2_MESSAGE_Get LV2_MESSAGE_URI "#Get"
+#define LV2_MESSAGE_Message LV2_MESSAGE_URI "#Message"
+#define LV2_MESSAGE_Move LV2_MESSAGE_URI "#Move"
+#define LV2_MESSAGE_Patch LV2_MESSAGE_URI "#Patch"
+#define LV2_MESSAGE_Post LV2_MESSAGE_URI "#Post"
+#define LV2_MESSAGE_Put LV2_MESSAGE_URI "#Put"
+#define LV2_MESSAGE_Request LV2_MESSAGE_URI "#Request"
+#define LV2_MESSAGE_Response LV2_MESSAGE_URI "#Response"
+#define LV2_MESSAGE_Set LV2_MESSAGE_URI "#Set"
+
+#define LV2_MESSAGE_add LV2_MESSAGE_URI "#add"
+#define LV2_MESSAGE_body LV2_MESSAGE_URI "#body"
+#define LV2_MESSAGE_cause LV2_MESSAGE_URI "#cause"
+
+#endif /* LV2_MESSAGE_H */
diff --git a/lv2/lv2plug.in/ns/ext/message/message.ttl b/lv2/lv2plug.in/ns/ext/message/message.ttl
new file mode 100644
index 0000000..a22dea3
--- /dev/null
+++ b/lv2/lv2plug.in/ns/ext/message/message.ttl
@@ -0,0 +1,334 @@
+# LV2 Message Extension
+# Copyright 2012 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.
+
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix msg: <http://lv2plug.in/ns/ext/message#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+<http://lv2plug.in/ns/ext/message>
+ a lv2:Specification ;
+ doap:license <http://opensource.org/licenses/isc> ;
+ doap:maintainer [
+ a foaf:Person ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf> ;
+ foaf:homepage <http://drobilla.net/> ;
+ foaf:name "David Robillard"
+ ] ;
+ doap:name "LV2 Message" ;
+ doap:release [
+ doap:created "2012-02-08" ;
+ doap:revision "0.1"
+ ] ;
+ doap:shortdesc "Messages for accessing and manipulating properties." ;
+ lv2:documentation """
+<p>This extension defines messages which can be used to access and manipulate
+property-based data. It is designed to provide a powerful dynamic control
+interface for LV2 plugins, but is useful for RDF-like systems in general.</p>
+
+<p>The main feature of this design is that requests and responses are
+themselves completely described in RDF. Thus, the complete <q>protocol</q> can
+be expressed wherever RDF can without imposing additional implementation
+burdens like a new syntax or binary formats. In particular, messages can be
+serialised in Turtle, or as an <a
+href="http://lv2plug.in/ns/ext/atom#Object">LV2 Object</a>.</p>
+
+<p>This set of message types is deliberately small to avoid an explosion of
+messages that all implementations would have to explicitly support. Instead,
+the idea is to achieve control via manipulating properties rather than defining
+custom commands. However, this is conceptual; there is no requirement that the
+receiver actually implement a store of resources with properties.</p>
+
+<p>For example, consider an object that can blink. Rather than define a
+specific interface to control this (e.g. <code>obj.start_blinking();
+obj.stop_blinking()</code>), set a <q>blinking</q> property to true or false to
+achieve the desired behaviour. One benefit of this approach is that a
+persistent state model is available <q>for free</q>: simply serialise the
+<q>blinking</q> property.</p>
+
+<p>Because changes are described in terms of properties, important
+functionality like undo stacks or revision control are simple to implement
+generically. Accordingly, plugins are strongly encouraged to use these
+property-based messages rather than defining custom methods for every action
+they require (or worse, defining entirely new formats for messages).</p>
+
+<p>These methods are deliberately very similar to HTTP methods, but defined
+specifically for property-based resources. The <q>properties</q> used here are
+RDF properties, thus predicates from any of the countless pre-existing
+vocabularies may be used.</p>
+""" .
+
+msg:Ack
+ a rdfs:Class ;
+ rdfs:subClassOf msg:Response ;
+ rdfs:label "Ack" ;
+ lv2:documentation """
+<p>An acknowledgement that a request has been successfully processed. This is
+returned as a reply when a specific reply type is not necessary or
+appropriate.</p>
+""" .
+
+msg:Delete
+ a rdfs:Class ;
+ rdfs:subClassOf msg:Request ;
+ rdfs:label "Delete" ;
+ lv2:documentation """
+<p>Request the subject(s) be deleted.</p>
+""" .
+
+msg:Error
+ a rdfs:Class ;
+ rdfs:subClassOf msg:Response ;
+ rdfs:label "Error" ;
+ lv2:documentation """
+<p>A response indicating an error processing a request.</p>
+""" .
+
+msg:Get
+ a rdfs:Class ;
+ rdfs:subClassOf msg:Request ;
+ rdfs:label "Get" ;
+ lv2:documentation """
+<p>Request a description of the subject.</p>
+
+<p>The detail of the response is not specified, it may be a flat description of
+all the properties of the subject, or a more expressive description with
+several subjects. A good choice is a <q><a
+href="http://www.w3.org/Submission/CBD/">concise bounded description</a></q>,
+i.e. a description which recursively includes all properties with blank node
+values.</p>
+
+<p>The response should have the same msg:subject property as the request, and
+a msg:body that is a description of that subject. For example:</p>
+<pre class="turtle-code">
+&lt;get-request&gt;
+ a msg:Get ;
+ msg:subject &lt;something&gt; .
+</pre>
+
+<p>Could result in:</p>
+<pre class="turtle-code">
+[]
+ a msg:Response ;
+ msg:cause &lt;get-request&gt; ;
+ msg:subject &lt;something&gt; ;
+ msg:body [
+ eg:name "Something" ;
+ eg:ratio 1.6180339887 ;
+ ] .
+</pre>
+
+<p>Note the use of blank nodes is not required; the value of msg:body may be
+the actual resource node. Depending on the transport and syntax used this may
+be preferable. However, the msg:subject property is required regardless. For
+example, the same response could be written:</p>
+
+<pre class="turtle-code">
+&lt;something&gt;
+ eg:name "Something" ;
+ eg:ratio 1.6180339887 .
+
+[]
+ a msg:Response ;
+ msg:cause &lt;get-request&gt; ;
+ msg:subject &lt;something&gt; ;
+ msg:body &lt;something&gt; .
+</pre>
+""" .
+
+msg:Insert
+ a rdfs:Class ;
+ rdfs:subClassOf msg:Request ;
+ rdfs:label "Insert" ;
+ rdfs:subClassOf [
+ a owl:Restriction ;
+ owl:maxCardinality 1 ;
+ owl:onProperty msg:subject
+ ] ;
+ lv2:documentation """
+<p>Insert the msg:body at msg:subject. If the subject does not exist, it is
+created. If the subject does already exist, it is added to. This request only
+adds properties, it never removes them. The user must take care that multiple
+values are not set for properties which should only have one value.</p>
+""" .
+
+msg:Message
+ a rdfs:Class ;
+ rdfs:label "Message" .
+
+msg:Move
+ a rdfs:Class ;
+ rdfs:subClassOf msg:Request ;
+ rdfs:label "Move" ;
+ rdfs:subClassOf [
+ a owl:Restriction ;
+ owl:maxCardinality 1 ;
+ owl:onProperty msg:subject ;
+ ] , [
+ a owl:Restriction ;
+ owl:cardinality 1 ;
+ owl:onProperty msg:destination ;
+ ] ;
+ lv2:documentation """
+<p>Move the msg:subject to msg:destination. After this, msg:destination has
+the description msg:subject had prior to this request's execution, and
+msg:subject does not exist any more.It is an error if the subject does not
+exist or the destination already exists.</p>
+""" .
+
+msg:Patch
+ a rdfs:Class ;
+ rdfs:subClassOf msg:Request , [
+ a owl:Restriction ;
+ owl:minCardinality 1 ;
+ owl:onProperty msg:subject
+ ] , [
+ a owl:Restriction ;
+ owl:maxCardinality 1 ;
+ owl:onProperty msg:add
+ ] , [
+ a owl:Restriction ;
+ owl:maxCardinality 1 ;
+ owl:onProperty msg:remove
+ ] ;
+ lv2:documentation """
+<p>A method for modifying the properties of an object.</p>
+
+<p>This method always has at least one msg:subject, and exactly one msg:add
+and msg:remove property. The value of msg:add and msg:remove are nodes
+which have the properties to add or remove from the subject(s), respectively.
+The special value msg:wildcard may be used as the value of a remove property
+to remove all properties with the given predicate. For example:</p>
+
+<pre class="turtle-code">
+[]
+ a msg:Patch ;
+ msg:subject &lt;something&gt; ;
+ msg:add [
+ eg:name "New name" ;
+ eg:age 42 ;
+ ] ;
+ msg:remove [
+ eg:name "Old name" ;
+ eg:age msg:wildcard ; # Remove all old eg:age properties
+ ] .
+</pre>
+""" .
+
+msg:Put
+ a rdfs:Class ;
+ rdfs:subClassOf msg:Request ;
+ rdfs:label "Put" ;
+ rdfs:subClassOf [
+ a owl:Restriction ;
+ owl:maxCardinality 1 ;
+ owl:onProperty msg:subject
+ ] ;
+ lv2:documentation """
+<p>Put the msg:body as the msg:subject. If the subject does not already exist,
+it is created. If the subject does already exist, the msg:body is considered
+an updated version of it, and the previous version is replaced.</p>
+""" .
+
+msg:Request
+ a rdfs:Class ;
+ rdfs:label "Request" ;
+ rdfs:subClassOf msg:Message ;
+ lv2:documentation """
+<p>A request. A request may have a msg:subject property, which indicates which
+resource the request applies to. The subject may be omitted in contexts where
+it is implicit (e.g. the recipient is the subject).</p>
+""" .
+
+msg:Response
+ a rdfs:Class ;
+ rdfs:subClassOf msg:Message ;
+ rdfs:label "Response" ;
+ lv2:documentation """
+<p>A response to a method.</p>
+""" .
+
+msg:Set
+ a rdfs:Class ;
+ rdfs:subClassOf msg:Request , [
+ a owl:Restriction ;
+ owl:cardinality 1 ;
+ owl:onProperty msg:body
+ ] ;
+ lv2:documentation """
+<p>A method for setting properties of an object to unique values.</p>
+
+<p>This is a simplified version of msg:Patch which only makes sense for
+properties which have at most one value. This method always has at least one
+msg:subject, and exactly one msg:add property. All the properties of the
+value of msg:add are set on the subject, with all old values for those
+properties removed. For example:</p>
+
+<pre class="turtle-code">
+[]
+ a msg:Set ;
+ msg:subject &lt;something&gt; ;
+ msg:body [
+ eg:name "New name" ;
+ eg:age 42 ;
+ ] .
+</pre>
+
+<p>This method is equivalent to a msg:Patch where the msg:remove value has
+every property of msg:add but with wildcard values. For example, the above
+message is equivalent to:</p>
+<pre class="turtle-code">
+[]
+ a msg:Patch ;
+ msg:subject &lt;something&gt; ;
+ msg:add [
+ eg:name "New name" ;
+ eg:age 42 ;
+ ] ;
+ msg:remove [
+ eg:name msg:wildcare ;
+ eg:age msg:wildcard ;
+ ] ;
+</pre>
+""" .
+
+msg:add
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:domain msg:Method .
+
+msg:body
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:domain msg:Message ;
+ lv2:documentation """
+<p>The body of a message.</p>
+
+<p>The details of this property's value depend on the type of message it is a
+part of.</p>
+""" .
+
+msg:cause
+ a rdf:Property ,
+ owl:ObjectProperty ;
+ rdfs:domain msg:Response ;
+ rdfs:range msg:Request ;
+ lv2:documentation """
+<p>The request this is a response to.</p>
+""" . \ No newline at end of file
diff --git a/lv2/lv2plug.in/ns/ext/message/waf b/lv2/lv2plug.in/ns/ext/message/waf
new file mode 120000
index 0000000..5235032
--- /dev/null
+++ b/lv2/lv2plug.in/ns/ext/message/waf
@@ -0,0 +1 @@
+../../../../../waf \ No newline at end of file
diff --git a/lv2/lv2plug.in/ns/ext/message/wscript b/lv2/lv2plug.in/ns/ext/message/wscript
new file mode 120000
index 0000000..7e2c01b
--- /dev/null
+++ b/lv2/lv2plug.in/ns/ext/message/wscript
@@ -0,0 +1 @@
+../../../../../ext.wscript \ No newline at end of file
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 <semaphore.h>
#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)