diff options
Diffstat (limited to 'utils/ladspa2lv2.c')
-rw-r--r-- | utils/ladspa2lv2.c | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/utils/ladspa2lv2.c b/utils/ladspa2lv2.c new file mode 100644 index 0000000..74343ab --- /dev/null +++ b/utils/ladspa2lv2.c @@ -0,0 +1,250 @@ +/* ladspa2lv2 + * Copyright (C) 2007 Dave Robillard <http://drobilla.net> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <inttypes.h> +#include <ladspa.h> +#include <dlfcn.h> +#include <librdf.h> + +#define U(x) ((const unsigned char*)(x)) + +librdf_world* world = NULL; + +LADSPA_Descriptor* +load_ladspa_plugin(const char* lib_path, unsigned long index) +{ + void* const handle = dlopen(lib_path, RTLD_LAZY); + if (handle == NULL) + return NULL; + + LADSPA_Descriptor_Function df + = (LADSPA_Descriptor_Function)dlsym(handle, "ladspa_descriptor"); + + if (df == NULL) { + dlclose(handle); + return NULL; + } + + LADSPA_Descriptor* const descriptor = (LADSPA_Descriptor*)df(index); + + return descriptor; +} + + +void +add_resource(librdf_model* model, + librdf_node* subject, + const char* predicate_uri, + const char* object_uri) +{ + librdf_node* predicate = librdf_new_node_from_uri_string(world, U(predicate_uri)); + librdf_node* object = librdf_new_node_from_uri_string(world, U(object_uri)); + + librdf_statement* triple = librdf_new_statement_from_nodes(world, subject, predicate, object); + + librdf_model_add_statement(model, triple); + + librdf_free_statement(triple); +} + + +void +add_node(librdf_model* model, + librdf_node* subject, + const char* predicate_uri, + librdf_node* object) +{ + librdf_node* predicate = librdf_new_node_from_uri_string(world, U(predicate_uri)); + + librdf_statement* triple = librdf_new_statement_from_nodes(world, subject, predicate, object); + + librdf_model_add_statement(model, triple); + + librdf_free_statement(triple); +} + + +void +add_string(librdf_model* model, + librdf_node* subject, + const char* predicate_uri, + const char* object_string) +{ + librdf_node* predicate = librdf_new_node_from_uri_string(world, U(predicate_uri)); + librdf_node* object = librdf_new_node_from_literal(world, U(object_string), NULL, 0); + + librdf_statement* triple = librdf_new_statement_from_nodes(world, subject, predicate, object); + + librdf_model_add_statement(model, triple); + + librdf_free_statement(triple); +} + + +void +add_int(librdf_model* model, + librdf_node* subject, + const char* predicate_uri, + int object_int) +{ + static const size_t MAX_LEN = 21; // strlen(2^64) + 1 + char object_str[MAX_LEN]; + snprintf(object_str, MAX_LEN, "%d", object_int); + + librdf_uri* type = librdf_new_uri(world, U("http://www.w3.org/2001/XMLSchema#integer")); + + librdf_node* predicate = librdf_new_node_from_uri_string(world, U(predicate_uri)); + librdf_node* object = librdf_new_node_from_typed_literal(world, U(object_str), NULL, type); + + librdf_statement* triple = librdf_new_statement_from_nodes(world, subject, predicate, object); + + librdf_model_add_statement(model, triple); + + librdf_free_statement(triple); + librdf_free_uri(type); +} + + +void +add_float(librdf_model* model, + librdf_node* subject, + const char* predicate_uri, + float object_float) +{ + static const size_t MAX_LEN = 64; // ? + char object_str[MAX_LEN]; + snprintf(object_str, MAX_LEN, "%f", object_float); + + librdf_uri* type = librdf_new_uri(world, U("http://www.w3.org/2001/XMLSchema#decimal")); + + librdf_node* predicate = librdf_new_node_from_uri_string(world, U(predicate_uri)); + librdf_node* object = librdf_new_node_from_typed_literal(world, U(object_str), NULL, type); + + librdf_statement* triple = librdf_new_statement_from_nodes(world, subject, predicate, object); + + librdf_model_add_statement(model, triple); + + librdf_free_statement(triple); + librdf_free_uri(type); +} + + +void +write_lv2_turtle(LADSPA_Descriptor* descriptor, const char* plugin_uri, const char* filename) +{ + librdf_storage* storage = librdf_new_storage(world, + "hashes", NULL, "hash-type='memory'"); + librdf_model* model = librdf_new_model(world, storage, NULL); + librdf_serializer* serializer = librdf_new_serializer(world, "turtle", NULL, NULL); + + librdf_node* plugin = librdf_new_node_from_uri_string(world, U(plugin_uri)); + + // Set up namespaces + librdf_serializer_set_namespace(serializer, librdf_new_uri(world, + U("http://www.w3.org/1999/02/22-rdf-syntax-ns#")), "rdf"); + librdf_serializer_set_namespace(serializer, librdf_new_uri(world, + U("http://www.w3.org/2000/01/rdf-schema#")), "rdfs"); + librdf_serializer_set_namespace(serializer, librdf_new_uri(world, + U("http://www.w3.org/2001/XMLSchema")), "xsd"); + librdf_serializer_set_namespace(serializer, librdf_new_uri(world, + U("http://usefulinc.com/ns/doap#")), "doap"); + librdf_serializer_set_namespace(serializer, librdf_new_uri(world, + U("http://xmlns.com/foaf/0.1/")), "foaf"); + librdf_serializer_set_namespace(serializer, librdf_new_uri(world, + U("http://lv2plug.in/ontology#")), "lv2"); + + add_resource(model, plugin, + "rdf:type", + "lv2:Plugin"); + + add_string(model, plugin, + "doap:name", + descriptor->Name); + + if (LADSPA_IS_HARD_RT_CAPABLE(descriptor->Properties)) + add_resource(model, plugin, + "lv2:property", + "lv2:hardRTCapable"); + + for (uint32_t i=0; i < descriptor->PortCount; ++i) { + char index_str[32]; + snprintf(index_str, (size_t)32, "%u", i); + + librdf_node* port_node = librdf_new_node(world); + + add_node(model, plugin, + "lv2:port", + port_node); + + add_int(model, port_node, + "lv2:index", + (int)i); + + add_resource(model, port_node, + "lv2:dataType", + "lv2:float"); + + add_string(model, port_node, + "lv2:name", + descriptor->PortNames[i]); + } + + librdf_serializer_serialize_model_to_file(serializer, filename, NULL, model); +} + + +void +print_usage() +{ + printf("Usage: ladspa2slv2 /path/to/laddspalib.so ladspa_index lv2_uri\n"); + printf("Partially convert a LADSPA plugin to an LV2 plugin."); + printf("(This is a utility for developers, it will not generate a usable\n"); + printf("LV2 plugin directly).\n\n"); +} + + +int +main(int argc, char** argv) +{ + if (argc != 4) { + print_usage(); + return 1; + } + + const char* const lib_path = argv[1]; + const unsigned long index = atol(argv[2]); + const char* const uri = argv[3]; + + world = librdf_new_world(); + librdf_world_open(world); + + LADSPA_Descriptor* descriptor = load_ladspa_plugin(lib_path, index); + + if (descriptor) { + printf("Loaded %s : %lu\n", lib_path, index); + write_lv2_turtle(descriptor, uri, "ladspaplugin.ttl"); + } else { + printf("Failed to load %s : %lu\n", lib_path, index); + } + + librdf_free_world(world); + + return 0; +} |