URISet properties(World* world, SPtr<const Client::ObjectModel> model) { URISet properties; URISet types = RDFS::types(world, model); LilvNode* rdf_type = lilv_new_uri(world->lilv_world(), LILV_NS_RDF "type"); LilvNode* rdf_Property = lilv_new_uri(world->lilv_world(), LILV_NS_RDF "Property"); LilvNode* rdfs_domain = lilv_new_uri(world->lilv_world(), LILV_NS_RDFS "domain"); LilvNodes* props = lilv_world_find_nodes( world->lilv_world(), NULL, rdf_type, rdf_Property); LILV_FOREACH(nodes, p, props) { const LilvNode* prop = lilv_nodes_get(props, p); if (lilv_node_is_uri(prop)) { LilvNodes* domains = lilv_world_find_nodes( world->lilv_world(), prop, rdfs_domain, NULL); unsigned n_matching_domains = 0; LILV_FOREACH(nodes, d, domains) { const LilvNode* domain_node = lilv_nodes_get(domains, d); if (!lilv_node_is_uri(domain_node)) { // TODO: Blank node domains (e.g. unions) continue; } const Raul::URI domain(lilv_node_as_uri(domain_node)); if (types.count(domain)) { ++n_matching_domains; } } if (lilv_nodes_size(domains) == 0 || ( n_matching_domains > 0 && n_matching_domains == lilv_nodes_size(domains))) { properties.insert(Raul::URI(lilv_node_as_uri(prop))); } lilv_nodes_free(domains); } } lilv_node_free(rdfs_domain); lilv_node_free(rdf_Property); lilv_node_free(rdf_type); return properties; }
void print_port(const LilvPlugin* p, uint32_t index, float* mins, float* maxes, float* defaults) { const LilvPort* port = lilv_plugin_get_port_by_index(p, index); printf("\n\tPort %d:\n", index); if (!port) { printf("\t\tERROR: Illegal/nonexistent port\n"); return; } bool first = true; const LilvNodes* classes = lilv_port_get_classes(p, port); printf("\t\tType: "); LILV_FOREACH(nodes, i, classes) { const LilvNode* value = lilv_nodes_get(classes, i); if (!first) { printf("\n\t\t "); } printf("%s", lilv_node_as_uri(value)); first = false; } if (lilv_port_is_a(p, port, event_class)) { LilvNodes* supported = lilv_port_get_value( p, port, supports_event_pred); if (lilv_nodes_size(supported) > 0) { printf("\n\t\tSupported events:\n"); LILV_FOREACH(nodes, i, supported) { const LilvNode* value = lilv_nodes_get(supported, i); printf("\t\t\t%s\n", lilv_node_as_uri(value)); } } lilv_nodes_free(supported); }
LV2Effect::LV2Effect(const LilvPlugin *data, const std::set<wxString> & categories) : mValid(true), mCategories(categories), mMidiInput(0), mLatencyPortIndex(-1) { // We don't support any features at all, so if the plugin requires // any we skip it. LilvNodes *req = lilv_plugin_get_required_features(data); size_t nFeatures = lilv_nodes_size(req); lilv_nodes_free(req); if (nFeatures > 0) { mValid = false; return; } mData = data; pluginName = GetString(lilv_plugin_get_name(mData), true); fInBuffer = NULL; fOutBuffer = NULL; mLength = 0; // Allocate buffers for the port indices and the default control values int numPorts = lilv_plugin_get_num_ports(mData); float *minimumValues = new float [numPorts]; float *maximumValues = new float [numPorts]; float *defaultValues = new float [numPorts]; // Retrieve the port ranges for all ports (some values may be NaN) lilv_plugin_get_port_ranges_float(mData, minimumValues, maximumValues, defaultValues); // Get info about all ports for (int i = 0; i < numPorts; i++) { const LilvPort *port = lilv_plugin_get_port_by_index(mData, i); LV2Port internalPort; internalPort.mIndex = lilv_port_get_index(mData, port); // Get the port name LilvNode *tmpName = lilv_port_get_name(mData, port); internalPort.mName = GetString(tmpName); lilv_node_free(tmpName); // Get the scale points LilvScalePoints* points = lilv_port_get_scale_points(mData, port); LILV_FOREACH(scale_points, j, points) { const LilvScalePoint *point = lilv_scale_points_get(points, j); internalPort.mScaleValues.Add(lilv_node_as_float(lilv_scale_point_get_value(point))); internalPort.mScaleLabels.Add(GetString(lilv_scale_point_get_label(point))); } lilv_scale_points_free(points); // Get the groups LilvNodes *groups = lilv_port_get_value(mData, port, gPortGroup); if (groups) { LilvNode *group = lilv_nodes_get_first(groups); wxString uri = GetString(group); wxString label; const LilvNode *name = lilv_world_get(gWorld, group, gName, NULL); if (name) { label = GetString(name); } else { // Shouldn't happen, but provide something label = uri; } lilv_nodes_free(groups); // Check for new group if (mPortGroups.find(uri) == mPortGroups.end()) { mPortGroups[uri] = LV2PortGroup(label); } #if 0 // Get subgroup // // LLL: This isn't right...must find or construct a plugin with // subgroups. LilvNodes *subgroup = lilv_node_get_value(mData, port, gSubGroupOf); if (subgroups) { LilvNode *subgroup = lilv_nodes_get_first(subgroups); wxString uri = GetString(subgroup); const LilvNode *subgroup = lilv_world_get(gWorld, group, gSubGroupOf, NULL); wxString label = GetString(name); lilv_nodes_free(subgroup); } else #endif { mRootGroup.AddSubGroup(mPortGroups[uri]); } mPortGroups[uri].AddParameter(i); } else { mRootGroup.AddParameter(i); } // Get the port type if (lilv_port_is_a(mData, port, gAudioPortClass)) { if (lilv_port_is_a(mData, port, gInputPortClass)) { mAudioInputs.Add(internalPort); } else if (lilv_port_is_a(mData, port, gOutputPortClass)) { mAudioOutputs.Add(internalPort); } } else if (lilv_port_is_a(mData, port, gControlPortClass) && lilv_port_is_a(mData, port, gInputPortClass)) { internalPort.mControlBuffer = float(1.0); internalPort.mMin = minimumValues[i]; internalPort.mMax = maximumValues[i]; internalPort.mDefault = defaultValues[i]; if (isfinite(defaultValues[i])) { internalPort.mControlBuffer = defaultValues[i]; } else if (isfinite(minimumValues[i])) { internalPort.mControlBuffer = minimumValues[i]; } else if (isfinite(maximumValues[i])) { internalPort.mControlBuffer = maximumValues[i]; } if (lilv_port_has_property(mData, port, gPortToggled)) { internalPort.mToggle = true; } else if (lilv_port_has_property(mData, port, gPortIsInteger)) { internalPort.mInteger = true; } else if (lilv_port_has_property(mData, port, gPortIsSampleRate)) { internalPort.mSampleRate = true; } else if (lilv_port_has_property(mData, port, gPortIsEnumeration)) { internalPort.mEnumeration = true; } mControlInputs.Add(internalPort); } else if (lilv_port_is_a(mData, port, gControlPortClass) && lilv_port_is_a(mData, port, gOutputPortClass)) { // If there is more than one latency port, the plugin is invalid if (lilv_port_has_property(mData, port, gPortIsLatency)) { if (mLatencyPortIndex >= 0) { mValid = false; continue; } mLatencyPortIndex = i; } else if (!lilv_port_has_property(mData, port, gPortIsOptional)) { mControlOutputs.Add(internalPort); } } else if (lilv_port_is_a(mData, port, gMidiPortClass) && lilv_port_is_a(mData, port, gInputPortClass)) { // If there is more than one MIDI input port, the plugin is invalid if (mMidiInput) { mValid = false; continue; } mMidiInput = new LV2Port(internalPort); } else { // Unknown port type, we set the invalid flag // mValid = false; } } delete [] minimumValues; delete [] maximumValues; delete [] defaultValues; // MIDI synths may not have any audio inputs. if (mMidiInput && mAudioInputs.GetCount() > 0) { mValid = false; } // Determine whether the plugin is a generator, effect or analyser // depending on the number of ports of each type (not completely accurate, // but works most of the time) int flags = PLUGIN_EFFECT; if (mAudioInputs.GetCount() == 0) { flags |= INSERT_EFFECT; } else if (mAudioOutputs.GetCount() == 0) { flags |= ANALYZE_EFFECT; } else { flags |= PROCESS_EFFECT; } SetEffectFlags(flags); }
static LilvNodes* lilv_nodes_from_stream_objects_i18n(LilvWorld* world, SordIter* stream, SordQuadIndex field) { LilvNodes* values = lilv_nodes_new(); const SordNode* nolang = NULL; // Untranslated value const SordNode* partial = NULL; // Partial language match char* syslang = lilv_get_lang(); FOREACH_MATCH(stream) { const SordNode* value = sord_iter_get_node(stream, field); if (sord_node_get_type(value) == SORD_LITERAL) { const char* lang = sord_node_get_language(value); LilvLangMatch lm = LILV_LANG_MATCH_NONE; if (lang) { lm = (syslang) ? lilv_lang_matches(lang, syslang) : LILV_LANG_MATCH_PARTIAL; } else { nolang = value; if (!syslang) { lm = LILV_LANG_MATCH_EXACT; } } if (lm == LILV_LANG_MATCH_EXACT) { // Exact language match, add to results zix_tree_insert((ZixTree*)values, lilv_node_new_from_node(world, value), NULL); } else if (lm == LILV_LANG_MATCH_PARTIAL) { // Partial language match, save in case we find no exact partial = value; } } else { zix_tree_insert((ZixTree*)values, lilv_node_new_from_node(world, value), NULL); } } sord_iter_free(stream); free(syslang); if (lilv_nodes_size(values) > 0) { return values; } const SordNode* best = nolang; if (syslang && partial) { // Partial language match for system language best = partial; } else if (!best) { // No languages matches at all, and no untranslated value // Use any value, if possible best = partial; } if (best) { zix_tree_insert( (ZixTree*)values, lilv_node_new_from_node(world, best), NULL); } else { // No matches whatsoever lilv_nodes_free(values); values = NULL; } return values; }