Exemple #1
0
void Lv2Plugin::init ()
{
  m_activated = false;
  m_features = m_world.features.array();
  m_instance = slv2_plugin_instantiate(
      m_plugin, 
      m_sampleRate,
      m_features->get(Feature::PLUGIN_FEATURE) );
  
  Q_ASSERT(m_instance);

  m_name = slv2_plugin_get_name( m_plugin );
  Q_ASSERT(m_name);

  int count = slv2_plugin_get_num_ports(m_plugin);
  m_ports.resize( count );
  for (int i = 0; i < count; ++i) {
    m_ports[i] = new Lv2Port( m_world, this, i );
  }

  m_authorName     = slv2_plugin_get_author_name( m_plugin );
  m_authorEmail    = slv2_plugin_get_author_email( m_plugin );
  m_authorHomepage = slv2_plugin_get_author_homepage( m_plugin );

  m_features->initialize( *this );
}
Exemple #2
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;
}
Exemple #3
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;
   
}
SLV2Instance
slv2_plugin_instantiate(SLV2Plugin               plugin,
                        double                   sample_rate,
                        const LV2_Feature*const* features)
{
	struct _Instance* result = NULL;

	const LV2_Feature** local_features = NULL;
	if (features == NULL) {
		local_features = malloc(sizeof(LV2_Feature));
		local_features[0] = NULL;
	}

	const char* const lib_uri = slv2_value_as_uri(slv2_plugin_get_library_uri(plugin));
	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 library %s (%s)\n", lib_path, dlerror());
		return NULL;
	}

	LV2_Descriptor_Function df = dlsym(lib, "lv2_descriptor");

	if (!df) {
		fprintf(stderr, "Could not find symbol 'lv2_descriptor', "
				"%s is not a LV2 plugin.\n", lib_path);
		dlclose(lib);
		return NULL;
	} else {
		// Search for plugin by URI

		// FIXME: Kludge to get bundle path (containing directory of binary)
		const char* bundle_path = slv2_uri_to_path(slv2_value_as_uri(
					slv2_plugin_get_bundle_uri(plugin)));

		//printf("Bundle path: %s\n", bundle_path);

		for (uint32_t i=0; 1; ++i) {

			const LV2_Descriptor* ld = df(i);

			if (!ld) {
				fprintf(stderr, "Did not find plugin %s in %s\n",
						slv2_value_as_uri(slv2_plugin_get_uri(plugin)), lib_path);
				dlclose(lib);
				break; // return NULL
			} else if (!strcmp(ld->URI, slv2_value_as_uri(slv2_plugin_get_uri(plugin)))) {

				assert(plugin->plugin_uri);

				//printf("Found %s at index %u in:\n\t%s\n\n",
				//		librdf_uri_as_string(plugin->plugin_uri), i, lib_path);

				assert(ld->instantiate);

				// Create SLV2Instance to return
				result = malloc(sizeof(struct _Instance));
				result->lv2_descriptor = ld;
                result->lv2_handle = ld->instantiate(ld, sample_rate, (char*)bundle_path,
						(features) ? features : local_features);
                struct _InstanceImpl* impl = malloc(sizeof(struct _InstanceImpl));
				impl->lib_handle = lib;
				result->pimpl = impl;

				break;
			}
		}
	}

	if (result) {
		assert(slv2_plugin_get_num_ports(plugin) > 0);

		// Failed to instantiate
		if (result->lv2_handle == NULL) {
			//printf("Failed to instantiate %s\n", plugin->plugin_uri);
			free(result);
			return NULL;
		}

		// "Connect" all ports to NULL (catches bugs)
		for (uint32_t i=0; i < slv2_plugin_get_num_ports(plugin); ++i)
			result->lv2_descriptor->connect_port(result->lv2_handle, i, NULL);
	}

	free(local_features);

	return result;
}