static GParamSpec * gst_lv2_class_get_param_spec (GstLV2Class * klass, gint portnum) { SLV2Plugin lv2plugin = klass->plugin; SLV2Port port = slv2_plugin_get_port_by_index (lv2plugin, portnum); SLV2Value lv2def, lv2min, lv2max; GParamSpec *ret; gchar *name; gint perms; gfloat lower = 0.0f, upper = 1.0f, def = 0.0f; name = gst_lv2_class_get_param_name (klass, portnum); perms = G_PARAM_READABLE; if (slv2_port_is_a (lv2plugin, port, input_class)) perms |= G_PARAM_WRITABLE | G_PARAM_CONSTRUCT; if (slv2_port_is_a (lv2plugin, port, control_class)) perms |= GST_PARAM_CONTROLLABLE; if (slv2_port_has_property (lv2plugin, port, toggled_prop)) { ret = g_param_spec_boolean (name, name, name, FALSE, perms); g_free (name); return ret; } slv2_port_get_range (lv2plugin, port, &lv2def, &lv2min, &lv2max); if (lv2def) def = slv2_value_as_float (lv2def); if (lv2min) lower = slv2_value_as_float (lv2min); if (lv2max) upper = slv2_value_as_float (lv2max); if (def < lower) { GST_WARNING ("%s has lower bound %f > default %f\n", slv2_value_as_string (slv2_plugin_get_uri (lv2plugin)), lower, def); lower = def; } if (def > upper) { GST_WARNING ("%s has upper bound %f < default %f\n", slv2_value_as_string (slv2_plugin_get_uri (lv2plugin)), upper, def); upper = def; } if (slv2_port_has_property (lv2plugin, port, integer_prop)) ret = g_param_spec_int (name, name, name, lower, upper, def, perms); else ret = g_param_spec_float (name, name, name, lower, upper, def, perms); g_free (name); 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 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()); }
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; }