bool slv2_port_has_property(SLV2Plugin p, SLV2Port port, SLV2Value property) { assert(property); SLV2Values results = NULL; char* query = slv2_strjoin( "SELECT DISTINCT ?port WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port ." "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n", " lv2:portProperty <", slv2_value_as_uri(property), "> .\n}", NULL); results = slv2_plugin_query_variable(p, query, 0); const bool ret = (slv2_values_size(results) > 0); free(query); free(results); return ret; }
/* search the plugin path */ static gboolean lv2_plugin_discover (void) { unsigned i; SLV2Plugins plugins = slv2_world_get_all_plugins (world); for (i = 0; i < slv2_plugins_size (plugins); ++i) { SLV2Plugin lv2plugin = slv2_plugins_get_at (plugins, i); GTypeInfo typeinfo = { sizeof (GstLV2Class), (GBaseInitFunc) gst_lv2_base_init, NULL, (GClassInitFunc) gst_lv2_class_init, NULL, lv2plugin, sizeof (GstLV2), 0, (GInstanceInitFunc) gst_lv2_init, }; GType type; /* construct the type name from plugin URI */ gchar *type_name = g_strdup_printf ("%s", slv2_value_as_uri (slv2_plugin_get_uri (lv2plugin))); g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-+", '-'); /* if it's already registered, drop it */ if (g_type_from_name (type_name)) goto next; /* create the type */ type = g_type_register_static (GST_TYPE_SIGNAL_PROCESSOR, type_name, &typeinfo, 0); /* FIXME: not needed anymore when we can add pad templates, etc in class_init * as class_data contains the LADSPA_Descriptor too */ g_type_set_qdata (type, GST_SLV2_PLUGIN_QDATA, (gpointer) lv2plugin); if (!gst_element_register (gst_lv2_plugin, type_name, GST_RANK_NONE, type)) goto next; next: g_free (type_name); } return TRUE; }
void slv2_port_get_range(SLV2Plugin p, SLV2Port port, SLV2Value* def, SLV2Value* min, SLV2Value* max) { if (def) *def = NULL; if (min) *min = NULL; if (max) *max = NULL; char* query = slv2_strjoin( "SELECT DISTINCT ?def ?min ?max WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\".\n", "OPTIONAL { ?port lv2:default ?def }\n", "OPTIONAL { ?port lv2:minimum ?min }\n", "OPTIONAL { ?port lv2:maximum ?max }\n", "\n}", NULL); librdf_query_results* results = slv2_plugin_query(p, query); while (!librdf_query_results_finished(results)) { librdf_node* def_node = librdf_query_results_get_binding_value(results, 0); librdf_node* min_node = librdf_query_results_get_binding_value(results, 1); librdf_node* max_node = librdf_query_results_get_binding_value(results, 2); if (def && def_node && !*def) *def = slv2_value_new_librdf_node(p->world, def_node); if (min && min_node && !*min) *min = slv2_value_new_librdf_node(p->world, min_node); if (max && max_node && !*max) *max = slv2_value_new_librdf_node(p->world, max_node); if ((!def || *def) && (!min || *min) && (!max || *max)) break; librdf_query_results_next(results); } librdf_free_query_results(results); free(query); }
SLV2Values slv2_port_get_value_by_qname(SLV2Plugin p, SLV2Port port, const char* property) { assert(property); SLV2Values results = NULL; char* query = slv2_strjoin( "SELECT DISTINCT ?value WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n\t", property, " ?value .\n" "FILTER(lang(?value) = \"\") }", NULL); results = slv2_plugin_query_variable(p, query, 0); free(query); return results; }
SLV2ScalePoints slv2_port_get_scale_points(SLV2Plugin p, SLV2Port port) { char* query = slv2_strjoin( "SELECT DISTINCT ?value ?label WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\" ;\n", " lv2:scalePoint ?point .\n" "?point rdf:value ?value ;\n" " rdfs:label ?label .\n" "\n} ORDER BY ?value", NULL); librdf_query_results* results = slv2_plugin_query(p, query); SLV2ScalePoints ret = NULL; if (!librdf_query_results_finished(results)) ret = slv2_scale_points_new(); while (!librdf_query_results_finished(results)) { librdf_node* value_node = librdf_query_results_get_binding_value(results, 0); librdf_node* label_node = librdf_query_results_get_binding_value(results, 1); SLV2Value value = slv2_value_new_librdf_node(p->world, value_node); SLV2Value label = slv2_value_new_librdf_node(p->world, label_node); raptor_sequence_push(ret, slv2_scale_point_new(value, label)); librdf_query_results_next(results); } librdf_free_query_results(results); free(query); assert(!ret || slv2_values_size(ret) > 0); return ret; }
void Lv2PluginProvider::addLv2Plugin (SLV2Plugin plugin) { QString key = slv2_value_as_uri( slv2_plugin_get_uri( plugin ) ); if (m_lv2InfoMap.contains( key )) { return; } PluginInfoPtr info(new Lv2PluginInfo(m_lv2World, plugin)); // This always seems to return 'Plugin', which isn't so useful to us // SLV2PluginClass pclass = slv2_plugin_get_class( _plugin ); // SLV2Value label = slv2_plugin_class_get_label( pclass ); // printf( "Plugin Class is : '%s'\n", slv2_value_as_string( label ) ); //printf(" Audio (input, output)=(%d,%d)\n", // descriptor->audioInputCount(), descriptor->audioOutputCount()); m_lv2InfoMap.insert(key, info); //printf(" Type=%d\n", (int)descriptor->type()); }
bool slv2_port_supports_event(SLV2Plugin p, SLV2Port port, SLV2Value event) { assert(event); char* query = slv2_strjoin( "ASK WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port ." "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n", " lv2ev:supportsEvent <", event, "> .\n" "}", NULL); librdf_query_results* results = slv2_plugin_query(p, query); assert(librdf_query_results_is_boolean(results)); const bool ret = librdf_query_results_get_boolean(results); free(query); librdf_free_query_results(results); return ret; }
const LV2PortGroup& LV2Effect::GetPortGroups() { if (!mPortGroupsRetrieved) { // Find all port groups with ports in them. char portGroupQuery[] = "PREFIX : <http://lv2plug.in/ns/lv2core#>\n" "PREFIX pg: <http://ll-plugins.nongnu.org/lv2/ext/portgroups#>\n" "SELECT ?index, ?uri, ?label WHERE {\n" "<> :port ?port.\n" "?port :index ?index.\n" "?port pg:membership ?ms.\n" "?ms pg:group ?uri.\n" "?uri rdfs:label ?label.\n" "}"; SLV2Values portIndices = slv2_plugin_query_variable(mData, portGroupQuery, 0); SLV2Values groupUris = slv2_plugin_query_variable(mData, portGroupQuery, 1); SLV2Values groupLabels = slv2_plugin_query_variable(mData, portGroupQuery, 2); std::map<wxString, LV2PortGroup> portGroups; std::vector<bool> inGroup(mControlInputs.size(), false); size_t nMemberships = slv2_values_size(portIndices); for (size_t i = 0; i < nMemberships; ++i) { uint32_t idx = slv2_value_as_int(slv2_values_get_at(portIndices, i)); uint32_t p; for (p = 0; p < mControlInputs.size(); ++p) { if (mControlInputs[p].mIndex == idx) break; } if (p == mControlInputs.size()) continue; wxString uri = wxString::FromUTF8(slv2_value_as_string(slv2_values_get_at(groupUris, i))); wxString label = wxString::FromUTF8(slv2_value_as_string(slv2_values_get_at(groupLabels, i))); std::map<wxString, LV2PortGroup>::iterator iter = portGroups.find(uri); if (iter == portGroups.end()) portGroups[uri] = LV2PortGroup(label); portGroups[uri].AddParameter(p); inGroup[p] = true; } slv2_values_free(portIndices); slv2_values_free(groupUris); slv2_values_free(groupLabels); // Add all ports that aren't in any port groups to the root group. for (uint32_t p = 0; p < mControlInputs.size(); ++p) { if (!inGroup[p]) mRootGroup.AddParameter(p); } // Find all subgroup relationships. char subGroupQuery[] = "PREFIX : <http://lv2plug.in/ns/lv2core#>\n" "PREFIX pg: <http://ll-plugins.nongnu.org/lv2/ext/portgroups#>\n" "SELECT ?sub, ?parent WHERE {\n" "?sub pg:subgroupOf ?parent.\n" "}"; SLV2Values subs = slv2_plugin_query_variable(mData, subGroupQuery, 0); SLV2Values parents = slv2_plugin_query_variable(mData, subGroupQuery, 1); size_t nSubgroups = slv2_values_size(subs); for (size_t i = 0; i < nSubgroups; ++i) { wxString parent = wxString::FromUTF8(slv2_value_as_uri(slv2_values_get_at(parents, i))); wxString sub = wxString::FromUTF8(slv2_value_as_uri(slv2_values_get_at(subs, i))); std::map<wxString, LV2PortGroup>::iterator iter = portGroups.find(parent); std::map<wxString, LV2PortGroup>::iterator iter2 = portGroups.find(sub); if (iter != portGroups.end() && iter2 != portGroups.end()) { iter->second.AddSubGroup(iter2->second); } } slv2_values_free(subs); slv2_values_free(parents); // Make all groups subgroups of the root group. std::map<wxString, LV2PortGroup>::iterator iter; for (iter = portGroups.begin(); iter != portGroups.end(); ++iter) mRootGroup.AddSubGroup(iter->second); mPortGroupsRetrieved = true; } std::queue<const LV2PortGroup*> groups; groups.push(&mRootGroup); while (!groups.empty()) { const LV2PortGroup* g = groups.front(); groups.pop(); const std::vector<LV2PortGroup>& subs = g->GetSubGroups(); for (std::vector<LV2PortGroup>::const_iterator iter = subs.begin(); iter != subs.end(); ++iter) groups.push(&*iter); } return mRootGroup; }
SLV2Instance slv2_plugin_instantiate(SLV2Plugin plugin, double sample_rate, const LV2_Feature*const* features) { struct _Instance* result = NULL; const LV2_Feature** local_features = NULL; if (features == NULL) { local_features = malloc(sizeof(LV2_Feature)); local_features[0] = NULL; } const char* const lib_uri = slv2_value_as_uri(slv2_plugin_get_library_uri(plugin)); const char* const lib_path = slv2_uri_to_path(lib_uri); if (!lib_path) return NULL; dlerror(); void* lib = dlopen(lib_path, RTLD_NOW); if (!lib) { fprintf(stderr, "Unable to open library %s (%s)\n", lib_path, dlerror()); return NULL; } LV2_Descriptor_Function df = dlsym(lib, "lv2_descriptor"); if (!df) { fprintf(stderr, "Could not find symbol 'lv2_descriptor', " "%s is not a LV2 plugin.\n", lib_path); dlclose(lib); return NULL; } else { // Search for plugin by URI // FIXME: Kludge to get bundle path (containing directory of binary) const char* bundle_path = slv2_uri_to_path(slv2_value_as_uri( slv2_plugin_get_bundle_uri(plugin))); //printf("Bundle path: %s\n", bundle_path); for (uint32_t i=0; 1; ++i) { const LV2_Descriptor* ld = df(i); if (!ld) { fprintf(stderr, "Did not find plugin %s in %s\n", slv2_value_as_uri(slv2_plugin_get_uri(plugin)), lib_path); dlclose(lib); break; // return NULL } else if (!strcmp(ld->URI, slv2_value_as_uri(slv2_plugin_get_uri(plugin)))) { assert(plugin->plugin_uri); //printf("Found %s at index %u in:\n\t%s\n\n", // librdf_uri_as_string(plugin->plugin_uri), i, lib_path); assert(ld->instantiate); // Create SLV2Instance to return result = malloc(sizeof(struct _Instance)); result->lv2_descriptor = ld; result->lv2_handle = ld->instantiate(ld, sample_rate, (char*)bundle_path, (features) ? features : local_features); struct _InstanceImpl* impl = malloc(sizeof(struct _InstanceImpl)); impl->lib_handle = lib; result->pimpl = impl; break; } } } if (result) { assert(slv2_plugin_get_num_ports(plugin) > 0); // Failed to instantiate if (result->lv2_handle == NULL) { //printf("Failed to instantiate %s\n", plugin->plugin_uri); free(result); return NULL; } // "Connect" all ports to NULL (catches bugs) for (uint32_t i=0; i < slv2_plugin_get_num_ports(plugin); ++i) result->lv2_descriptor->connect_port(result->lv2_handle, i, NULL); } free(local_features); return result; }
SLV2UIInstance slv2_ui_instantiate(SLV2Plugin plugin, SLV2UI ui, LV2UI_Write_Function write_function, LV2UI_Controller controller, const LV2_Feature* const* features) { struct _SLV2UIInstance* result = NULL; bool local_features = (features == NULL); if (local_features) { features = malloc(sizeof(LV2_Feature)); ((LV2_Feature**)features)[0] = NULL; } const char* const lib_uri = slv2_value_as_string(slv2_ui_get_binary_uri(ui)); const char* const lib_path = slv2_uri_to_path(lib_uri); if (!lib_path) return NULL; dlerror(); void* lib = dlopen(lib_path, RTLD_NOW); if (!lib) { fprintf(stderr, "Unable to open UI library %s (%s)\n", lib_path, dlerror()); return NULL; } LV2UI_DescriptorFunction df = dlsym(lib, "lv2ui_descriptor"); if (!df) { fprintf(stderr, "Could not find symbol 'lv2ui_descriptor', " "%s is not a LV2 plugin UI.\n", lib_path); dlclose(lib); return NULL; } else { const char* bundle_path = slv2_uri_to_path(slv2_value_as_uri(slv2_ui_get_bundle_uri(ui))); for (uint32_t i=0; 1; ++i) { const LV2UI_Descriptor* ld = df(i); if (!ld) { fprintf(stderr, "Did not find UI %s in %s\n", slv2_value_as_uri(slv2_ui_get_uri(ui)), lib_path); dlclose(lib); break; // return NULL } else if (!strcmp(ld->URI, slv2_value_as_uri(slv2_ui_get_uri(ui)))) { assert(plugin->plugin_uri); printf("Found UI %s at index %u in:\n\t%s\n\n", slv2_value_as_uri(plugin->plugin_uri), i, lib_path); assert(ld->instantiate); // Create SLV2UIInstance to return result = malloc(sizeof(struct _SLV2UIInstance)); struct _SLV2UIInstanceImpl* impl = malloc(sizeof(struct _SLV2UIInstanceImpl)); impl->lv2ui_descriptor = ld; impl->lv2ui_handle = ld->instantiate(ld, slv2_value_as_uri(slv2_plugin_get_uri(plugin)), (char*)bundle_path, write_function, controller, &impl->widget, features); impl->lib_handle = lib; result->pimpl = impl; break; } } } // Failed to instantiate if (result == NULL || result->pimpl->lv2ui_handle == NULL) { //printf("Failed to instantiate %s\n", plugin->plugin_uri); free(result); return NULL; } // Failed to create a widget, but still got a handle - this means that // the plugin is buggy if (result->pimpl->widget == NULL) { slv2_ui_instance_free(result); return NULL; } if (local_features) free((LV2_Feature**)features); return result; }