aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lv2/lv2plug.in/ns/ext/atom/atom-test.c37
-rw-r--r--lv2/lv2plug.in/ns/ext/atom/atom.h31
-rw-r--r--lv2/lv2plug.in/ns/ext/atom/atom.ttl26
-rw-r--r--lv2/lv2plug.in/ns/ext/atom/forge.h32
-rw-r--r--lv2/lv2plug.in/ns/ext/message/message.h31
-rw-r--r--lv2/lv2plug.in/ns/ext/state/state.h11
-rw-r--r--lv2/lv2plug.in/ns/ext/state/state.ttl23
-rw-r--r--plugins/eg-sampler.lv2/sampler.c94
-rw-r--r--plugins/eg-sampler.lv2/sampler_ui.c40
-rw-r--r--plugins/eg-sampler.lv2/uris.h62
10 files changed, 201 insertions, 186 deletions
diff --git a/lv2/lv2plug.in/ns/ext/atom/atom-test.c b/lv2/lv2plug.in/ns/ext/atom/atom-test.c
index 2cc0da9..2011f68 100644
--- a/lv2/lv2plug.in/ns/ext/atom/atom-test.c
+++ b/lv2/lv2plug.in/ns/ext/atom/atom-test.c
@@ -72,16 +72,17 @@ main()
LV2_URID eg_four = urid_map(NULL, "http://example.org/four");
LV2_URID eg_true = urid_map(NULL, "http://example.org/true");
LV2_URID eg_false = urid_map(NULL, "http://example.org/false");
+ LV2_URID eg_path = urid_map(NULL, "http://example.org/path");
LV2_URID eg_uri = urid_map(NULL, "http://example.org/uri");
LV2_URID eg_urid = urid_map(NULL, "http://example.org/urid");
LV2_URID eg_string = urid_map(NULL, "http://example.org/string");
LV2_URID eg_literal = urid_map(NULL, "http://example.org/literal");
LV2_URID eg_tuple = urid_map(NULL, "http://example.org/tuple");
LV2_URID eg_vector = urid_map(NULL, "http://example.org/vector");
- LV2_URID eg_seq = urid_map(NULL, "http://example.org/seq");
+ LV2_URID eg_seq = urid_map(NULL, "http: //example.org/seq");
#define BUF_SIZE 1024
-#define NUM_PROPS 13
+#define NUM_PROPS 14
uint8_t buf[BUF_SIZE];
lv2_atom_forge_set_buffer(&forge, buf, BUF_SIZE);
@@ -132,15 +133,26 @@ main()
return test_fail("%ld != 0 (false)\n", f->value);
}
+ // eg_path = (Path)"/foo/bar"
+ const uint8_t* pstr = (const uint8_t*)"/foo/bar";
+ const size_t pstr_len = strlen((const char*)pstr);
+ lv2_atom_forge_property_head(&forge, eg_path, 0);
+ LV2_Atom_String* path = lv2_atom_forge_uri(&forge, pstr, pstr_len);
+ uint8_t* pbody = (uint8_t*)LV2_ATOM_BODY(path);
+ if (strcmp((const char*)pbody, (const char*)pstr)) {
+ return test_fail("%s != \"%s\"\n",
+ (const char*)pbody, (const char*)pstr);
+ }
+
// eg_uri = (URI)"http://example.org/value"
const uint8_t* ustr = (const uint8_t*)"http://example.org/value";
const size_t ustr_len = strlen((const char*)ustr);
lv2_atom_forge_property_head(&forge, eg_uri, 0);
- LV2_Atom_String* uri = lv2_atom_forge_uri(&forge, ustr, ustr_len);
- uint8_t* body = (uint8_t*)LV2_ATOM_BODY(uri);
- if (strcmp((const char*)body, (const char*)ustr)) {
+ LV2_Atom_String* uri = lv2_atom_forge_uri(&forge, ustr, ustr_len);
+ uint8_t* ubody = (uint8_t*)LV2_ATOM_BODY(uri);
+ if (strcmp((const char*)ubody, (const char*)ustr)) {
return test_fail("%s != \"%s\"\n",
- (const char*)body, (const char*)ustr);
+ (const char*)ubody, (const char*)ustr);
}
// eg_urid = (URID)"http://example.org/value"
@@ -157,7 +169,7 @@ main()
&forge, (const uint8_t*)"hello", strlen("hello"));
uint8_t* sbody = (uint8_t*)LV2_ATOM_BODY(string);
if (strcmp((const char*)sbody, "hello")) {
- return test_fail("%s != \"hello\"\n", (const char*)body);
+ return test_fail("%s != \"hello\"\n", (const char*)sbody);
}
// eg_literal = (Literal)"hello"@fr
@@ -165,9 +177,9 @@ main()
LV2_Atom_Literal* literal = lv2_atom_forge_literal(
&forge, (const uint8_t*)"bonjour", strlen("bonjour"),
0, urid_map(NULL, "http://lexvo.org/id/term/fr"));
- body = (uint8_t*)LV2_ATOM_CONTENTS(LV2_Atom_Literal, literal);
- if (strcmp((const char*)body, "bonjour")) {
- return test_fail("%s != \"bonjour\"\n", (const char*)body);
+ uint8_t* lbody = (uint8_t*)LV2_ATOM_CONTENTS(LV2_Atom_Literal, literal);
+ if (strcmp((const char*)lbody, "bonjour")) {
+ return test_fail("%s != \"bonjour\"\n", (const char*)lbody);
}
// eg_tuple = "foo",true
@@ -267,6 +279,7 @@ main()
const LV2_Atom* four;
const LV2_Atom* affirmative;
const LV2_Atom* negative;
+ const LV2_Atom* path;
const LV2_Atom* uri;
const LV2_Atom* urid;
const LV2_Atom* string;
@@ -285,6 +298,7 @@ main()
{ eg_four, &matches.four },
{ eg_true, &matches.affirmative },
{ eg_false, &matches.negative },
+ { eg_path, &matches.path },
{ eg_uri, &matches.uri },
{ eg_urid, &matches.urid },
{ eg_string, &matches.string },
@@ -312,6 +326,8 @@ main()
return test_fail("Bad match true\n");
} else if (!lv2_atom_equals((LV2_Atom*)f, matches.negative)) {
return test_fail("Bad match false\n");
+ } else if (!lv2_atom_equals((LV2_Atom*)path, matches.path)) {
+ return test_fail("Bad match path\n");
} else if (!lv2_atom_equals((LV2_Atom*)uri, matches.uri)) {
return test_fail("Bad match URI\n");
} else if (!lv2_atom_equals((LV2_Atom*)string, matches.string)) {
@@ -333,6 +349,7 @@ main()
eg_four, &matches.four,
eg_true, &matches.affirmative,
eg_false, &matches.negative,
+ eg_path, &matches.path,
eg_uri, &matches.uri,
eg_urid, &matches.urid,
eg_string, &matches.string,
diff --git a/lv2/lv2plug.in/ns/ext/atom/atom.h b/lv2/lv2plug.in/ns/ext/atom/atom.h
index 66f0490..f45ba74 100644
--- a/lv2/lv2plug.in/ns/ext/atom/atom.h
+++ b/lv2/lv2plug.in/ns/ext/atom/atom.h
@@ -27,6 +27,37 @@
#define LV2_ATOM_URI "http://lv2plug.in/ns/ext/atom"
+#define LV2_ATOM__Atom LV2_ATOM_URI "#Atom"
+#define LV2_ATOM__Bang LV2_ATOM_URI "#Bang"
+#define LV2_ATOM__Number LV2_ATOM_URI "#Number"
+#define LV2_ATOM__Int32 LV2_ATOM_URI "#Int32"
+#define LV2_ATOM__Int64 LV2_ATOM_URI "#Int64"
+#define LV2_ATOM__Float LV2_ATOM_URI "#Float"
+#define LV2_ATOM__Double LV2_ATOM_URI "#Double"
+#define LV2_ATOM__Bool LV2_ATOM_URI "#Bool"
+#define LV2_ATOM__String LV2_ATOM_URI "#String"
+#define LV2_ATOM__Literal LV2_ATOM_URI "#Literal"
+#define LV2_ATOM__Path LV2_ATOM_URI "#Path"
+#define LV2_ATOM__URI LV2_ATOM_URI "#URI"
+#define LV2_ATOM__URID LV2_ATOM_URI "#URID"
+#define LV2_ATOM__Vector LV2_ATOM_URI "#Vector"
+#define LV2_ATOM__Tuple LV2_ATOM_URI "#Tuple"
+#define LV2_ATOM__Property LV2_ATOM_URI "#Property"
+#define LV2_ATOM__Object LV2_ATOM_URI "#Object"
+#define LV2_ATOM__Resource LV2_ATOM_URI "#Resource"
+#define LV2_ATOM__Blank LV2_ATOM_URI "#Blank"
+#define LV2_ATOM__TimeUnit LV2_ATOM_URI "#TimeUnit"
+#define LV2_ATOM__AudioFrames LV2_ATOM_URI "#AudioFrames"
+#define LV2_ATOM__Beats LV2_ATOM_URI "#Beats"
+#define LV2_ATOM__Event LV2_ATOM_URI "#Event"
+#define LV2_ATOM__Sequence LV2_ATOM_URI "#Sequence"
+#define LV2_ATOM__AtomPort LV2_ATOM_URI "#AtomPort"
+#define LV2_ATOM__ValuePort LV2_ATOM_URI "#ValuePort"
+#define LV2_ATOM__MessagePort LV2_ATOM_URI "#MessagePort"
+#define LV2_ATOM__bufferType LV2_ATOM_URI "#bufferType"
+#define LV2_ATOM__supports LV2_ATOM_URI "#supports"
+#define LV2_ATOM__eventTransfer LV2_ATOM_URI "#eventTransfer"
+
#define LV2_ATOM_REFERENCE_TYPE 0
#include <stdint.h>
diff --git a/lv2/lv2plug.in/ns/ext/atom/atom.ttl b/lv2/lv2plug.in/ns/ext/atom/atom.ttl
index 70a1252..677a159 100644
--- a/lv2/lv2plug.in/ns/ext/atom/atom.ttl
+++ b/lv2/lv2plug.in/ns/ext/atom/atom.ttl
@@ -218,22 +218,28 @@ void set_to_turtle_string(LV2_Atom_Literal* lit, const char* ttl) {
</pre>
""" .
+atom:Path
+ a rdfs:Class ;
+ rdfs:subClassOf atom:String ;
+ rdfs:label "File path string" ;
+ lv2:documentation """
+<p>A local file path string. This is identical in format to atom:String,
+except the string is a path. Since the ability to distinguish paths from plain
+strings is often necessary, paths MUST NOT be transmitted as atom:String.</p>
+""" .
+
atom:URI
a rdfs:Class ;
rdfs:subClassOf atom:String ;
rdfs:label "URI string" ;
lv2:documentation """
<p>A URI string. This is identical in format to atom:String, except the string
-is a URI. This is occasionally useful when a URI is needed but mapping it is
-inappropriate. URIs should never be expressed as atom:String, because this
-makes it impossible to distinguish URIs from arbitrary strings, which makes
-functionality like mapping or rewriting URIs impossible. Similarly, there is
-deliberately no atom type for filesystem paths. To refer to a filename, use a
-complete file URI, with hostname if at all possible. This allows hosts to
-properly handle paths in situations like serialisation or network
-transmission.</p>
-
-<p>Pedantically, this is an <q>IRI</q>, since UTF-8 characters are allowed.</p>
+is a URI. This is useful when a URI is needed but mapping is inappropriate.
+Since the ability to distinguish URIs from plain strings is often necessary,
+URIs MUST NOT be transmitted as atom:String.</p>
+
+<p>This is not strictly a URI, since UTF-8 is allowed. Escaping and related
+issues issues are the host's responsibility.</p>
""" .
atom:URID
diff --git a/lv2/lv2plug.in/ns/ext/atom/forge.h b/lv2/lv2plug.in/ns/ext/atom/forge.h
index 4db9638..06f24f5 100644
--- a/lv2/lv2plug.in/ns/ext/atom/forge.h
+++ b/lv2/lv2plug.in/ns/ext/atom/forge.h
@@ -85,6 +85,7 @@ typedef struct {
LV2_URID Int32;
LV2_URID Int64;
LV2_URID Literal;
+ LV2_URID Path;
LV2_URID Property;
LV2_URID Resource;
LV2_URID Sequence;
@@ -172,6 +173,7 @@ lv2_atom_forge_init(LV2_Atom_Forge* forge, LV2_URID_Map* map)
forge->Int32 = map->map(map->handle, LV2_ATOM_URI "#Int32");
forge->Int64 = map->map(map->handle, LV2_ATOM_URI "#Int64");
forge->Literal = map->map(map->handle, LV2_ATOM_URI "#Literal");
+ forge->Path = map->map(map->handle, LV2_ATOM_URI "#Path");
forge->Property = map->map(map->handle, LV2_ATOM_URI "#Property");
forge->Resource = map->map(map->handle, LV2_ATOM_URI "#Resource");
forge->Sequence = map->map(map->handle, LV2_ATOM_URI "#Sequence");
@@ -322,13 +324,31 @@ lv2_atom_forge_uri(LV2_Atom_Forge* forge,
const LV2_Atom_String a = { { forge->URI, len + 1 } };
LV2_Atom_String* out = (LV2_Atom_String*)
lv2_atom_forge_write_nopad(forge, &a, sizeof(a));
- if (!out) {
- return NULL;
+ if (out) {
+ if (!lv2_atom_forge_string_body(forge, uri, len)) {
+ out->atom.type = 0;
+ out->atom.size = 0;
+ out = NULL;
+ }
}
- if (!lv2_atom_forge_string_body(forge, uri, len)) {
- out->atom.type = 0;
- out->atom.size = 0;
- return NULL;
+ return out;
+}
+
+/** Write an atom:Path. Note that @p path need not be NULL terminated. */
+static inline LV2_Atom_String*
+lv2_atom_forge_path(LV2_Atom_Forge* forge,
+ const uint8_t* path,
+ size_t len)
+{
+ const LV2_Atom_String a = { { forge->Path, len + 1 } };
+ LV2_Atom_String* out = (LV2_Atom_String*)
+ lv2_atom_forge_write_nopad(forge, &a, sizeof(a));
+ if (out) {
+ if (!lv2_atom_forge_string_body(forge, path, len)) {
+ out->atom.type = 0;
+ out->atom.size = 0;
+ out = NULL;
+ }
}
return out;
}
diff --git a/lv2/lv2plug.in/ns/ext/message/message.h b/lv2/lv2plug.in/ns/ext/message/message.h
index 9c03713..728b836 100644
--- a/lv2/lv2plug.in/ns/ext/message/message.h
+++ b/lv2/lv2plug.in/ns/ext/message/message.h
@@ -27,21 +27,20 @@
#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"
+#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/state/state.h b/lv2/lv2plug.in/ns/ext/state/state.h
index b450b93..aa272b7 100644
--- a/lv2/lv2plug.in/ns/ext/state/state.h
+++ b/lv2/lv2plug.in/ns/ext/state/state.h
@@ -36,10 +36,11 @@ extern "C" {
#define LV2_STATE_URI "http://lv2plug.in/ns/ext/state"
-#define LV2_STATE_INTERFACE_URI LV2_STATE_URI "#Interface"
-#define LV2_STATE_PATH_URI LV2_STATE_URI "#Path"
-#define LV2_STATE_MAP_PATH_URI LV2_STATE_URI "#mapPath"
-#define LV2_STATE_MAKE_PATH_URI LV2_STATE_URI "#makePath"
+#define LV2_STATE__Interface LV2_STATE_URI "#Interface"
+#define LV2_STATE__State LV2_STATE_URI "#State"
+#define LV2_STATE__state LV2_STATE_URI "#state"
+#define LV2_STATE__mapPath LV2_STATE_URI "#mapPath"
+#define LV2_STATE__makePath LV2_STATE_URI "#makePath"
typedef void* LV2_State_Handle;
typedef void* LV2_State_Map_Path_Handle;
@@ -315,7 +316,7 @@ typedef struct {
} LV2_State_Map_Path;
/**
- Feature data for state:makePath (@ref LV2_STATE_MAKE_PATH_URI).
+ Feature data for state:makePath (@ref LV2_STATE__makePath).
*/
typedef struct {
diff --git a/lv2/lv2plug.in/ns/ext/state/state.ttl b/lv2/lv2plug.in/ns/ext/state/state.ttl
index 6c0656a..4b86eb6 100644
--- a/lv2/lv2plug.in/ns/ext/state/state.ttl
+++ b/lv2/lv2plug.in/ns/ext/state/state.ttl
@@ -193,7 +193,9 @@ Map get_plugin_state(LV2_Handle instance)
<p>Plugins may need to refer to files (e.g. loaded samples) in their state.
This is done by storing the file's path as a property just like any other
value. However, there are some rules which MUST be followed when storing
-paths, see <a href="#mapPath">state:mapPath</a> for details.</p>
+paths, see <a href="#mapPath">state:mapPath</a> for details. Plugins MUST
+use the type <a href="http://lv2plug.in/ns/ext/atom#Path">atom:Path</a>
+for all paths in their state.</p>
<h3>Creating New Files or Directories</h3>
@@ -267,7 +269,6 @@ state:mapPath
a lv2:Feature ;
rdfs:label "Support for storing paths in files" ;
lv2:documentation """
-
<p>This feature maps absolute paths to/from <q>abstract paths</q> which are
stored in state. To support this feature a host must pass an LV2_Feature with
URI LV2_STATE_MAP_PATH_URI and data pointed to an LV2_State_Map_Path to the
@@ -305,7 +306,6 @@ state:makePath
a lv2:Feature ;
rdfs:label "Support for creating new files and directories" ;
lv2:documentation """
-
<p>This feature allows plugins to create new files and/or directories. To
support this feature the host passes an LV2_Feature with URI
LV2_STATE_MAKE_PATH_URI and data pointed to an LV2_State_Make_Path to the
@@ -340,20 +340,3 @@ char* save_myfile(LV2_State_Make_Path* make_path)
}
</pre>
""" .
-
-state:Path
- a rdfs:Class ;
- rdfs:label "Path" ;
- lv2:documentation """
-<p>A path to a file or directory.</p>
-
-<p>The format of a state:Path is a C string, possibly escaped or otherwise
-restricted in a system-specific manner. This URI (LV2_STATE_PATH_URI), mapped
-to an integer, MUST be used as the <code>type</code> parameter for any files
-passed to the LV2_State_Store_Function; and will likewise be returned by the
-corresponding call to the LV2_State_Retrieve_Function.</p>
-
-<p>When storing and retrieving a path, the plugin MUST NOT assume the same path
-will be restored. However, the restored path will refer to a file with
-equivalent contents to the original.</p>
-""" .
diff --git a/plugins/eg-sampler.lv2/sampler.c b/plugins/eg-sampler.lv2/sampler.c
index 904f026..043f629 100644
--- a/plugins/eg-sampler.lv2/sampler.c
+++ b/plugins/eg-sampler.lv2/sampler.c
@@ -63,11 +63,10 @@ enum {
static const char* default_sample_file = "monosample.wav";
typedef struct {
- SF_INFO info; /**< Info about sample from sndfile */
- float* data; /**< Sample data in float */
- char* uri; /**< URI of file */
- const char* path; /**< Path of file (pointer into uri) */
- size_t uri_len; /**< Length of uri. */
+ SF_INFO info; /**< Info about sample from sndfile */
+ float* data; /**< Sample data in float */
+ char* path; /**< Path of file */
+ size_t path_len; /**< Length of path */
} Sample;
typedef struct {
@@ -110,41 +109,10 @@ typedef struct {
Sample* sample;
} SampleMessage;
-static bool
-parse_file_uri(const char* uri,
- const char** host, size_t* host_len,
- const char** path, size_t* path_len)
-{
- if (strncmp(uri, "file://", strlen("file://"))) {
- return false;
- }
-
- *host = uri + strlen("file://");
- const char* host_end = *host;
- for (; *host_end && *host_end != '/'; ++host_end) {}
-
- *host_len = host_end - *host;
- *path = host_end;
- *path_len = (uri + strlen(uri)) - host_end;
-
- return true;
-}
-
static Sample*
-load_sample(Sampler* plugin, const char* uri)
+load_sample(Sampler* plugin, const char* path)
{
- const size_t uri_len = strlen(uri);
- const char* host = NULL;
- const char* path = NULL;
- size_t host_len = 0;
- size_t path_len = 0;
- if (!parse_file_uri(uri, &host, &host_len, &path, &path_len)) {
- fprintf(stderr, "Request to load bad file URI %s\n", uri);
- return NULL;
- }
-
- /* Probably should check if the host is local here, but we'll just
- blissfully attempt to load the path on this machine... */
+ const size_t path_len = strlen(path);
printf("Loading sample %s\n", path);
Sample* const sample = (Sample*)malloc(sizeof(Sample));
@@ -168,11 +136,10 @@ load_sample(Sampler* plugin, const char* uri)
sf_close(sndfile);
/* Fill sample struct and return it. */
- sample->data = data;
- sample->uri = (char*)malloc(uri_len + 1);
- sample->path = sample->uri + (path - uri);
- sample->uri_len = uri_len;
- memcpy(sample->uri, uri, uri_len + 1);
+ sample->data = data;
+ sample->path = (char*)malloc(path_len + 1);
+ sample->path_len = path_len;
+ memcpy(sample->path, path, path_len + 1);
return sample;
}
@@ -181,14 +148,14 @@ static bool
handle_set_message(Sampler* plugin,
const LV2_Atom_Object* obj)
{
- /* Get file URI from message */
- const LV2_Atom* file_uri = get_msg_file_uri(&plugin->uris, obj);
- if (!file_uri) {
+ /* Get file path from message */
+ const LV2_Atom* file_path = get_msg_file_path(&plugin->uris, obj);
+ if (!file_path) {
return false;
}
/* Load sample. */
- Sample* sample = load_sample(plugin, LV2_ATOM_BODY(file_uri));
+ Sample* sample = load_sample(plugin, LV2_ATOM_BODY(file_path));
if (sample) {
/* Loaded sample, send it to run() to be applied. */
const SampleMessage msg = {
@@ -206,10 +173,12 @@ handle_set_message(Sampler* plugin,
void
free_sample(Sample* sample)
{
- fprintf(stderr, "Freeing %s\n", sample->uri);
- free(sample->uri);
- free(sample->data);
- free(sample);
+ if (sample) {
+ fprintf(stderr, "Freeing %s\n", sample->path);
+ free(sample->path);
+ free(sample->data);
+ free(sample);
+ }
}
void*
@@ -441,23 +410,10 @@ run(LV2_Handle instance,
plugin->sample = m.sample;
/* Send a notification that we're using a new sample. */
-
lv2_atom_forge_audio_time(&plugin->forge, 0, 0);
-
- LV2_Atom_Forge_Frame set_frame;
- lv2_atom_forge_blank(&plugin->forge, &set_frame, 1, uris->msg_Set);
-
- lv2_atom_forge_property_head(&plugin->forge, uris->msg_body, 0);
- LV2_Atom_Forge_Frame body_frame;
- lv2_atom_forge_blank(&plugin->forge, &body_frame, 2, 0);
-
- lv2_atom_forge_property_head(&plugin->forge, uris->eg_file, 0);
- lv2_atom_forge_uri(&plugin->forge,
- (const uint8_t*)plugin->sample->uri,
- plugin->sample->uri_len);
-
- lv2_atom_forge_pop(&plugin->forge, &body_frame);
- lv2_atom_forge_pop(&plugin->forge, &set_frame);
+ write_set_filename_msg(&plugin->forge, uris,
+ plugin->sample->path,
+ plugin->sample->path_len);
} else {
fprintf(stderr, "Unknown message from worker\n");
@@ -476,7 +432,7 @@ save(LV2_Handle instance,
{
LV2_State_Map_Path* map_path = NULL;
for (int i = 0; features[i]; ++i) {
- if (!strcmp(features[i]->URI, LV2_STATE_MAP_PATH_URI)) {
+ if (!strcmp(features[i]->URI, LV2_STATE__mapPath)) {
map_path = (LV2_State_Map_Path*)features[i]->data;
}
}
@@ -489,7 +445,7 @@ save(LV2_Handle instance,
plugin->uris.eg_file,
apath,
strlen(plugin->sample->path) + 1,
- plugin->uris.state_Path,
+ plugin->uris.atom_Path,
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
free(apath);
diff --git a/plugins/eg-sampler.lv2/sampler_ui.c b/plugins/eg-sampler.lv2/sampler_ui.c
index 056f0bb..2c039a5 100644
--- a/plugins/eg-sampler.lv2/sampler_ui.c
+++ b/plugins/eg-sampler.lv2/sampler_ui.c
@@ -75,46 +75,18 @@ on_load_clicked(GtkWidget* widget,
/* Got what we need, destroy the dialog. */
gtk_widget_destroy(dialog);
- /* Build a complete file URI with hostname, e.g. file://hal/home/me/foo.wav
- This is to precisely specify the file location, even if the plugin is
- running on a different host (which is entirely possible). Plugins
- should do this even though some hosts may not support such setups.
- */
- const char* hostname = g_get_host_name();
- char* file_uri = g_filename_to_uri(filename, hostname, NULL);
- const size_t file_uri_len = strlen(file_uri);
-
#define OBJ_BUF_SIZE 1024
uint8_t obj_buf[OBJ_BUF_SIZE];
lv2_atom_forge_set_buffer(&ui->forge, obj_buf, OBJ_BUF_SIZE);
- /* Send [
- * a msg:Set ;
- * msg:body [
- * eg-sampler:filename <file://hal/home/me/foo.wav> ;
- * ] ;
- * ]
- */
- LV2_Atom_Forge_Frame set_frame;
- LV2_Atom* set = (LV2_Atom*)lv2_atom_forge_blank(
- &ui->forge, &set_frame, 1, ui->uris.msg_Set);
-
- lv2_atom_forge_property_head(&ui->forge, ui->uris.msg_body, 0);
- LV2_Atom_Forge_Frame body_frame;
- lv2_atom_forge_blank(&ui->forge, &body_frame, 2, 0);
-
- lv2_atom_forge_property_head(&ui->forge, ui->uris.eg_file, 0);
- lv2_atom_forge_uri(&ui->forge, (const uint8_t*)file_uri, file_uri_len);
-
- ui->write(ui->controller, 0, lv2_atom_total_size(set),
- ui->uris.atom_eventTransfer,
- set);
+ LV2_Atom* msg = write_set_filename_msg(&ui->forge, &ui->uris,
+ filename, strlen(filename));
- lv2_atom_forge_pop(&ui->forge, &body_frame);
- lv2_atom_forge_pop(&ui->forge, &set_frame);
+ ui->write(ui->controller, 0, lv2_atom_total_size(msg),
+ ui->uris.atom_eventTransfer,
+ msg);
g_free(filename);
- g_free(file_uri);
}
static LV2UI_Handle
@@ -186,7 +158,7 @@ port_event(LV2UI_Handle handle,
LV2_Atom* atom = (LV2_Atom*)buffer;
if (atom->type == ui->uris.atom_Blank) {
LV2_Atom_Object* obj = (LV2_Atom_Object*)atom;
- const LV2_Atom* file_uri = get_msg_file_uri(&ui->uris, obj);
+ const LV2_Atom* file_uri = get_msg_file_path(&ui->uris, obj);
if (!file_uri) {
fprintf(stderr, "Unknown message sent to UI.\n");
return;
diff --git a/plugins/eg-sampler.lv2/uris.h b/plugins/eg-sampler.lv2/uris.h
index 6584c13..97cefca 100644
--- a/plugins/eg-sampler.lv2/uris.h
+++ b/plugins/eg-sampler.lv2/uris.h
@@ -31,6 +31,7 @@
typedef struct {
LV2_URID atom_Blank;
+ LV2_URID atom_Path;
LV2_URID atom_Resource;
LV2_URID atom_eventTransfer;
LV2_URID eg_applySample;
@@ -39,22 +40,21 @@ typedef struct {
LV2_URID midi_Event;
LV2_URID msg_Set;
LV2_URID msg_body;
- LV2_URID state_Path;
} SamplerURIs;
static inline void
map_sampler_uris(LV2_URID_Map* map, SamplerURIs* uris)
{
- uris->atom_Blank = map->map(map->handle, NS_ATOM "Blank");
- uris->atom_Resource = map->map(map->handle, NS_ATOM "Resource");
- uris->atom_eventTransfer = map->map(map->handle, NS_ATOM "eventTransfer");
+ uris->atom_Blank = map->map(map->handle, LV2_ATOM__Blank);
+ uris->atom_Path = map->map(map->handle, LV2_ATOM__Path);
+ uris->atom_Resource = map->map(map->handle, LV2_ATOM__Resource);
+ uris->atom_eventTransfer = map->map(map->handle, LV2_ATOM__eventTransfer);
uris->eg_applySample = map->map(map->handle, APPLY_SAMPLE_URI);
uris->eg_file = map->map(map->handle, FILE_URI);
uris->eg_freeSample = map->map(map->handle, FREE_SAMPLE_URI);
uris->midi_Event = map->map(map->handle, MIDI_EVENT_URI);
- uris->msg_Set = map->map(map->handle, LV2_MESSAGE_Set);
- uris->msg_body = map->map(map->handle, LV2_MESSAGE_body);
- uris->state_Path = map->map(map->handle, LV2_STATE_PATH_URI);
+ uris->msg_Set = map->map(map->handle, LV2_MESSAGE__Set);
+ uris->msg_body = map->map(map->handle, LV2_MESSAGE__body);
}
static inline bool
@@ -64,15 +64,45 @@ is_object_type(const SamplerURIs* uris, LV2_URID type)
|| type == uris->atom_Blank;
}
+static inline LV2_Atom*
+write_set_filename_msg(LV2_Atom_Forge* forge,
+ const SamplerURIs* uris,
+ const char* filename,
+ const size_t filename_len)
+{
+ /* Send [
+ * a msg:Set ;
+ * msg:body [
+ * eg-sampler:filename </home/me/foo.wav> ;
+ * ] ;
+ * ]
+ */
+ LV2_Atom_Forge_Frame set_frame;
+ LV2_Atom* set = (LV2_Atom*)lv2_atom_forge_blank(
+ forge, &set_frame, 1, uris->msg_Set);
+
+ lv2_atom_forge_property_head(forge, uris->msg_body, 0);
+ LV2_Atom_Forge_Frame body_frame;
+ lv2_atom_forge_blank(forge, &body_frame, 2, 0);
+
+ lv2_atom_forge_property_head(forge, uris->eg_file, 0);
+ lv2_atom_forge_path(forge, (const uint8_t*)filename, filename_len);
+
+ lv2_atom_forge_pop(forge, &body_frame);
+ lv2_atom_forge_pop(forge, &set_frame);
+
+ return set;
+}
+
static inline const LV2_Atom*
-get_msg_file_uri(const SamplerURIs* uris,
- const LV2_Atom_Object* obj)
+get_msg_file_path(const SamplerURIs* uris,
+ const LV2_Atom_Object* obj)
{
/* Message should look like this:
* [
* a msg:Set ;
* msg:body [
- * eg-sampler:file <file://hal/home/me/foo.wav> ;
+ * eg-sampler:file </home/me/foo.wav> ;
* ] ;
* ]
*/
@@ -94,15 +124,15 @@ get_msg_file_uri(const SamplerURIs* uris,
return NULL;
}
- /* Get file URI from body. */
- const LV2_Atom* file_uri = NULL;
- lv2_object_getv(body, uris->eg_file, &file_uri, 0);
- if (!file_uri) {
- fprintf(stderr, "Ignored set message with no file URI.\n");
+ /* Get file path from body. */
+ const LV2_Atom* file_path = NULL;
+ lv2_object_getv(body, uris->eg_file, &file_path, 0);
+ if (!file_path) {
+ fprintf(stderr, "Ignored set message with no file PATH.\n");
return NULL;
}
- return file_uri;
+ return file_path;
}
#endif /* SAMPLER_URIS_H */