Beispiel #1
0
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;
}
Beispiel #2
0
static gchar *
gst_lv2_class_get_param_name (GstLV2Class * klass, gint portnum)
{
  SLV2Plugin lv2plugin = klass->plugin;
  SLV2Port port = slv2_plugin_get_port_by_index (lv2plugin, portnum);
  return g_strdup (slv2_value_as_string (slv2_port_get_symbol (lv2plugin,
              port)));
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
const ScalePointMap& LV2Effect::GetScalePoints() {

   if (!mScalePointsRetrieved) {
      
      char scalePointQuery[] = 
         "PREFIX : <http://lv2plug.in/ns/lv2core#>\n"
         "SELECT ?index, ?value, ?label WHERE {\n"
         "<> :port ?port.\n"
         "?port a :ControlPort.\n"
         "?port a :InputPort.\n"
         "?port :index ?index.\n"
         "?port :scalePoint ?point.\n"
         "?point rdf:value ?value.\n"
         "?point rdfs:label ?label.\n"
         "}";
      
      SLV2Values portIndices = slv2_plugin_query_variable(mData, 
                                                          scalePointQuery, 0);
      SLV2Values pointValues = slv2_plugin_query_variable(mData, 
                                                          scalePointQuery, 1);
      SLV2Values pointLabels = slv2_plugin_query_variable(mData, 
                                                          scalePointQuery, 2);
      
      size_t nScalePoints = slv2_values_size(portIndices);
      for (size_t i = 0; i < nScalePoints; ++i) {
         uint32_t idx = slv2_value_as_int(slv2_values_get_at(portIndices, i));
         float value = slv2_value_as_float(slv2_values_get_at(pointValues, i));
         wxString label = wxString::FromUTF8(slv2_value_as_string(slv2_values_get_at(pointLabels, i)));
         mScalePoints[idx][value] = label;
      }
      slv2_values_free(portIndices);
      slv2_values_free(pointValues);
      slv2_values_free(pointLabels);
      
      mScalePointsRetrieved = true;
   }
   
   return mScalePoints;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
QString Lv2Plugin::copyright () const
{
  return m_copyright ? slv2_value_as_string( m_copyright ) : NULL;
}
Beispiel #10
0
QString Lv2Plugin::authorHomepage () const
{
  return m_authorHomepage ? slv2_value_as_string( m_authorHomepage ) : NULL;
}
Beispiel #11
0
QString Lv2Plugin::authorEmail () const
{
  return m_authorEmail ? slv2_value_as_string( m_authorEmail ) : NULL;
}
Beispiel #12
0
QString Lv2Plugin::authorName () const
{
  return m_authorName ? slv2_value_as_string( m_authorName ) : "Unknown";
}
Beispiel #13
0
LV2EffectDialog::LV2EffectDialog(LV2Effect *eff,
                                 wxWindow * parent,
                                 SLV2Plugin data,
                                 int sampleRate,
                                 double length,
                                 double noteLength,
                                 unsigned char noteVelocity,
                                 unsigned char noteKey)
   :wxDialog(parent, -1, 
             LAT1CTOWX(slv2_value_as_string(slv2_plugin_get_name(data))),
             wxDefaultPosition, wxDefaultSize,
             wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
    effect(eff),
    mControls(eff->GetControls())
{
   mLength = length;
   this->mData = data;
   this->sampleRate = sampleRate;
	#ifdef __WXMSW__
		// On Windows, for some reason, wxWindows calls OnTextCtrl during creation
		// of the text control, and LV2EffectDialog::OnTextCtrl calls HandleText, 
		// which assumes all the fields have been initialized. 
		// This can give us a bad pointer crash, so manipulate inSlider to 
		// no-op HandleText during creation.
		inSlider = true;
	#else
		inSlider = false;
	#endif
   inText = false;
   
   // Allocate memory for the user parameter controls
   toggles = new wxCheckBox*[mControls.size()];
   sliders = new wxSlider*[mControls.size()];
   fields = new wxTextCtrl*[mControls.size()];
   labels = new wxStaticText*[mControls.size()];
   
   wxControl *item;

   wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL);
   
   // Add information about the plugin
   SLV2Value tmpValue = slv2_plugin_get_author_name(data);
   if (tmpValue) {
      const char* author = slv2_value_as_string(tmpValue);
      item = new wxStaticText(this, 0,
                              wxString(_("Author: "))+LAT1CTOWX(author));
      vSizer->Add(item, 0, wxALL, 5);
      slv2_value_free(tmpValue);
   }
   
   wxScrolledWindow *w = new wxScrolledWindow(this,
                                              wxID_ANY,
                                              wxDefaultPosition,
                                              wxDefaultSize,
                                              wxVSCROLL | wxTAB_TRAVERSAL);

   // Try to give the window a sensible default/minimum size
   w->SetMinSize(wxSize(
      wxMax(600, parent->GetSize().GetWidth() * 2/3),
      parent->GetSize().GetHeight() / 2));
                                              
   w->SetScrollRate(0, 20);
   vSizer->Add(w, 1, wxEXPAND|wxALL, 5);

   // Preview, OK, & Cancel buttons
   vSizer->Add(CreateStdButtonSizer(this, ePreviewButton|eCancelButton|eOkButton), 0, wxEXPAND);

   SetSizer(vSizer);

   wxSizer *paramSizer =
      new wxStaticBoxSizer(wxVERTICAL, w, _("Effect Settings"));

   wxFlexGridSizer *gridSizer =
      new wxFlexGridSizer(5, 0, 0);
   gridSizer->AddGrowableCol(3);
   
   const LV2PortGroup& rootGroup = eff->GetPortGroups();
   const ScalePointMap& scalePoints = eff->GetScalePoints();
   
   // Now add the length control
   if (effect->GetEffectFlags() & INSERT_EFFECT) {
      item = new wxStaticText(w, 0, _("Length (seconds)"));
      gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
      mSeconds = new wxTextCtrl(w, LADSPA_SECONDS_ID, Internat::ToDisplayString(length));
      mSeconds->SetName(_("Length (seconds)"));
      gridSizer->Add(mSeconds, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
      gridSizer->Add(1, 1, 0);
      gridSizer->Add(1, 1, 0);
      gridSizer->Add(1, 1, 0);
      ConnectFocus(mSeconds);
   }
   
   // The note controls if the plugin is a synth
   if (effect->IsSynth()) {
      
      // Note length control
      item = new wxStaticText(w, 0, _("Note length (seconds)"));
      gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
      mNoteSeconds = new wxTextCtrl(w, LADSPA_SECONDS_ID, Internat::ToDisplayString(length / 2));
      mNoteSeconds->SetName(_("Note length (seconds)"));
      gridSizer->Add(mNoteSeconds, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
      gridSizer->Add(1, 1, 0);
      gridSizer->Add(1, 1, 0);
      gridSizer->Add(1, 1, 0);
      ConnectFocus(mNoteSeconds);
      
      // Note velocity control
      item = new wxStaticText(w, 0, _("Note velocity"));
      gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
      mNoteVelocity = new wxTextCtrl(w, LADSPA_SECONDS_ID, Internat::ToDisplayString(64));
      mNoteVelocity->SetName(_("Note velocity"));
      gridSizer->Add(mNoteVelocity, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
      gridSizer->Add(1, 1, 0);
      gridSizer->Add(1, 1, 0);
      gridSizer->Add(1, 1, 0);
      ConnectFocus(mNoteVelocity);

      // Note key control
      item = new wxStaticText(w, 0, _("Note key"));
      gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
      mNoteKey = new wxTextCtrl(w, LADSPA_SECONDS_ID, Internat::ToDisplayString(64));
      mNoteKey->SetName(_("Note key"));
      gridSizer->Add(mNoteKey, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
      gridSizer->Add(1, 1, 0);
      gridSizer->Add(1, 1, 0);
      gridSizer->Add(1, 1, 0);
      ConnectFocus(mNoteKey);
   }

   paramSizer->Add(gridSizer, 1, wxEXPAND | wxALL, 5);

   // Create user parameter controls
   std::queue<const LV2PortGroup*> groups;
   groups.push(&rootGroup);
   
   while (!groups.empty()) {
      
      const LV2PortGroup* pg = groups.front();
      groups.pop();
      
      if (pg->GetName() != wxT("")) {
         wxSizer *groupSizer =
            new wxStaticBoxSizer(wxVERTICAL, w, pg->GetName());
         paramSizer->Add(groupSizer, 0, wxEXPAND | wxALL, 5);
         gridSizer = new wxFlexGridSizer(5, 0, 0);
         gridSizer->AddGrowableCol(3);
         groupSizer->Add(gridSizer, 1, wxEXPAND | wxALL, 5);
      }
      
      std::vector<LV2PortGroup>::const_iterator iter;
      for (iter = pg->GetSubGroups().begin(); iter != pg->GetSubGroups().end();
           ++iter) {
         groups.push(&*iter);
      }
      
      const std::vector<uint32_t>& params = pg->GetParameters();
      for (uint32_t k = 0; k < params.size(); ++k) {
         uint32_t p = params[k];
         
         wxString labelText = mControls[p].mName;
         item = new wxStaticText(w, 0, labelText + wxT(":"));
         gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
         
         wxString fieldText;
         
         if (mControls[p].mToggle) {
            toggles[p] = new wxCheckBox(w, p, wxT(""));
            toggles[p]->SetName(labelText);
            toggles[p]->SetValue(mControls[p].mControlBuffer > 0);
            gridSizer->Add(toggles[p], 0, wxALL, 5);
            ConnectFocus(toggles[p]);
            
            gridSizer->Add(1, 1, 0);
            gridSizer->Add(1, 1, 0);
            gridSizer->Add(1, 1, 0);
         }
         
         else {
            if (mControls[p].mInteger)
               fieldText.Printf(wxT("%d"), (int)(mControls[p].mControlBuffer + 0.5));
            else
               fieldText = Internat::ToDisplayString(mControls[p].mControlBuffer);
            
            fields[p] = new wxTextCtrl(w, p, fieldText);
            fields[p]->SetName(labelText);
            gridSizer->Add(fields[p], 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
            ConnectFocus(fields[p]);
            
            wxString bound;
            double lower = 0.0;
            double upper = 0.0;
            bool haslo = false;
            bool hashi = false;
            bool forceint = false;
            wxString loLabel;
            wxString hiLabel;
            
            ScalePointMap::const_iterator iter = 
               scalePoints.find(mControls[p].mIndex);
            
            if (!std::isnan(mControls[p].mMin)) {
               lower = mControls[p].mMin;
               haslo = true;
               if (iter != scalePoints.end()) {
                  std::map<float, wxString>::const_iterator iter2 =
                     iter->second.find(lower);
                  if (iter2 != iter->second.end()) {
                     loLabel = iter2->second;
                  }
               }
            }
            
            if (!std::isnan(mControls[p].mMax)) {
               upper = mControls[p].mMax;
               hashi = true;
               if (iter != scalePoints.end()) {
                  std::map<float, wxString>::const_iterator iter2 =
                     iter->second.find(upper);
                  if (iter2 != iter->second.end())
                     hiLabel = iter2->second;
               }
            }
            
            if (mControls[p].mSampleRate) {
               lower *= sampleRate * 1000;
               upper *= sampleRate;
               forceint = true;
            }
            
            wxString str;
            if (haslo) {
               str = loLabel;
               if (str.IsEmpty()) {
                  if (mControls[p].mInteger || forceint)
                     str.Printf(wxT("%d"), (int)(lower + 0.5));
                  else
                     str = Internat::ToDisplayString(lower);
               }
               item = new wxStaticText(w, 0, str);
               gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
            }
            else {
               gridSizer->Add(1, 1, 0);
            }
            
            sliders[p] =
               new wxSlider(w, p,
                            0, 0, 1000,
                            wxDefaultPosition,
                            wxSize(200, -1));
            sliders[p]->SetName(labelText);
            gridSizer->Add(sliders[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 5);
            ConnectFocus(sliders[p]);
            
            if (hashi) {
               str = hiLabel;
               if (str.IsEmpty()) {
                  if (mControls[p].mInteger || forceint)
                     str.Printf(wxT("%d"), (int)(upper + 0.5));
                  else
                     str = Internat::ToDisplayString(upper);
               }
               item = new wxStaticText(w, 0, str);
               gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 5);
            }
            else {
               gridSizer->Add(1, 1, 0);
            }
         }
      }
   }
   
   // Set all of the sliders based on the value in the
   // text fields
   inSlider = false; // Now we're ready for HandleText to actually do something.
   HandleText();
   
   w->SetSizer(paramSizer);

   Layout();
   Fit();
   SetSizeHints(GetSize());
}
Beispiel #14
0
LV2Effect::LV2Effect(SLV2Plugin data,
                     const std::set<wxString>& categories)
   : mValid(true),
     mCategories(categories),
     mMidiInput(0),
     mScalePointsRetrieved(false),
     mPortGroupsRetrieved(false) {
   
   // We don't support any features at all, so if the plugin requires
   // any we skip it.
   SLV2Values req = slv2_plugin_get_required_features(data);
   size_t nFeatures = slv2_values_size(req);
   slv2_values_free(req);
   if (nFeatures > 0) {
      mValid = false;
      return;
   }

   mData = data;
   pluginName = 
      wxString::FromUTF8(slv2_value_as_string(slv2_plugin_get_name(mData)));
   
   fInBuffer = NULL;
   fOutBuffer = NULL;
   
   mLength = 0;

   uint32_t p;
   
   // Allocate buffers for the port indices and the default control values
   uint32_t numPorts = slv2_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)
   slv2_plugin_get_port_ranges_float(mData, minimumValues, 
                                     maximumValues, defaultValues);
   
   // Get info about all ports
   for(p = 0; p < numPorts; p++) {
      SLV2Port port = slv2_plugin_get_port_by_index(mData, p);
      LV2Port internalPort;
      internalPort.mIndex = p;

      // Get the port name
      SLV2Value tmpName = slv2_port_get_name(data, port);
      internalPort.mName = LAT1CTOWX(slv2_value_as_string(tmpName));
      slv2_value_free(tmpName);
      
      // Get the port type
      if (slv2_port_is_a(mData, port, gAudioPortClass)) {
         if (slv2_port_is_a(mData, port, gInputPortClass))
            mAudioInputs.push_back(internalPort);
         else if (slv2_port_is_a(mData, port, gOutputPortClass))
            mAudioOutputs.push_back(internalPort);
      }

      else if (slv2_port_is_a(mData, port, gControlPortClass) &&
          slv2_port_is_a(mData, port, gInputPortClass)) {
         internalPort.mControlBuffer = float(1.0);
         internalPort.mMin = minimumValues[p];
         internalPort.mMax = maximumValues[p];
         internalPort.mDefault = defaultValues[p];
         if (std::isfinite(defaultValues[p]))
            internalPort.mControlBuffer = defaultValues[p];
         else if (std::isfinite(minimumValues[p]))
            internalPort.mControlBuffer = minimumValues[p];
         else if (std::isfinite(maximumValues[p]))
            internalPort.mControlBuffer = maximumValues[p];
         if (slv2_port_has_property(data, port, gPortToggled))
            internalPort.mToggle = true;
         if (slv2_port_has_property(data, port, gPortIsInteger))
            internalPort.mInteger = true;
         if (slv2_port_has_property(data, port, gPortIsSampleRate))
            internalPort.mSampleRate = true;

         mControlInputs.push_back(internalPort);
      }
      
      else if (slv2_port_is_a(mData, port, gMidiPortClass) &&
               slv2_port_is_a(mData, port, gInputPortClass)) {
         // If there are more than one MIDI input ports, 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.size() > 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)
   flags = PLUGIN_EFFECT;
   if (mAudioInputs.size() == 0)
      flags |= INSERT_EFFECT;
   else if (mAudioOutputs.size() == 0)
      flags |= ANALYZE_EFFECT;
   else
      flags |= PROCESS_EFFECT;
   
}
Beispiel #15
0
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;
}
Beispiel #16
0
static void
gst_lv2_base_init (gpointer g_class)
{
  GstLV2Class *klass = (GstLV2Class *) g_class;
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
  GstSignalProcessorClass *gsp_class = GST_SIGNAL_PROCESSOR_CLASS (g_class);
  GstElementDetails *details;
  SLV2Plugin lv2plugin;
  SLV2Value val;
  guint j, audio_in_count, audio_out_count, control_in_count, control_out_count;
  gchar *klass_tags;

  GST_DEBUG ("base_init %p", g_class);

  lv2plugin = (SLV2Plugin) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
      GST_SLV2_PLUGIN_QDATA);

  g_assert (lv2plugin);

  /* pad templates */
  gsp_class->num_audio_in = 0;
  gsp_class->num_audio_out = 0;
  /* properties */
  gsp_class->num_control_in = 0;
  gsp_class->num_control_out = 0;

  for (j = 0; j < slv2_plugin_get_num_ports (lv2plugin); j++) {
    SLV2Port port = slv2_plugin_get_port_by_index (lv2plugin, j);
    if (slv2_port_is_a (lv2plugin, port, audio_class)) {
      gchar *name =
          g_strdup (slv2_value_as_string (slv2_port_get_symbol (lv2plugin,
                  port)));

      GST_DEBUG ("LV2 port name: \"%s\"", name);

      if (slv2_port_is_a (lv2plugin, port, input_class))
        gst_signal_processor_class_add_pad_template (gsp_class, name,
            GST_PAD_SINK, gsp_class->num_audio_in++);
      else if (slv2_port_is_a (lv2plugin, port, output_class))
        gst_signal_processor_class_add_pad_template (gsp_class, name,
            GST_PAD_SRC, gsp_class->num_audio_out++);
      /* TODO: else ignore plugin */

      g_free (name);
    } else if (slv2_port_is_a (lv2plugin, port, control_class)) {
      if (slv2_port_is_a (lv2plugin, port, input_class))
        gsp_class->num_control_in++;
      else if (slv2_port_is_a (lv2plugin, port, output_class))
        gsp_class->num_control_out++;
      /* TODO: else ignore plugin */
    }
    /* TODO: else ignore plugin */
  }

  /* construct the element details struct */
  details = g_new0 (GstElementDetails, 1);
  val = slv2_plugin_get_name (lv2plugin);
  if (val) {
    details->longname = g_strdup (slv2_value_as_string (val));
    slv2_value_free (val);
  } else {
    details->longname = g_strdup ("no description available");
  }
  details->description = details->longname;
  val = slv2_plugin_get_author_name (lv2plugin);
  if (val) {
    details->author = g_strdup (slv2_value_as_string (val));
    slv2_value_free (val);
  } else {
    details->author = g_strdup ("no author available");
  }

  if (gsp_class->num_audio_in == 0)
    klass_tags = "Source/Audio/LV2";
  else if (gsp_class->num_audio_out == 0) {
    if (gsp_class->num_control_out == 0)
      klass_tags = "Sink/Audio/LV2";
    else
      klass_tags = "Sink/Analyzer/Audio/LV2";
  } else
    klass_tags = "Filter/Effect/Audio/LV2";

  details->klass = klass_tags;
  GST_INFO ("tags : %s", details->klass);
  gst_element_class_set_details (element_class, details);
  g_free (details->longname);
  g_free (details->author);
  g_free (details);

  klass->audio_in_portnums = g_new0 (gint, gsp_class->num_audio_in);
  klass->audio_out_portnums = g_new0 (gint, gsp_class->num_audio_out);
  klass->control_in_portnums = g_new0 (gint, gsp_class->num_control_in);
  klass->control_out_portnums = g_new0 (gint, gsp_class->num_control_out);

  audio_in_count = audio_out_count = control_in_count = control_out_count = 0;

  for (j = 0; j < slv2_plugin_get_num_ports (lv2plugin); j++) {
    SLV2Port port = slv2_plugin_get_port_by_index (lv2plugin, j);
    gboolean is_input = slv2_port_is_a (lv2plugin, port, input_class);
    if (slv2_port_is_a (lv2plugin, port, audio_class)) {
      if (is_input)
        klass->audio_in_portnums[audio_in_count++] = j;
      else
        klass->audio_out_portnums[audio_out_count++] = j;
    } else if (slv2_port_is_a (lv2plugin, port, control_class)) {
      if (is_input)
        klass->control_in_portnums[control_in_count++] = j;
      else
        klass->control_out_portnums[control_out_count++] = j;
    }
  }

  g_assert (audio_in_count == gsp_class->num_audio_in);
  g_assert (audio_out_count == gsp_class->num_audio_out);
  g_assert (control_in_count == gsp_class->num_control_in);
  g_assert (control_out_count == gsp_class->num_control_out);

  /*if (!LV2_IS_INPLACE_BROKEN (desc->Properties))
     GST_SIGNAL_PROCESSOR_CLASS_SET_CAN_PROCESS_IN_PLACE (klass); */

  klass->plugin = lv2plugin;
}
Beispiel #17
0
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;
}