Schema bug fixes (parsable now).
Fixed some leaks. Internal query API cleanups. Added latency reporting support. git-svn-id: http://svn.drobilla.net/lad@110 a436a847-0d15-0410-975c-d299462d15a1
This commit is contained in:
parent
1abd854fe1
commit
3a79a86998
|
@ -1,4 +1,4 @@
|
|||
CFLAGS = -Wall -I../../../include -fPIC
|
||||
CFLAGS = -Wall -I../../../include -fPIC -g -O0
|
||||
|
||||
all: amp.so
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ To be used by a host a Plugin must have at least the following properties:
|
|||
rdf:type (with object :Plugin)
|
||||
doap:name (one without language tag)
|
||||
doap:licence
|
||||
lv2:port
|
||||
:port
|
||||
""" .
|
||||
|
||||
|
||||
|
@ -147,7 +147,7 @@ Plugins will write values to this array during their run method.
|
|||
|
||||
:dataType a rdf:Property ;
|
||||
rdfs:domain :Port ;
|
||||
rdfs:range lv2:DataType ;
|
||||
rdfs:range :DataType ;
|
||||
rdfs:label "Port Data type" ;
|
||||
rdfs:comment """
|
||||
Relates a Port to the data type(s) it can accept. Hosts that do not support
|
||||
|
|
|
@ -158,6 +158,27 @@ slv2_plugin_get_property(const SLV2Plugin* p,
|
|||
uint32_t
|
||||
slv2_plugin_get_num_ports(const SLV2Plugin* p);
|
||||
|
||||
/** Return whether or not the plugin introduces (and reports) latency.
|
||||
*
|
||||
* The index of the latency port can be found with slv2_plugin_get_latency_port
|
||||
* ONLY if this function returns true.
|
||||
*/
|
||||
bool
|
||||
slv2_plugin_has_latency(const SLV2Plugin* p);
|
||||
|
||||
/** Return the index of the plugin's latency port, or the empty string if the
|
||||
* plugin has no latency.
|
||||
*
|
||||
* It is a fatal error to call this on a plugin without checking if the port
|
||||
* exists by first calling slv2_plugin_has_latency.
|
||||
*
|
||||
* Any plugin that introduces unwanted latency that should be compensated for
|
||||
* (by hosts with the ability/need) MUST provide this port, which is a control
|
||||
* rate output port that reports the latency for each cycle in frames.
|
||||
*/
|
||||
uint32_t
|
||||
slv2_plugin_get_latency_port(const SLV2Plugin* p);
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <lv2.h>
|
||||
|
||||
|
@ -30,7 +31,7 @@ extern "C" {
|
|||
/* If you're a user of SLV2, stop reading this file RIGHT NOW.
|
||||
* Unfortunately it needs to be exposed to allow inlining of some things that
|
||||
* really need to be inlined, but these are opaque types. Don't even think
|
||||
* about writing code that depends on any information here....
|
||||
* about writing code that depends on any information here :)
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -86,8 +86,11 @@ rasqal_query_results*
|
|||
slv2_plugin_run_query(const SLV2Plugin* p,
|
||||
const char* query_string);
|
||||
|
||||
size_t
|
||||
slv2_query_get_num_results(rasqal_query_results* results, const char* var_name);
|
||||
|
||||
SLV2Property
|
||||
slv2_query_get_results(rasqal_query_results* results);
|
||||
slv2_query_get_results(rasqal_query_results* results, const char* var_name);
|
||||
|
||||
/** Free an SLV2Property. */
|
||||
void
|
||||
|
|
|
@ -156,7 +156,7 @@ slv2_plugin_get_property(const SLV2Plugin* p,
|
|||
|
||||
rasqal_query_results* results = slv2_plugin_run_query(p, query);
|
||||
|
||||
struct _Property* result = slv2_query_get_results(results);
|
||||
SLV2Property result = slv2_query_get_results(results, "value");
|
||||
|
||||
rasqal_free_query_results(results);
|
||||
rasqal_finish();
|
||||
|
@ -169,8 +169,6 @@ slv2_plugin_get_property(const SLV2Plugin* p,
|
|||
uint32_t
|
||||
slv2_plugin_get_num_ports(const SLV2Plugin* p)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
|
||||
rasqal_init();
|
||||
|
||||
char* query = strjoin(
|
||||
|
@ -179,12 +177,32 @@ slv2_plugin_get_num_ports(const SLV2Plugin* p)
|
|||
"} \n", NULL);
|
||||
|
||||
rasqal_query_results* results = slv2_plugin_run_query(p, query);
|
||||
const size_t result = slv2_query_get_num_results(results, "value");
|
||||
|
||||
while (!rasqal_query_results_finished(results)) {
|
||||
++result;
|
||||
rasqal_query_results_next(results);
|
||||
}
|
||||
rasqal_free_query_results(results);
|
||||
rasqal_finish();
|
||||
free(query);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
slv2_plugin_has_latency(const SLV2Plugin* p)
|
||||
{
|
||||
assert(p);
|
||||
|
||||
rasqal_init();
|
||||
|
||||
char* query =
|
||||
"SELECT DISTINCT ?value FROM data: WHERE { \n"
|
||||
" plugin: lv2:port ?port . \n"
|
||||
" ?port lv2:portHint lv2:reportsLatency . \n"
|
||||
"}\n";
|
||||
|
||||
rasqal_query_results* results = slv2_plugin_run_query(p, query);
|
||||
bool result = ( rasqal_query_results_get_bindings_count(results) > 0 );
|
||||
|
||||
rasqal_free_query_results(results);
|
||||
rasqal_finish();
|
||||
free(query);
|
||||
|
@ -192,3 +210,34 @@ slv2_plugin_get_num_ports(const SLV2Plugin* p)
|
|||
return result;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
slv2_plugin_get_latency_port(const SLV2Plugin* p)
|
||||
{
|
||||
assert(p);
|
||||
|
||||
rasqal_init();
|
||||
|
||||
char* query =
|
||||
"SELECT DISTINCT ?value FROM data: WHERE { \n"
|
||||
" plugin: lv2:port ?port . \n"
|
||||
" ?port lv2:portHint lv2:reportsLatency ; \n"
|
||||
" lv2:index ?index . \n"
|
||||
"}\n";
|
||||
|
||||
rasqal_query_results* results = slv2_plugin_run_query(p, query);
|
||||
|
||||
struct _Property* result = slv2_query_get_results(results, "index");
|
||||
|
||||
// FIXME: need a sane error handling strategy
|
||||
assert(result->num_values == 1);
|
||||
char* endptr = 0;
|
||||
uint32_t index = strtol(result->values[0], &endptr, 10);
|
||||
// FIXME: check.. stuff..
|
||||
|
||||
rasqal_free_query_results(results);
|
||||
rasqal_finish();
|
||||
free(query);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ slv2_plugin_instantiate(const SLV2Plugin* plugin,
|
|||
assert(result);
|
||||
assert(slv2_plugin_get_num_ports(plugin) > 0);
|
||||
|
||||
// Connect all ports to NULL (catches bugs)
|
||||
// "Connect" all ports to NULL (catches bugs)
|
||||
for (uint32_t i=0; i < slv2_plugin_get_num_ports(plugin); ++i)
|
||||
result->descriptor->connect_port(result->lv2_handle, i, NULL);
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@ slv2_port_get_data_type(SLV2Plugin* p,
|
|||
assert(type->values);
|
||||
|
||||
char* ret = type->values[0];
|
||||
type->values[0] = NULL; // prevent deletion
|
||||
|
||||
slv2_property_free(type);
|
||||
return ret;
|
||||
}
|
||||
|
@ -87,7 +89,7 @@ slv2_port_get_property(SLV2Plugin* p,
|
|||
|
||||
rasqal_query_results* results = slv2_plugin_run_query(p, query);
|
||||
|
||||
SLV2Property result = slv2_query_get_results(results);
|
||||
SLV2Property result = slv2_query_get_results(results, "value");
|
||||
|
||||
rasqal_free_query_results(results);
|
||||
rasqal_finish();
|
||||
|
@ -107,8 +109,11 @@ slv2_port_get_symbol(SLV2Plugin* p,
|
|||
SLV2Property prop
|
||||
= slv2_port_get_property(p, index, "lv2:symbol");
|
||||
|
||||
if (prop && prop->num_values == 1)
|
||||
result = strdup(prop->values[0]);
|
||||
if (prop && prop->num_values == 1) {
|
||||
result = prop->values[0];
|
||||
prop->values[0] = NULL; // prevent deletion
|
||||
}
|
||||
|
||||
slv2_property_free(prop);
|
||||
|
||||
return result;
|
||||
|
|
|
@ -83,40 +83,57 @@ slv2_plugin_run_query(const SLV2Plugin* p,
|
|||
return results;
|
||||
}
|
||||
|
||||
|
||||
SLV2Property
|
||||
slv2_query_get_results(rasqal_query_results* results)
|
||||
size_t
|
||||
slv2_query_get_num_results(rasqal_query_results* results, const char* var_name)
|
||||
{
|
||||
struct _Property* result = NULL;
|
||||
|
||||
if (rasqal_query_results_get_count(results) > 0) {
|
||||
result = malloc(sizeof(struct _Property));
|
||||
result->num_values = 0;
|
||||
result->values = NULL;
|
||||
}
|
||||
|
||||
while (!rasqal_query_results_finished(results)) {
|
||||
|
||||
rasqal_literal* literal =
|
||||
rasqal_query_results_get_binding_value_by_name(results, "value");
|
||||
assert(literal != NULL);
|
||||
|
||||
// Add value on to the array. Yes, this is disgusting.
|
||||
result->num_values++;
|
||||
// FIXME LEAK:
|
||||
result->values = realloc(result->values, result->num_values * sizeof(char*));
|
||||
result->values[result->num_values-1] = strdup(rasqal_literal_as_string(literal));
|
||||
|
||||
rasqal_query_results_next(results);
|
||||
size_t result = 0;
|
||||
|
||||
while (!rasqal_query_results_finished(results)) {
|
||||
if (!strcmp(rasqal_query_results_get_binding_name(results, 0), var_name)) {
|
||||
++result;
|
||||
}
|
||||
rasqal_query_results_next(results);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SLV2Property
|
||||
slv2_query_get_results(rasqal_query_results* results, const char* var_name)
|
||||
{
|
||||
struct _Property* result = NULL;
|
||||
|
||||
if (rasqal_query_results_get_bindings_count(results) > 0) {
|
||||
result = malloc(sizeof(struct _Property));
|
||||
result->num_values = 0;
|
||||
result->values = NULL;
|
||||
}
|
||||
|
||||
while (!rasqal_query_results_finished(results)) {
|
||||
|
||||
rasqal_literal* literal =
|
||||
rasqal_query_results_get_binding_value_by_name(results, var_name);
|
||||
assert(literal != NULL);
|
||||
|
||||
// Add value on to the array, reallocing all the way.
|
||||
// Yes, this is disgusting. Roughly as disgusting as the rasqal query
|
||||
// results API. coincidentally.
|
||||
result->num_values++;
|
||||
result->values = realloc(result->values, result->num_values * sizeof(char*));
|
||||
result->values[result->num_values-1] = strdup(rasqal_literal_as_string(literal));
|
||||
|
||||
rasqal_query_results_next(results);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
slv2_property_free(struct _Property* prop)
|
||||
{
|
||||
//struct _Property* prop = (struct _Property*)property;
|
||||
for (size_t i=0; i < prop->num_values; ++i)
|
||||
free(prop->values[i]);
|
||||
|
||||
free(prop->values);
|
||||
free(prop);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue