From 9dd89e3a4b9d9f0bfb408c827358f8e97c12373b Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 3 May 2008 17:27:00 +0000 Subject: Add slv2_plugin_get_port_ranges. Use slv2_plugin_get_port_ranges in lv2_jack_host and lv2_inspect (significant performance improvement for plugins with lots of ports). git-svn-id: http://svn.drobilla.net/lad/slv2@1193 a436a847-0d15-0410-975c-d299462d15a1 --- hosts/lv2_jack_host.c | 18 ++++++++------- slv2/plugin.h | 16 +++++++++++++ src/plugin.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/slv2_internal.h | 3 +++ utils/lv2_inspect.c | 20 ++++++++++------ 5 files changed, 106 insertions(+), 15 deletions(-) diff --git a/hosts/lv2_jack_host.c b/hosts/lv2_jack_host.c index 52b6aff..2368352 100644 --- a/hosts/lv2_jack_host.c +++ b/hosts/lv2_jack_host.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -100,7 +101,7 @@ static const LV2_Feature event_ref_feature = { "http://lv2plug.in/ns/ext/event", const LV2_Feature* features[3] = { &uri_map_feature, &event_ref_feature, NULL }; void die(const char* msg); -void create_port(struct JackHost* host, uint32_t port_index); +void create_port(struct JackHost* host, uint32_t port_index, float default_value); int jack_process_cb(jack_nframes_t nframes, void* data); void list_plugins(SLV2Plugins list); @@ -189,9 +190,12 @@ main(int argc, char** argv) /* Create ports */ host.num_ports = slv2_plugin_get_num_ports(host.plugin); host.ports = calloc((size_t)host.num_ports, sizeof(struct Port)); - + float* default_values = calloc(slv2_plugin_get_num_ports(host.plugin), + sizeof(float)); + slv2_plugin_get_port_ranges(host.plugin, NULL, NULL, default_values); + for (uint32_t i=0; i < host.num_ports; ++i) - create_port(&host, i); + create_port(&host, i, default_values[i]); /* Activate plugin and JACK */ slv2_instance_activate(host.instance); @@ -254,7 +258,8 @@ die(const char* msg) */ void create_port(struct JackHost* host, - uint32_t port_index) + uint32_t port_index, + float default_value) { struct Port* const port = &host->ports[port_index]; @@ -285,11 +290,8 @@ create_port(struct JackHost* host, /* Set control values */ if (slv2_port_is_a(host->plugin, port->slv2_port, host->control_class)) { port->type = CONTROL; - SLV2Value def; - slv2_port_get_range(host->plugin, port->slv2_port, &def, NULL, NULL); - port->control = def ? slv2_value_as_float(def) : 0.0f; + port->control = isnan(default_value) ? 0.0 : default_value; printf("Set %s to %f\n", symbol_str, host->ports[port_index].control); - slv2_value_free(def); } else if (slv2_port_is_a(host->plugin, port->slv2_port, host->audio_class)) { port->type = AUDIO; } else if (slv2_port_is_a(host->plugin, port->slv2_port, host->event_class)) { diff --git a/slv2/plugin.h b/slv2/plugin.h index 0592bfd..435f869 100644 --- a/slv2/plugin.h +++ b/slv2/plugin.h @@ -270,6 +270,22 @@ uint32_t slv2_plugin_get_num_ports(SLV2Plugin p); +/** Get the port ranges (minimum, maximum and default values) for all ports. + * + * min_values, max_values and def_values must either point to an array of + * N floats, where N is the value returned by slv2_plugin_get_num_ports() for + * this plugin, or NULL. This function will set the elements of the non-NULL + * array pointers to the minimum, maximum and default values of the ports on + * this plugin, with array index corresponding to port index. If a port doesn't + * have a minimum, maximum or default value, the corresponding array element will + * be set to NAN. + */ +void +slv2_plugin_get_port_ranges(SLV2Plugin p, + float* min_values, + float* max_values, + float* def_values); + /** Get the number of ports on this plugin that are members of some class(es). * * Note that this is a varargs function so ports fitting any type 'profile' diff --git a/src/plugin.c b/src/plugin.c index 4cdc1ed..a945e8a 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -18,6 +18,7 @@ #define _XOPEN_SOURCE 500 +#include #include #include #include @@ -509,6 +510,69 @@ slv2_plugin_get_num_ports(SLV2Plugin p) } +void +slv2_plugin_get_port_float_values(SLV2Plugin p, + const char* qname, + float* values) +{ + if (!p->rdf) + slv2_plugin_load(p); + + const unsigned char* query; + librdf_query* q; + librdf_query_results* results; + + for (int i = 0; i < raptor_sequence_size(p->ports); ++i) + values[i] = NAN; + + query = (const unsigned char*)slv2_strjoin( + "PREFIX : \n" + "SELECT DISTINCT ?index ?value WHERE {\n" + "<> :port ?port .\n" + "?port :index ?index .\n" + "?port ", qname, " ?value .\n" + "} ", NULL); + + q = librdf_new_query(p->world->world, "sparql", + NULL, query, slv2_value_as_librdf_uri(p->plugin_uri)); + + results = librdf_query_execute(q, p->rdf); + + while (!librdf_query_results_finished(results)) { + librdf_node* idx_node = librdf_query_results_get_binding_value(results, 0); + librdf_node* val_node = librdf_query_results_get_binding_value(results, 1); + assert(librdf_node_is_literal(idx_node)); + assert(librdf_node_is_literal(val_node)); + const int idx = atoi((const char*)librdf_node_get_literal_value(idx_node)); + const float val = atof((const char*)librdf_node_get_literal_value(val_node)); + values[idx] = val; + librdf_free_node(idx_node); + librdf_free_node(val_node); + librdf_query_results_next(results); + } + + librdf_free_query_results(results); + librdf_free_query(q); +} + + +void +slv2_plugin_get_port_ranges(SLV2Plugin p, + float* min_values, + float* max_values, + float* def_values) +{ + if (min_values) + slv2_plugin_get_port_float_values(p, ":minimum", min_values); + + if (max_values) + slv2_plugin_get_port_float_values(p, ":maximum", max_values); + + if (def_values) + slv2_plugin_get_port_float_values(p, ":default", def_values); +} + + uint32_t slv2_plugin_get_num_ports_of_class(SLV2Plugin p, SLV2Value class_1, ...) diff --git a/src/slv2_internal.h b/src/slv2_internal.h index d38daa4..753867e 100644 --- a/src/slv2_internal.h +++ b/src/slv2_internal.h @@ -72,6 +72,9 @@ struct _SLV2Plugin { SLV2Plugin slv2_plugin_new(SLV2World world, SLV2Value uri, librdf_uri* bundle_uri, librdf_uri* binary_uri); void slv2_plugin_load(SLV2Plugin p); void slv2_plugin_free(SLV2Plugin plugin); +void slv2_plugin_get_port_float_values(SLV2Plugin p, + const char* qname, + float* values); librdf_query_results* slv2_plugin_query(SLV2Plugin plugin, const char* sparql_str); diff --git a/utils/lv2_inspect.c b/utils/lv2_inspect.c index 200d7dc..ebdb052 100644 --- a/utils/lv2_inspect.c +++ b/utils/lv2_inspect.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -27,7 +28,7 @@ SLV2Value event_class = NULL; SLV2Value control_class = NULL; void -print_port(SLV2Plugin p, uint32_t index) +print_port(SLV2Plugin p, uint32_t index, float* mins, float* maxes, float* defaults) { SLV2Port port = slv2_plugin_get_port_by_index(p, index); @@ -71,11 +72,12 @@ print_port(SLV2Plugin p, uint32_t index) slv2_value_free(val); if (slv2_port_is_a(p, port, control_class)) { - SLV2Value def, min, max; - slv2_port_get_range(p, port, &def, &min, &max); - printf("\t\tMinimum: %f\n", slv2_value_as_float(min)); - printf("\t\tMaximum: %f\n", slv2_value_as_float(max)); - printf("\t\tDefault: %f\n", slv2_value_as_float(def)); + if (!isnan(mins[index])) + printf("\t\tMinimum: %f\n", mins[index]); + if (!isnan(mins[index])) + printf("\t\tMaximum: %f\n", maxes[index]); + if (!isnan(mins[index])) + printf("\t\tDefault: %f\n", defaults[index]); } SLV2Values properties = slv2_port_get_properties(p, port); @@ -207,11 +209,15 @@ print_plugin(SLV2Plugin p) /* Ports */ const uint32_t num_ports = slv2_plugin_get_num_ports(p); + float* mins = calloc(num_ports, sizeof(float)); + float* maxes = calloc(num_ports, sizeof(float)); + float* defaults = calloc(num_ports, sizeof(float)); + slv2_plugin_get_port_ranges(p, mins, maxes, defaults); //printf("\n\t# Ports: %d\n", num_ports); for (uint32_t i=0; i < num_ports; ++i) - print_port(p, i); + print_port(p, i, mins, maxes, defaults); } -- cgit v1.2.1