Result LV2Module::instantiate (double samplerate) { freeInstance(); currentSampleRate = samplerate; features.clearQuick(); world.getFeatures (features); // check for a worker interface LilvNodes* nodes = lilv_plugin_get_extension_data (plugin); LILV_FOREACH (nodes, iter, nodes) { const LilvNode* node = lilv_nodes_get (nodes, iter); if (lilv_node_equals (node, world.work_interface)) { worker = new LV2Worker (world.getWorkThread(), 1); features.add (worker->getFeature()); } } lilv_nodes_free (nodes); nodes = nullptr; features.add (nullptr); instance = lilv_plugin_instantiate (plugin, samplerate, features.getRawDataPointer()); if (instance == nullptr) { features.clearQuick(); worker = nullptr; return Result::fail ("Could not instantiate plugin."); } if (const void* data = getExtensionData (LV2_WORKER__interface)) { assert (worker != nullptr); worker->setSize (2048); worker->setInterface (lilv_instance_get_handle (instance), (LV2_Worker_Interface*) data); } else if (worker) { features.removeFirstMatchingValue (worker->getFeature()); worker = nullptr; } return Result::ok(); }
LILV_API bool lilv_state_equals(const LilvState* a, const LilvState* b) { if (!lilv_node_equals(a->plugin_uri, b->plugin_uri) || (a->label && !b->label) || (b->label && !a->label) || (a->label && b->label && strcmp(a->label, b->label)) || a->num_props != b->num_props || a->num_values != b->num_values) { return false; } for (uint32_t i = 0; i < a->num_values; ++i) { PortValue* const av = &a->values[i]; PortValue* const bv = &b->values[i]; if (av->size != bv->size || av->type != bv->type || strcmp(av->symbol, bv->symbol) || memcmp(av->value, bv->value, av->size)) { return false; } } for (uint32_t i = 0; i < a->num_props; ++i) { Property* const ap = &a->props[i]; Property* const bp = &b->props[i]; if (ap->key != bp->key || ap->type != bp->type || ap->flags != bp->flags) { return false; } else if (ap->type == a->atom_Path) { if (!lilv_file_equals(lilv_state_rel2abs(a, (char*)ap->value), lilv_state_rel2abs(b, (char*)bp->value))) { return false; } } else if (ap->size != bp->size || memcmp(ap->value, bp->value, ap->size)) { return false; } } return true; }
wxArrayString LV2EffectsModule::FindPlugins(PluginManagerInterface & WXUNUSED(pm)) { // Retrieve data about all LV2 plugins const LilvPlugins *plugs = lilv_world_get_all_plugins(gWorld); // Iterate over all plugins retrieve their URI wxArrayString plugins; LILV_FOREACH(plugins, i, plugs) { const LilvPlugin *plug = lilv_plugins_get(plugs, i); // Bypass Instrument (MIDI) plugins for now const LilvPluginClass *cls = lilv_plugin_get_class(plug); if (lilv_node_equals(lilv_plugin_class_get_uri(cls), LV2Effect::gInstrument)) { continue; } plugins.Add(LilvString(lilv_plugin_get_uri(plug))); } return plugins; }
/* Convert an LV2 port role to a Gst channel positon * WARNING: If the group has only a single port, * GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER will be returned for pg:centerRole * (which is used by LV2 for mono groups), but this is not correct. In this * case the value must be changed to GST_AUDIO_CHANNEL_POSITION_FRONT_MONO * (this can't be done by this function because this information isn't known * at the time it is used). */ static GstAudioChannelPosition gst_lv2_filter_role_to_position (LilvNode * role) { /* Front. Mono and left/right are mututally exclusive */ if (lilv_node_equals (role, center_role)) { return GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER; } else if (lilv_node_equals (role, left_role)) { return GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; } else if (lilv_node_equals (role, right_role)) { return GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; /* Rear. Left/right and center are mututally exclusive */ } else if (lilv_node_equals (role, rear_center_role)) { return GST_AUDIO_CHANNEL_POSITION_REAR_CENTER; } else if (lilv_node_equals (role, rear_left_role)) { return GST_AUDIO_CHANNEL_POSITION_REAR_LEFT; } else if (lilv_node_equals (role, rear_right_role)) { return GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT; /* Subwoofer/low-frequency-effects */ } else if (lilv_node_equals (role, lfe_role)) { return GST_AUDIO_CHANNEL_POSITION_LFE1; /* Center front speakers. Center and left/right_of_center * are mutually exclusive */ } else if (lilv_node_equals (role, center_left_role)) { return GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER; } else if (lilv_node_equals (role, center_right_role)) { return GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER; /* sides */ } else if (lilv_node_equals (role, side_left_role)) { return GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT; } else if (lilv_node_equals (role, side_right_role)) { return GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT; } return GST_AUDIO_CHANNEL_POSITION_INVALID; }
static double bench(const LilvPlugin* p, uint32_t sample_count, uint32_t block_size) { URITable uri_table; uri_table_init(&uri_table); LV2_URID_Map map = { &uri_table, uri_table_map }; LV2_Feature map_feature = { LV2_URID_MAP_URI, &map }; LV2_URID_Unmap unmap = { &uri_table, uri_table_unmap }; LV2_Feature unmap_feature = { LV2_URID_UNMAP_URI, &unmap }; const LV2_Feature* features[] = { &map_feature, &unmap_feature, NULL }; float* const buf = (float*)calloc(block_size * 2, sizeof(float)); float* const in = buf; float* const out = buf + block_size; if (!buf) { fprintf(stderr, "Out of memory\n"); return 0.0; } LV2_Atom_Sequence seq = { { sizeof(LV2_Atom_Sequence_Body), uri_table_map(&uri_table, LV2_ATOM__Sequence) }, { 0, 0 } }; const char* uri = lilv_node_as_string(lilv_plugin_get_uri(p)); LilvNodes* required = lilv_plugin_get_required_features(p); LILV_FOREACH(nodes, i, required) { const LilvNode* feature = lilv_nodes_get(required, i); if (!lilv_node_equals(feature, urid_map)) { fprintf(stderr, "<%s> requires feature <%s>, skipping\n", uri, lilv_node_as_uri(feature)); free(buf); uri_table_destroy(&uri_table); return 0.0; } } LilvInstance* instance = lilv_plugin_instantiate(p, 48000.0, features); if (!instance) { fprintf(stderr, "Failed to instantiate <%s>\n", lilv_node_as_uri(lilv_plugin_get_uri(p))); free(buf); uri_table_destroy(&uri_table); return 0.0; } float* controls = (float*)calloc( lilv_plugin_get_num_ports(p), sizeof(float)); lilv_plugin_get_port_ranges_float(p, NULL, NULL, controls); const uint32_t n_ports = lilv_plugin_get_num_ports(p); for (uint32_t index = 0; index < n_ports; ++index) { const LilvPort* port = lilv_plugin_get_port_by_index(p, index); if (lilv_port_is_a(p, port, lv2_ControlPort)) { lilv_instance_connect_port(instance, index, &controls[index]); } else if (lilv_port_is_a(p, port, lv2_AudioPort) || lilv_port_is_a(p, port, lv2_CVPort)) { if (lilv_port_is_a(p, port, lv2_InputPort)) { lilv_instance_connect_port(instance, index, in); } else if (lilv_port_is_a(p, port, lv2_OutputPort)) { lilv_instance_connect_port(instance, index, out); } else { fprintf(stderr, "<%s> port %d neither input nor output, skipping\n", uri, index); lilv_instance_free(instance); free(buf); free(controls); uri_table_destroy(&uri_table); return 0.0; } } else if (lilv_port_is_a(p, port, atom_AtomPort)) { lilv_instance_connect_port(instance, index, &seq); } else { fprintf(stderr, "<%s> port %d has unknown type, skipping\n", uri, index); lilv_instance_free(instance); free(buf); free(controls); uri_table_destroy(&uri_table); return 0.0; } } lilv_instance_activate(instance); struct timespec ts = bench_start(); for (uint32_t i = 0; i < (sample_count / block_size); ++i) { lilv_instance_run(instance, block_size); } const double elapsed = bench_end(&ts); lilv_instance_deactivate(instance); lilv_instance_free(instance); uri_table_destroy(&uri_table); if (full_output) { printf("%d %d ", block_size, sample_count); } printf("%lf %s\n", elapsed, uri); free(buf); free(controls); return elapsed; }