Esempio n. 1
0
	LILV_FOREACH(plugins, i, list) {
		const LilvPlugin* p = lilv_plugins_get(list, i);
		if (show_names) {
			LilvNode* n = lilv_plugin_get_name(p);
			printf("%s\n", lilv_node_as_string(n));
			lilv_node_free(n);
		} else {
			printf("%s\n", lilv_node_as_uri(lilv_plugin_get_uri(p)));
		}
	}
Esempio n. 2
0
String
LV2Module::getName() const
{
   if (LilvNode* node = lilv_plugin_get_name (plugin))
   {
       String name = CharPointer_UTF8 (lilv_node_as_string (node));
       lilv_node_free (node);
       return name;
   }

   return String::empty;
}
Esempio n. 3
0
LV2EffectDialog::LV2EffectDialog(LV2Effect *effect,
                                 wxWindow  *parent,
                                 const LilvPlugin *data,
                                 int sampleRate,
                                 double length,
                                 double WXUNUSED(noteLength),
                                 unsigned char WXUNUSED(noteVelocity),
                                 unsigned char WXUNUSED(noteKey))
:  wxDialog(parent, wxID_ANY, 
            mEffect->GetString(lilv_plugin_get_name(data)),
            wxDefaultPosition, wxSize(500, -1),
            wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
   mEffect(effect),
   mData(data),
   mControls(effect->GetControls()),
   mSampleRate(sampleRate),
   mLength(length)
{

#if defined(__WXMSW__)
   // On Windows, for some reason, wxWindows calls OnTextCtrl during creation
   // of the text control, and LV2EffectDialog::OnTextCtrl calls HandleText,
   // which assumes all the mFields 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;
   inText = true;
   
   // Allocate memory for the user parameter controls
   int ctrlcnt = (int) mControls.GetCount();
   mToggles = new wxCheckBox*[ctrlcnt];
   mSliders = new wxSlider*[ctrlcnt];
   mFields = new wxTextCtrl*[ctrlcnt];
   mLabels = new wxStaticText*[ctrlcnt];
   mEnums = new wxChoice*[ctrlcnt];
   
   wxControl *item;

   wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL);
   
   // Add information about the plugin
   LilvNode *tmpValue = lilv_plugin_get_author_name(data);
   if (tmpValue)
   {
      wxString author(_("Author: ") + mEffect->GetString(tmpValue));
      item = new wxStaticText(this, wxID_ANY, author);
      vSizer->Add(item, 0, wxALL, 5);
      lilv_node_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);
   
   // Now add the length control
   if (mEffect->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 (mEffect->IsSynth())
   {
      // Note length control
      item = new wxStaticText(w, wxID_ANY, _("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, wxID_ANY, _("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, wxID_ANY, _("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(&mEffect->GetRootGroup());
   
   while (!groups.empty())
   {
      const LV2PortGroup* pg = groups.front();
      groups.pop();

      if (pg->GetName() != wxEmptyString)
      {
         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);
      }

      const LV2PortGroupArray & subgroups = pg->GetSubGroups();
      LV2PortGroupArray::const_iterator si;
      for (si = subgroups.begin(); si != subgroups.end(); si++)
      {
         if ((*si)->GetParameters().GetCount() != 0)
         {
            groups.push(*si);
         }
      }
      
      const wxArrayInt & params = pg->GetParameters();
      for (size_t pi = 0; pi < params.GetCount(); pi++)
      {
         int p = params[pi];
         if (p >= ctrlcnt)
         {
            continue;
         }
         LV2Port & port = mControls[p];

         wxString labelText = port.mName;
         item = new wxStaticText(w, 0, labelText + wxT(":"));
         gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
         
         wxString fieldText;

         if (port.mToggle)
         {
            mToggles[p] = new wxCheckBox(w, p, wxT(""));
            mToggles[p]->SetName(labelText);
            mToggles[p]->SetValue(port.mControlBuffer > 0);
            gridSizer->Add(mToggles[p], 0, wxALL, 5);
            ConnectFocus(mToggles[p]);
            
            gridSizer->Add(1, 1, 0);
            gridSizer->Add(1, 1, 0);
            gridSizer->Add(1, 1, 0);
         }
         else if (port.mEnumeration)
         {
            mEnums[p] = new wxChoice(w, p);
            mEnums[p]->SetName(labelText);
            mEnums[p]->Append(port.mScaleLabels);
            int s;
            for (s = (int) port.mScaleValues.GetCount() - 1; s >= 0; s--)
            {
               if (port.mControlBuffer >= port.mScaleValues[s])
               {
                  break;
               }
            }
            if (s < 0)
            {
               s = 0;
            }
            mEnums[p]->SetSelection(s);
            gridSizer->Add(mEnums[p], 0, wxALL | wxEXPAND, 5);
            ConnectFocus(mEnums[p]);
            
            gridSizer->Add(1, 1, 0);
            gridSizer->Add(1, 1, 0);
            gridSizer->Add(1, 1, 0);
         }
         else
         {
            if (port.mInteger)
            {
               fieldText.Printf(wxT("%d"), (int)(port.mControlBuffer + 0.5));
            }
            else
            {
               fieldText = Internat::ToDisplayString(port.mControlBuffer);
            }
            
            mFields[p] = new wxTextCtrl(w, p, fieldText);
            mFields[p]->SetName(labelText);
            gridSizer->Add(mFields[p], 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
            ConnectFocus(mFields[p]);

            wxString bound;
            double lower = 0.0;
            double upper = 0.0;
            bool haslo = false;
            bool hashi = false;
            bool forceint = false;
            wxString loLabel;
            wxString hiLabel;
#if 0
            ScalePointMap::const_iterator iter = 
               scalePoints.find(port.mIndex);
            
            if (!wxNaN(port.mMin))
            {
               lower = port.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 (!isnan(port.mMax))
            {
               upper = port.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;
                  }
               }
            }
#endif
            if (port.mSampleRate)
            {
               lower *= mSampleRate * 1000;
               upper *= mSampleRate;
               forceint = true;
            }
            
            wxString str;
            if (haslo)
            {
               str = loLabel;
               if (str.IsEmpty())
               {
                  if (port.mInteger || forceint)
                  {
                     str.Printf(wxT("%d"), (int)(lower + 0.5));
                  }
                  else
                  {
                     str = Internat::ToDisplayString(lower);
                  }
               }
               item = new wxStaticText(w, wxID_ANY, str);
               gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
            }
            else
            {
               gridSizer->Add(1, 1, 0);
            }

            mSliders[p] =
               new wxSlider(w, p,
                            0, 0, 1000,
                            wxDefaultPosition,
                            wxSize(200, -1));
            mSliders[p]->SetName(labelText);
            gridSizer->Add(mSliders[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 5);
            ConnectFocus(mSliders[p]);
            
            if (hashi)
            {
               str = hiLabel;
               if (str.IsEmpty())
               {
                  if (port.mInteger || forceint)
                  {
                     str.Printf(wxT("%d"), (int)(upper + 0.5));
                  }
                  else
                  {
                     str = Internat::ToDisplayString(upper);
                  }
               }
               item = new wxStaticText(w, wxID_ANY, str);
               gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 5);
            }
            else
            {
               gridSizer->Add(1, 1, 0);
            }
         }
      }
   }
   
   // Set all of the mSliders based on the value in the
   // text mFields
   inSlider = false; // Now we're ready for HandleText to actually do something.
   HandleText();
   
   w->SetSizer(paramSizer);

   Layout();
   Fit();
   SetSizeHints(GetSize());
}
Esempio n. 4
0
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 void
gst_lv2_filter_base_init (gpointer g_class)
{
    GstLV2FilterClass *klass = (GstLV2FilterClass *) g_class;
    GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
    LilvPlugin *lv2plugin;
    LilvNode *val;
    /* FIXME Handle channels positionning
     * GstAudioChannelPosition position = GST_AUDIO_CHANNEL_POSITION_INVALID; */
    guint j, in_pad_index = 0, out_pad_index = 0;
    gchar *longname, *author;

    lv2plugin = (LilvPlugin *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
                descriptor_quark);

    g_assert (lv2plugin);

    GST_INFO ("base_init %p, plugin %s", g_class,
              lilv_node_get_turtle_token (lilv_plugin_get_uri (lv2plugin)));

    klass->in_group.ports = g_array_new (FALSE, TRUE, sizeof (GstLV2FilterPort));
    klass->out_group.ports = g_array_new (FALSE, TRUE, sizeof (GstLV2FilterPort));
    klass->control_in_ports =
        g_array_new (FALSE, TRUE, sizeof (GstLV2FilterPort));
    klass->control_out_ports =
        g_array_new (FALSE, TRUE, sizeof (GstLV2FilterPort));

    /* find ports and groups */
    for (j = 0; j < lilv_plugin_get_num_ports (lv2plugin); j++) {
        const LilvPort *port = lilv_plugin_get_port_by_index (lv2plugin, j);
        const gboolean is_input = lilv_port_is_a (lv2plugin, port, input_class);
        struct _GstLV2FilterPort desc = { j, 0, };
        LilvNodes *lv2group = lilv_port_get (lv2plugin, port, group_pred);

        if (lv2group) {
            /* port is part of a group */
            const gchar *group_uri = lilv_node_as_uri (lv2group);
            GstLV2FilterGroup *group =
                is_input ? &klass->in_group : &klass->out_group;

            if (group->uri == NULL) {
                group->uri = g_strdup (group_uri);
                group->pad = is_input ? in_pad_index++ : out_pad_index++;
                group->ports = g_array_new (FALSE, TRUE, sizeof (GstLV2FilterPort));
            }

            /* FIXME Handle channels positionning
               position = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
               sub_values = lilv_port_get_value (lv2plugin, port, has_role_pred);
               if (lilv_nodes_size (sub_values) > 0) {
               LilvNode *role = lilv_nodes_get_at (sub_values, 0);
               position = gst_lv2_filter_role_to_position (role);
               }
               lilv_nodes_free (sub_values);

               if (position != GST_AUDIO_CHANNEL_POSITION_INVALID) {
               desc.position = position;
               } */

            g_array_append_val (group->ports, desc);
        } else {
            /* port is not part of a group, or it is part of a group but that group
             * is illegal so we just ignore it */
            if (lilv_port_is_a (lv2plugin, port, audio_class)) {

                desc.pad = is_input ? in_pad_index++ : out_pad_index++;
                if (is_input)
                    g_array_append_val (klass->in_group.ports, desc);
                else
                    g_array_append_val (klass->out_group.ports, desc);
            } else if (lilv_port_is_a (lv2plugin, port, control_class)) {
                if (is_input)
                    g_array_append_val (klass->control_in_ports, desc);
                else
                    g_array_append_val (klass->control_out_ports, desc);
            } else {
                /* unknown port type */
                GST_INFO ("unhandled port %d", j);
                continue;
            }
        }
    }
    gst_lv2_filter_type_class_add_pad_templates (klass);

    val = lilv_plugin_get_name (lv2plugin);
    if (val) {
        longname = g_strdup (lilv_node_as_string (val));
        lilv_node_free (val);
    } else {
        longname = g_strdup ("no description available");
    }
    val = lilv_plugin_get_author_name (lv2plugin);
    if (val) {
        author = g_strdup (lilv_node_as_string (val));
        lilv_node_free (val);
    } else {
        author = g_strdup ("no author available");
    }

    gst_element_class_set_metadata (element_class, longname,
                                    "Filter/Effect/Audio/LV2", longname, author);
    g_free (longname);
    g_free (author);

    klass->plugin = lv2plugin;
}