static GParamSpec * gst_lv2_filter_class_get_param_spec (GstLV2FilterClass * klass, gint portnum) { LilvPlugin *lv2plugin = klass->plugin; const LilvPort *port = lilv_plugin_get_port_by_index (lv2plugin, portnum); LilvNode *lv2def, *lv2min, *lv2max; GParamSpec *ret; gchar *name, *nick; gint perms; gfloat lower = 0.0f, upper = 1.0f, def = 0.0f; nick = gst_lv2_filter_class_get_param_nick (klass, port); name = gst_lv2_filter_class_get_param_name (klass, port); GST_DEBUG ("%s trying port %s : %s", lilv_node_as_string (lilv_plugin_get_uri (lv2plugin)), name, nick); perms = G_PARAM_READABLE; if (lilv_port_is_a (lv2plugin, port, input_class)) perms |= G_PARAM_WRITABLE | G_PARAM_CONSTRUCT; if (lilv_port_is_a (lv2plugin, port, control_class)) perms |= GST_PARAM_CONTROLLABLE; if (lilv_port_has_property (lv2plugin, port, toggled_prop)) { ret = g_param_spec_boolean (name, nick, nick, FALSE, perms); goto done; } lilv_port_get_range (lv2plugin, port, &lv2def, &lv2min, &lv2max); if (lv2def) def = lilv_node_as_float (lv2def); if (lv2min) lower = lilv_node_as_float (lv2min); if (lv2max) upper = lilv_node_as_float (lv2max); lilv_node_free (lv2def); lilv_node_free (lv2min); lilv_node_free (lv2max); if (def < lower) { GST_WARNING ("%s has lower bound %f > default %f", lilv_node_as_string (lilv_plugin_get_uri (lv2plugin)), lower, def); lower = def; } if (def > upper) { GST_WARNING ("%s has upper bound %f < default %f", lilv_node_as_string (lilv_plugin_get_uri (lv2plugin)), upper, def); upper = def; } if (lilv_port_has_property (lv2plugin, port, integer_prop)) ret = g_param_spec_int (name, nick, nick, lower, upper, def, perms); else ret = g_param_spec_float (name, nick, nick, lower, upper, def, perms); done: g_free (name); g_free (nick); return ret; }
void EFFECT_LV2::parse_parameter_hint_information(Lilv::Plugin plugin, Lilv::Port p, struct PARAM_DESCRIPTION *pd) { /* if srate not set, use 44.1kHz (used only for calculating * param hint values */ SAMPLE_SPECS::sample_rate_t srate = samples_per_second(); /* FIXME: this is just ugly! */ if (srate <= 0) { srate = 44100; } Lilv::Node name=p.get_name(); /* parameter name */ pd->description =name.as_string(); Lilv::Node deflt(NULL); Lilv::Node min(NULL); Lilv::Node max(NULL); lilv_port_get_range(plugin.me,p.me,&deflt.me,&min.me,&max.me); bool isSRRelative=p.has_property(ECA_LV2_WORLD::PortSamplerateDependentNode()); /* upper and lower bounds */ if (min) { pd->bounded_below = true; pd->lower_bound=min.as_float(); if (isSRRelative) { pd->lower_bound *= srate; } } else { pd->bounded_below = false; } if (max) { pd->bounded_above = true; pd->upper_bound=max.as_float(); if (isSRRelative) { pd->upper_bound *= srate; } } else { pd->bounded_above = false; } /* defaults - case 1 */ if (deflt) { pd->default_value=deflt.as_float(); } /* defaults - case 2 */ else if (min && !max) { if (pd->lower_bound < 0) pd->default_value = 0.0f; else pd->default_value = pd->lower_bound; } /* defaults - case 3 */ else if (!min && max) { if (pd->upper_bound > 0) pd->default_value = 0.0f; else pd->default_value = pd->upper_bound; } /* defaults - case 4 */ else if (max && min) { if (pd->lower_bound < 0 && pd->upper_bound > 0) pd->default_value = 0.0f; else if (pd->lower_bound < 0 && pd->upper_bound < 0) pd->default_value = pd->upper_bound; else pd->default_value = pd->lower_bound; } /* defaults - case 5 */ else { DBC_CHECK(!min && !max); if (isSRRelative) pd->default_value = srate; else pd->default_value = 1.0f; } if (p.has_property(ECA_LV2_WORLD::PortToggledNode())) pd->toggled = true; else pd->toggled = false; if (p.has_property(ECA_LV2_WORLD::PortIntegerNode())) pd->integer = true; else pd->integer = false; if (p.has_property(ECA_LV2_WORLD::PortLogarithmicNode())) pd->logarithmic = true; else pd->logarithmic = false; if (p.is_a(ECA_LV2_WORLD::OutputClassNode())) pd->output = true; else pd->output = false; }
Lv2Plugin::Lv2Plugin(const LilvPlugin *plugin, LilvInstance *instance, const Lv2Constants &uris, Lv2Worker *worker) : plugin(plugin), instance(instance), midiOutputCount(0), controlConnections(4), newControlMappingsQueue(16), worker(worker) { // audio inputs audioInputCount = lilv_plugin_get_num_ports_of_class(plugin, uris.lv2AudioPort, uris.lv2InputPort, 0); audioInputIndex = new uint32_t[audioInputCount]; audioInput = new AudioConnector[audioInputCount]; // audio outputs audioOutputCount = lilv_plugin_get_num_ports_of_class(plugin, uris.lv2AudioPort, uris.lv2OutputPort, 0); audioOutputIndex = new uint32_t[audioOutputCount]; audioOutput = new AudioConnection*[audioOutputCount]; for(uint32_t i = 0; i < audioOutputCount; i++) { audioOutput[i] = new AudioConnection(this); audioOutput[i]->clear(); } // initialize port structures uint32_t numPorts = lilv_plugin_get_num_ports(plugin); uint32_t audioInputCounter = 0; uint32_t audioOutputCounter = 0; for(uint32_t i = 0; i < numPorts; i++) { const LilvPort *port = lilv_plugin_get_port_by_index(plugin, i); if(lilv_port_is_a(plugin, port, uris.lv2AudioPort)) { if(lilv_port_is_a(plugin, port, uris.lv2InputPort)) { audioInputIndex[audioInputCounter++] = i; } else if(lilv_port_is_a(plugin, port, uris.lv2OutputPort)) { audioOutputIndex[audioOutputCounter++] = i; } } else if(lilv_port_is_a(plugin, port, uris.lv2ControlPort) && lilv_port_is_a(plugin, port, uris.lv2InputPort)) { // get control name const LilvNode* symbol = lilv_port_get_symbol(plugin, port); std::string portName(lilv_node_as_string(symbol)); // create, connect and hash new control port object Lv2ControlPort *newPort = new Lv2ControlPort(); LilvNode *dfault, *minimum, *maximum; lilv_port_get_range(plugin, port, &dfault, &minimum, &maximum); newPort->dfault = dfault ? lilv_node_as_float(dfault) : 0; newPort->minimum = lilv_node_as_float(minimum); newPort->maximum = lilv_node_as_float(maximum); lilv_instance_connect_port(instance, i, &(newPort->value)); controlMap[portName] = newPort; } else if(lilv_port_is_a(plugin, port, uris.lv2AtomPort)) { // is it a MIDI/atom input? LilvNodes *atomBufferType = lilv_port_get_value(plugin, port, uris.lv2AtomBufferType); LilvNodes* atomSupports = lilv_port_get_value(plugin, port, uris.lv2AtomSupports); if (lilv_port_is_a(plugin, port, uris.lv2InputPort) && lilv_nodes_contains(atomBufferType, uris.lv2AtomSequence) && lilv_nodes_contains(atomSupports, uris.lv2MidiEvent)) { // create new inputs and connect to atom sequence location Lv2MidiInput *newAtomPort = new Lv2MidiInput(); lilv_instance_connect_port(instance, i, newAtomPort->getAtomSequence()); midiInputList.add(newAtomPort); } else if (lilv_port_is_a(plugin, port, uris.lv2OutputPort)) { //atomSequence->atom.type = Lv2PluginFactory::instance()->uridMapper.uriToId(LV2_ATOM__Sequence); Lv2MidiOutput *midiOutput = new Lv2MidiOutput(this); lilv_instance_connect_port(instance, i, midiOutput->getAtomSequence()); midiOutputList.add(midiOutput); midiOutputCount++; } else { // warn std::cout << "!!! unknown atom port at index " << i << ": " << lilv_node_as_string(lilv_port_get_name(plugin, port)) << std::endl; } lilv_nodes_free(atomSupports); lilv_nodes_free(atomBufferType); } else { lilv_instance_connect_port(instance, i, NULL); std::cout << "!!! unknown port at index " << i << ": " << lilv_node_as_string(lilv_port_get_name(plugin, port)) << std::endl; } } }