diff options
author | David Robillard <d@drobilla.net> | 2012-02-09 06:40:45 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2012-02-09 06:40:45 +0000 |
commit | 3d8a2bef05f69eff154ad350db4be897f6d3edfa (patch) | |
tree | 7de4fecf06fe7b247bee97ff2d235a417c7d16da | |
parent | 4c3618b8bd6983886f0049f3204552e3a4152bdb (diff) | |
download | lv2-3d8a2bef05f69eff154ad350db4be897f6d3edfa.tar.xz |
Add message extension.
-rw-r--r-- | doc/reference.doxygen.in | 3 | ||||
l--------- | lv2/lv2plug.in/ns/ext/message/ext.pc.in | 1 | ||||
-rw-r--r-- | lv2/lv2plug.in/ns/ext/message/manifest.ttl | 9 | ||||
-rw-r--r-- | lv2/lv2plug.in/ns/ext/message/message.h | 47 | ||||
-rw-r--r-- | lv2/lv2plug.in/ns/ext/message/message.ttl | 334 | ||||
l--------- | lv2/lv2plug.in/ns/ext/message/waf | 1 | ||||
l--------- | lv2/lv2plug.in/ns/ext/message/wscript | 1 | ||||
-rw-r--r-- | plugins/eg-sampler.lv2/sampler.c | 70 | ||||
-rw-r--r-- | plugins/eg-sampler.lv2/sampler_ui.c | 27 | ||||
-rw-r--r-- | plugins/eg-sampler.lv2/uris.h | 10 | ||||
-rw-r--r-- | plugins/eg-sampler.lv2/wscript | 6 |
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"> +<get-request> + a msg:Get ; + msg:subject <something> . +</pre> + +<p>Could result in:</p> +<pre class="turtle-code"> +[] + a msg:Response ; + msg:cause <get-request> ; + msg:subject <something> ; + 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"> +<something> + eg:name "Something" ; + eg:ratio 1.6180339887 . + +[] + a msg:Response ; + msg:cause <get-request> ; + msg:subject <something> ; + msg:body <something> . +</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 <something> ; + 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 <something> ; + 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 <something> ; + 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) |