static PluginData * open_plugin (const char * path, const LADSPA_Descriptor * desc)
{
    const char * slash = strrchr (path, G_DIR_SEPARATOR);
    g_return_val_if_fail (slash && slash[1], NULL);
    g_return_val_if_fail (desc->Label && desc->Name, NULL);

    PluginData * plugin = g_slice_new (PluginData);
    plugin->path = g_strdup (slash + 1);
    plugin->desc = desc;
    plugin->controls = index_new ();
    plugin->in_ports = g_array_new (0, 0, sizeof (int));
    plugin->out_ports = g_array_new (0, 0, sizeof (int));
    plugin->selected = 0;

    for (int i = 0; i < desc->PortCount; i ++)
    {
        if (LADSPA_IS_PORT_CONTROL (desc->PortDescriptors[i]))
        {
            ControlData * control = parse_control (desc, i);
            if (control)
                index_append (plugin->controls, control);
        }
        else if (LADSPA_IS_PORT_AUDIO (desc->PortDescriptors[i]) &&
         LADSPA_IS_PORT_INPUT (desc->PortDescriptors[i]))
            g_array_append_val (plugin->in_ports, i);
        else if (LADSPA_IS_PORT_AUDIO (desc->PortDescriptors[i]) &&
         LADSPA_IS_PORT_OUTPUT (desc->PortDescriptors[i]))
            g_array_append_val (plugin->out_ports, i);
    }

    return plugin;
}
// Constructors.
qtractorLadspaPlugin::qtractorLadspaPlugin ( qtractorPluginList *pList,
	qtractorLadspaPluginType *pLadspaType )
	: qtractorPlugin(pList, pLadspaType), m_phInstances(NULL),
		m_piControlOuts(NULL), m_pfControlOuts(NULL),
		m_piAudioIns(NULL), m_piAudioOuts(NULL)
{
#ifdef CONFIG_DEBUG
	qDebug("qtractorLadspaPlugin[%p] filename=\"%s\" index=%lu typeHint=%d",
		this, type()->filename().toUtf8().constData(),
		type()->index(), int(type()->typeHint()));
#endif

	// Get some structural data first...
	const LADSPA_Descriptor *pLadspaDescriptor
		= pLadspaType->ladspa_descriptor();
	if (pLadspaDescriptor) {
		unsigned short iControlOuts = pLadspaType->controlOuts();
		unsigned short iAudioIns    = pLadspaType->audioIns();
		unsigned short iAudioOuts   = pLadspaType->audioOuts();
		if (iAudioIns > 0)
			m_piAudioIns = new unsigned long [iAudioIns];
		if (iAudioOuts > 0)
			m_piAudioOuts = new unsigned long [iAudioOuts];
		if (iControlOuts > 0) {
			m_piControlOuts = new unsigned long [iControlOuts];
			m_pfControlOuts = new float [iControlOuts];
		}
		iControlOuts = iAudioIns = iAudioOuts = 0;
		for (unsigned long i = 0; i < pLadspaDescriptor->PortCount; ++i) {
			const LADSPA_PortDescriptor portType
				= pLadspaDescriptor->PortDescriptors[i];
			if (LADSPA_IS_PORT_INPUT(portType)) {
				if (LADSPA_IS_PORT_AUDIO(portType))
					m_piAudioIns[iAudioIns++] = i;
				else
				if (LADSPA_IS_PORT_CONTROL(portType))
					addParam(new qtractorLadspaPluginParam(this, i));
			}
			else
			if (LADSPA_IS_PORT_OUTPUT(portType)) {
				if (LADSPA_IS_PORT_AUDIO(portType))
					m_piAudioOuts[iAudioOuts++] = i;
				else
				if (LADSPA_IS_PORT_CONTROL(portType)) {
					m_piControlOuts[iControlOuts] = i;
					m_pfControlOuts[iControlOuts] = 0.0f;
					++iControlOuts;
				}
			}
		}
		// FIXME: instantiate each instance properly...
		qtractorLadspaPlugin::setChannels(channels());
	}
}
// Derived methods.
bool qtractorLadspaPluginType::open (void)
{
	// Do we have a descriptor already?
	if (m_pLadspaDescriptor == NULL)
		m_pLadspaDescriptor = ladspa_descriptor(file(), index());
	if (m_pLadspaDescriptor == NULL)
		return false;

#ifdef CONFIG_DEBUG
	qDebug("qtractorLadspaPluginType[%p]::open() filename=\"%s\" index=%lu",
		this, filename().toUtf8().constData(), index());
#endif

	// Retrieve plugin type names.
	m_sName  = m_pLadspaDescriptor->Name;
	m_sLabel = m_pLadspaDescriptor->Label;

	// Retrieve plugin unique identifier.
	m_iUniqueID = m_pLadspaDescriptor->UniqueID;

	// Compute and cache port counts...
	m_iControlIns  = 0;
	m_iControlOuts = 0;
	m_iAudioIns    = 0;
	m_iAudioOuts   = 0;
	m_iMidiIns     = 0;
	m_iMidiOuts    = 0;

	for (unsigned long i = 0; i < m_pLadspaDescriptor->PortCount; ++i) {
		const LADSPA_PortDescriptor portType
			= m_pLadspaDescriptor->PortDescriptors[i];
		if (LADSPA_IS_PORT_INPUT(portType)) {
			if (LADSPA_IS_PORT_AUDIO(portType))
				++m_iAudioIns;
			else
			if (LADSPA_IS_PORT_CONTROL(portType))
				++m_iControlIns;
		}
		else
		if (LADSPA_IS_PORT_OUTPUT(portType)) {
			if (LADSPA_IS_PORT_AUDIO(portType))
				++m_iAudioOuts;
			else
			if (LADSPA_IS_PORT_CONTROL(portType))
				++m_iControlOuts;
		}
	}

	// Cache flags.
	m_bRealtime = LADSPA_IS_HARD_RT_CAPABLE(m_pLadspaDescriptor->Properties);

	// Done.
	return true;
}
Exemple #4
0
static int ladspa_open(void *arg)
{
    struct lp *plu = arg;
    void *dl_handle;
    LADSPA_Descriptor_Function pfDescriptorFunction;
    const LADSPA_Descriptor *psDescriptor;
    int i;
    struct lads *lad = &ladspas[num_ladspas];
    assert(plu->plugin && plu->name);
    dl_handle = loadLADSPAPluginLibrary(plu->plugin);
    if (!dl_handle) {
	error("ladspa: failed to load %s\n", plu->plugin);
	return 0;
    }
    pfDescriptorFunction = (LADSPA_Descriptor_Function)
	dlsym(dl_handle, "ladspa_descriptor");
    if (!pfDescriptorFunction) {
	error("ladspa: %s: %s\n", plu->plugin, dlerror());
	goto out_err;
    }
    for (i = 0;; i++) {
	psDescriptor = pfDescriptorFunction(i);
	if (!psDescriptor)
	    break;
	if (strcmp(plu->name, psDescriptor->Label) == 0)
	    break;
    }
    if (!psDescriptor) {
	error("ladspa: failed to find %s\n", plu->name);
	goto out_err;
    }

    assert(num_ladspas < MAX_LADSPAS);
    for (i = 0; i < psDescriptor->PortCount; i++) {
	if (LADSPA_IS_PORT_INPUT(psDescriptor->PortDescriptors[i]) &&
		LADSPA_IS_PORT_AUDIO(psDescriptor->PortDescriptors[i]))
	    lad->in = i;
	else if (LADSPA_IS_PORT_OUTPUT(psDescriptor->PortDescriptors[i]) &&
		LADSPA_IS_PORT_AUDIO(psDescriptor->PortDescriptors[i]))
	    lad->out = i;
	else if (LADSPA_IS_PORT_CONTROL(psDescriptor->PortDescriptors[i]))
	    lad->ctrl = i;
    }
    lad->descriptor = psDescriptor;
    lad->dl_handle = dl_handle;
    lad->link = arg;
    num_ladspas++;
    return 1;

out_err:
    dlclose(dl_handle);
    return 0;
}
static void
ladspa_count_ports (const LADSPA_Descriptor * descriptor,
    guint * audio_in, guint * audio_out, guint * control_in,
    guint * control_out)
{
  guint i;

  *audio_in = *audio_out = *control_in = *control_out = 0;

  for (i = 0; i < descriptor->PortCount; i++) {
    LADSPA_PortDescriptor p = descriptor->PortDescriptors[i];

    if (LADSPA_IS_PORT_AUDIO (p)) {
      if (LADSPA_IS_PORT_INPUT (p))
        (*audio_in)++;
      else
        (*audio_out)++;
    } else if (LADSPA_IS_PORT_CONTROL (p)) {
      if (LADSPA_IS_PORT_INPUT (p))
        (*control_in)++;
      else
        (*control_out)++;
    }
  }
}
Exemple #6
0
LadspaPluginInfo::LadspaPluginInfo (const QString &path, 
    const LADSPA_Descriptor *desc) :
  PluginInfo(),
  m_path(path),
  m_descriptor(desc)
{
  printf("PATH %s %s\n",qPrintable(path), desc->Name);
  setName(desc->Name);
  setAuthorName(desc->Maker);
  setUniqueId(QString("%1%2").arg( UriRoot ).arg( m_descriptor->UniqueID ));

  int inCnt = 0, outCnt = 0;
  for (unsigned long i=0; i < desc->PortCount; ++i) {
    LADSPA_PortDescriptor p = desc->PortDescriptors[i];
    if (LADSPA_IS_PORT_AUDIO(p)) {
      if (LADSPA_IS_PORT_INPUT(p)) {
        ++inCnt;
      }
      else if (LADSPA_IS_PORT_OUTPUT(p)) {
        ++outCnt;
      }
    }
  }

  setAudioInputCount(inCnt);
  setAudioOutputCount(outCnt);
}
void					WiredLADSPAInstance::LoadPorts()
{
	unsigned long		pos;
	t_ladspa_port		CurrentPort;

	UnLoadPorts();	
	for (pos = 0, CurrentPort.Descriptor = 0, CurrentPort.Id = 0, CurrentPort.RangeHint.LowerBound = 0, 
		 CurrentPort.RangeHint.UpperBound = 0, CurrentPort.RangeHint.HintDescriptor = 0;
		 pos < _Descriptor->PortCount; 
	 	 pos ++, CurrentPort.Descriptor = 0, CurrentPort.Id = 0, CurrentPort.RangeHint.LowerBound = 0, 
		 CurrentPort.RangeHint.UpperBound = 0, CurrentPort.RangeHint.HintDescriptor = 0)
	{
		CurrentPort.Descriptor = _Descriptor->PortDescriptors[pos];
		CurrentPort.RangeHint = _Descriptor->PortRangeHints[pos];
		CurrentPort.Id = pos;
		CurrentPort.Name = wxString(_Descriptor->PortNames[pos], *wxConvCurrent);
		if (LADSPA_IS_PORT_INPUT(CurrentPort.Descriptor))
		{
			if (LADSPA_IS_PORT_CONTROL(CurrentPort.Descriptor))
			{
				_InputDataPluginsPorts.insert(_InputDataPluginsPorts.end(), CurrentPort);
				AddGuiControl(&CurrentPort);
			}
			else if (LADSPA_IS_PORT_AUDIO(CurrentPort.Descriptor))
			{
				_InputAudioPluginsPorts.insert(_InputAudioPluginsPorts.end(), CurrentPort);
				_Type |= TYPE_PLUGINS_EFFECT;
			}
		}
		else if (LADSPA_IS_PORT_OUTPUT(CurrentPort.Descriptor))
		{
			if (LADSPA_IS_PORT_CONTROL(CurrentPort.Descriptor))
			{
				ConnectMonoOutput((float *) new LADSPA_Data, pos);
				_OutputDataPluginsPorts.insert(_OutputDataPluginsPorts.end(), CurrentPort);
			}
			else if (LADSPA_IS_PORT_AUDIO(CurrentPort.Descriptor))
				_OutputAudioPluginsPorts.insert(_OutputAudioPluginsPorts.end(), CurrentPort);
		}
	}
	if (!(_Type & TYPE_PLUGINS_EFFECT))
		_Type |= TYPE_PLUGINS_INSTR;
	//DumpPorts();
}
Exemple #8
0
LadspaEffect::LadspaEffect(const LADSPA_Descriptor *data)
{
   mData = data;
   pluginName = data->Name;

   buffer = NULL;
   fInBuffer = NULL;
   fOutBuffer = NULL;

   inputs = 0;
   outputs = 0;
   numInputControls = 0;

   unsigned long p;

   inputPorts = new unsigned long [mData->PortCount];
   outputPorts = new unsigned long [mData->PortCount];
   inputControls = new float [mData->PortCount];
   outputControls = new float [mData->PortCount];

   for(p=0; p<mData->PortCount; p++) {
      LADSPA_PortDescriptor d = mData->PortDescriptors[p];
      if (LADSPA_IS_PORT_AUDIO(d)) {
         if (LADSPA_IS_PORT_INPUT(d)) {
            inputPorts[inputs] = p;
            inputs++;
         }
         else if (LADSPA_IS_PORT_OUTPUT(d)) {
            outputPorts[outputs] = p;
            outputs++;
         }
      }
      if (LADSPA_IS_PORT_CONTROL(d) &&
          LADSPA_IS_PORT_INPUT(d)) {
         numInputControls++;

         float val = 1.0;
         LADSPA_PortRangeHint hint = mData->PortRangeHints[p];

         if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) &&
             val < hint.LowerBound)
            val = hint.LowerBound;

         if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
             val > hint.UpperBound)
            val = hint.UpperBound;

         if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor))
            val *= 44100;

         inputControls[p] = val;
      }
   }
}
Exemple #9
0
int PluginAClientLAD::get_outchannels()
{
	int result = 0;
	const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
	const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
	int port_count = lad_desc->PortCount;
	for( int i = 0; i < port_count; ++i ) {
		if( !LADSPA_IS_PORT_OUTPUT(port_desc[i]) ) continue;
		if( !LADSPA_IS_PORT_AUDIO(port_desc[i]) ) continue;
		++result;
	}
	return result;
}
unsigned long lp_ladspa_audio_ports::get_lad_input_pos(int pos)
{
	int in_count = 0;
	unsigned long i;
	for(i=0; i<pv_descriptor->PortCount; i++){
		if((LADSPA_IS_PORT_AUDIO(pv_descriptor->PortDescriptors[i]))&&(LADSPA_IS_PORT_INPUT(pv_descriptor->PortDescriptors[i]))){
			if(in_count == pos){
				return i;
			}
			in_count++;
		}
	}
	return -1;
}
Exemple #11
0
void plugin_tilde_ladspa_connect_audio (Pd_Plugin_Tilde* x,
                                        float** audio_inputs,
                                        float** audio_outputs,
                                        unsigned long num_samples)
{
  unsigned port_index = 0;
  unsigned input_count = 0;
  unsigned output_count = 0;

  if(!plugin_tilde_have_plugin(x))return;

  /* Allocate out-of-place memory if needed */
  if (plugin_tilde_ladspa_alloc_outofplace_memory (x, num_samples)) {
    error("plugin~: out of memory");
    return;
  }

  if (x->plugin.ladspa.outofplace_audio_outputs != NULL) {
    x->plugin.ladspa.actual_audio_outputs = audio_outputs;
    audio_outputs = x->plugin.ladspa.outofplace_audio_outputs;
  }

  input_count = 0;
  output_count = 0;
  for (port_index = 0; port_index < x->plugin.ladspa.type->PortCount; port_index++)
    {
      LADSPA_PortDescriptor port_type;
      port_type = x->plugin.ladspa.type->PortDescriptors[port_index];
      if (LADSPA_IS_PORT_AUDIO (port_type))
        {
          if (LADSPA_IS_PORT_INPUT (port_type))
            {
              x->plugin.ladspa.type->connect_port (x->plugin.ladspa.instance,
                                                   port_index,
                                                   (LADSPA_Data*)audio_inputs[input_count]);
              input_count++;
            }
          else if (LADSPA_IS_PORT_OUTPUT (port_type))
            {
              x->plugin.ladspa.type->connect_port (x->plugin.ladspa.instance,
                                                   port_index,
                                                   (LADSPA_Data*)audio_outputs[output_count]);
              output_count++;
            }
        }
    }

  x->plugin.ladspa.num_samples = num_samples;
}
Exemple #12
0
static void plugin_tilde_info (Pd_Plugin_Tilde* x) {

  unsigned port_index = 0;
  t_atom at[5];
  LADSPA_PortDescriptor port_type;
  LADSPA_PortRangeHintDescriptor iHintDescriptor;

  if(!plugin_tilde_have_plugin(x))return;

  for (port_index = 0; port_index < x->plugin.ladspa.type->PortCount; port_index++) {
    port_type = x->plugin.ladspa.type->PortDescriptors[port_index];
    iHintDescriptor = x->plugin.ladspa.type->PortRangeHints[port_index].HintDescriptor;

    t_symbol*xlet=gensym("unknown");
    t_symbol*type=gensym("unknown");
    t_symbol*name=gensym("unknown");

    t_float bound_lo=0.;
    t_float bound_hi=1.;

    if(LADSPA_IS_PORT_INPUT (port_type))
      xlet=gensym("in");
    else if (LADSPA_IS_PORT_OUTPUT (port_type))
      xlet=gensym("out");

    if (LADSPA_IS_PORT_CONTROL (port_type))
      type=gensym("control");
    else if (LADSPA_IS_PORT_AUDIO (port_type))
      type=gensym("audio");

    name=gensym(x->plugin.ladspa.type->PortNames[port_index]);

    if (LADSPA_IS_HINT_BOUNDED_BELOW(iHintDescriptor))
      bound_lo=x->plugin.ladspa.type->PortRangeHints[port_index].LowerBound;
    if (LADSPA_IS_HINT_BOUNDED_ABOVE(iHintDescriptor))
      bound_hi=x->plugin.ladspa.type->PortRangeHints[port_index].UpperBound;

    //    post("port#%d: %s %s %s  %f..%f", port_index, xlet->s_name, type->s_name, name->s_name, bound_lo, bound_hi);

    SETSYMBOL(at+0, xlet);
    SETSYMBOL(at+1, type);
    SETSYMBOL(at+2, name);
    SETFLOAT (at+3, bound_lo);
    SETFLOAT (at+4, bound_hi);

    outlet_anything (x->control_outlet, gensym ("port"), 5, at);
  }
}
Exemple #13
0
void LADSPA_Ctor(LADSPA *unit) {
    LADSPA_Descriptor key, *keyp = &key;
    const LADSPA_Descriptor **found;

    unit->desc = NULL;
    unit->handle = NULL;
    unit->requested_channels = (int) IN0(0);
    if(unit->requested_channels < 1) {
        Print("LADSPA: Must request more than 0 channels\n");
        unit->mDone = true;
        SETCALC(ClearUnitOutputs);
        return;
    }

    key.UniqueID = (unsigned long) IN0(1);
    found = (const LADSPA_Descriptor**) bsearch(&keyp, &plugins[0], plugins_index, sizeof(LADSPA_Descriptor*), desc_cmp);

    if(!found) {
        Print("LADSPA: ERROR, plugin %lu not found!\n",key.UniqueID);
        unit->mDone = true;
        SETCALC(ClearUnitOutputs);
        return;
    } else {
        unit->desc = *found;
    }

    unit->handle = unit->desc->instantiate(unit->desc,SAMPLERATE);

    int in_index = 2, out_index = 0;
    for(unsigned long i = 0; i < unit->desc->PortCount; i++) {
        if(LADSPA_IS_PORT_INPUT(unit->desc->PortDescriptors[i])) {
            unit->desc->connect_port(unit->handle,i,IN(in_index++));
        } else if(LADSPA_IS_PORT_OUTPUT(unit->desc->PortDescriptors[i])) {
            if(out_index<unit->requested_channels && LADSPA_IS_PORT_AUDIO(unit->desc->PortDescriptors[i]))
                unit->desc->connect_port(unit->handle,i,OUT(out_index++));
        }
    }

    unit->plugin_channels = out_index;

//    printf("output channels: ladspa: %d ugen: %d\n",unit->plugin_channels,unit->requested_channels);

    if(unit->desc->activate)
        unit->desc->activate(unit->handle);

    SETCALC(LADSPA_next);
}
unsigned long lp_ladspa_audio_ports::get_lad_output_pos(int pos)
{
	// Set the ports and descriptor
	int out_count = 0;
	unsigned long i;
	for(i=0; i<pv_descriptor->PortCount; i++){
		if((LADSPA_IS_PORT_AUDIO(pv_descriptor->PortDescriptors[i]))&&(LADSPA_IS_PORT_OUTPUT(pv_descriptor->PortDescriptors[i]))){
			if(out_count == pos){
				return i;
			}
			out_count++;
		}
	}


	return -1;
}
Exemple #15
0
static void count_ports(const LADSPA_Descriptor *desc,
                        unsigned long *nb_inputs, unsigned long *nb_outputs)
{
    LADSPA_PortDescriptor pd;
    int i;

    for (i = 0; i < desc->PortCount; i++) {
        pd = desc->PortDescriptors[i];

        if (LADSPA_IS_PORT_AUDIO(pd)) {
            if (LADSPA_IS_PORT_INPUT(pd)) {
                (*nb_inputs)++;
            } else if (LADSPA_IS_PORT_OUTPUT(pd)) {
                (*nb_outputs)++;
            }
        }
    }
}
Exemple #16
0
static void plugin_tilde_ladspa_count_ports (Pd_Plugin_Tilde* x)
{
  unsigned i = 0;

  x->num_audio_inputs = 0;
  x->num_audio_outputs = 0;
  x->num_control_inputs = 0;
  x->num_control_outputs = 0;

  for (i = 0; i < x->plugin.ladspa.type->PortCount; i++)
    {
      LADSPA_PortDescriptor port_type;
      port_type = x->plugin.ladspa.type->PortDescriptors[i];

      if (LADSPA_IS_PORT_AUDIO (port_type))
        {
          if (LADSPA_IS_PORT_INPUT (port_type))
            {
              x->num_audio_inputs++;
            }
          else if (LADSPA_IS_PORT_OUTPUT (port_type))
            {
              x->num_audio_outputs++;
            }
        }
      else if (LADSPA_IS_PORT_CONTROL (port_type))
        {
          if (LADSPA_IS_PORT_INPUT (port_type))
            {
              x->num_control_inputs++;
            }
          else if (LADSPA_IS_PORT_OUTPUT (port_type))
            {
              x->num_control_outputs++;
            }
        }
    }

  verbose(1, "plugin~: plugin ports: audio %d/%d ctrl %d/%d",
       x->num_audio_inputs, x->num_audio_outputs,
       x->num_control_inputs, x->num_control_outputs);
}
Exemple #17
0
bool LadspaManager::isPortAudio( const ladspa_key_t & _plugin,
								uint32_t _port )
{
	if( m_ladspaManagerMap.contains( _plugin ) 
		   && _port < getPortCount( _plugin ) )
	{
		LADSPA_Descriptor_Function descriptorFunction =
			m_ladspaManagerMap[_plugin]->descriptorFunction;
		const LADSPA_Descriptor * descriptor =
				descriptorFunction(
					m_ladspaManagerMap[_plugin]->index );
		
		return( LADSPA_IS_PORT_AUDIO
				( descriptor->PortDescriptors[_port] ) );
	}
	else
	{
		return( false );
	}
}
Exemple #18
0
uint16_t LadspaManager::getPluginOutputs(
		const LADSPA_Descriptor * _descriptor )
{
	uint16_t outputs = 0;
	
	for( uint16_t port = 0; port < _descriptor->PortCount; port++ )
	{
		if( LADSPA_IS_PORT_OUTPUT( 
				_descriptor->PortDescriptors[port] ) &&
			LADSPA_IS_PORT_AUDIO( 
				_descriptor->PortDescriptors[port] ) )
		{
			QString name = QString( 
					_descriptor->PortNames[port] );
			if( name.toUpper().contains( "OUT" ) )
			{
				outputs++;
			}
		}
	}
	return outputs;
}
Exemple #19
0
static gboolean
plugin_is_valid (const LADSPA_Descriptor * descriptor)
{
  unsigned long i;
  unsigned long icount = 0;
  unsigned long ocount = 0;
  
  for (i = 0; i < descriptor->PortCount; i++)
    {
      if (!LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[i]))
        continue;
      
      if (LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[i]))
        icount++;
      else
        ocount++;
    }
  
  if (ocount == 0)
    return FALSE;
  
  return TRUE;
}
Exemple #20
0
static void
plugin_desc_set_port_counts (plugin_desc_t * pd)
{
  unsigned long i;
  unsigned long icount = 0;
  unsigned long ocount = 0;
  
  for (i = 0; i < pd->port_count; i++)
    {
      if (LADSPA_IS_PORT_AUDIO (pd->port_descriptors[i]))
        {
          if (LADSPA_IS_PORT_INPUT (pd->port_descriptors[i]))
            plugin_desc_add_audio_port_index (&pd->audio_input_port_indicies, &icount, i);
          else
            plugin_desc_add_audio_port_index (&pd->audio_output_port_indicies, &ocount, i);
        }
      else
        {
          if (LADSPA_IS_PORT_OUTPUT (pd->port_descriptors[i]))
            continue;
            
          pd->control_port_count++;
          if (pd->control_port_count == 0)
            pd->control_port_indicies = g_malloc (sizeof (unsigned long) * pd->control_port_count);
          else
            pd->control_port_indicies = g_realloc (pd->control_port_indicies,
                                                   sizeof (unsigned long) * pd->control_port_count);
          
          pd->control_port_indicies[pd->control_port_count - 1] = i;
        }
    }
  
  if (icount == ocount)
    pd->channels = icount;
  else if( icount == 0 )
    {
      pd->channels = ocount;
      pd->has_input = FALSE;
    }
  else
    { /* deal with auxilliary ports */
      unsigned long ** port_indicies;
      unsigned long port_count;
      unsigned long i, j;
     
      if (icount > ocount)
        {
          pd->channels = ocount;
          pd->aux_channels = icount - ocount;
          pd->aux_are_input = TRUE;
          port_indicies = &pd->audio_input_port_indicies;
          port_count = icount;
        }
      else
        {
          pd->channels = icount;
          pd->aux_channels = ocount - icount;
          pd->aux_are_input = FALSE;
          port_indicies = &pd->audio_output_port_indicies;
          port_count = ocount;
        }
      
      /* allocate indicies */
      pd->audio_aux_port_indicies = g_malloc (sizeof (unsigned long) * pd->aux_channels);
      
      /* copy indicies */
      for (i = pd->channels, j = 0; i < port_count; i++, j++)
        pd->audio_aux_port_indicies[j] = (*port_indicies)[i];
      
      /* shrink the main indicies to only have channels indicies */
      *port_indicies = g_realloc (*port_indicies, sizeof (unsigned long) * pd->channels);
    }
}
Exemple #21
0
static void dump_info(const LADSPA_Descriptor *ldesc)
{
    int i = 0;

    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Plugin Name: \"%s\"\n", ldesc->Name);
    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Plugin Label: \"%s\"\n", ldesc->Label);
    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Plugin Unique ID: %lu\n", ldesc->UniqueID);
    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Maker: \"%s\"\n", ldesc->Maker);
    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Copyright: \"%s\"\n", ldesc->Copyright);

    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Must Run Real-Time: ");
    if (LADSPA_IS_REALTIME(ldesc->Properties))
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Yes\n");
    else
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "No\n");

    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Has activate() Function: ");
    if (ldesc->activate != NULL)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Yes\n");
    else
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "No\n");
    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Has deactivate() Function: ");
    if (ldesc->deactivate != NULL)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Yes\n");
    else
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "No\n");
    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Has run_adding() Function: ");
    if (ldesc->run_adding != NULL)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Yes\n");
    else
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "No\n");

    if (ldesc->instantiate == NULL)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS NO INSTANTIATE FUNCTION.\n");
    if (ldesc->connect_port == NULL)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS NO CONNECT_PORT FUNCTION.\n");
    if (ldesc->run == NULL)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS NO RUN FUNCTION.\n");
    if (ldesc->run_adding != NULL && ldesc->set_run_adding_gain == NULL)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS RUN_ADDING FUNCTION BUT " "NOT SET_RUN_ADDING_GAIN.\n");
    if (ldesc->run_adding == NULL && ldesc->set_run_adding_gain != NULL)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS SET_RUN_ADDING_GAIN FUNCTION BUT " "NOT RUN_ADDING.\n");
    if (ldesc->cleanup == NULL)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: PLUGIN HAS NO CLEANUP FUNCTION.\n");

    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Environment: ");
    if (LADSPA_IS_HARD_RT_CAPABLE(ldesc->Properties))
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Normal or Hard Real-Time\n");
    else
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Normal\n");

    if (LADSPA_IS_INPLACE_BROKEN(ldesc->Properties))
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "This plugin cannot use in-place processing. " "It will not work with all hosts.\n");

    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Ports:");

    if (ldesc->PortCount == 0)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "\tERROR: PLUGIN HAS NO PORTS.\n");

    for (i = 0; i < ldesc->PortCount; i++) {
        LADSPA_Data dft = 0.0f;
        int found = 0;

        if (LADSPA_IS_PORT_CONTROL(ldesc->PortDescriptors[i])) {
            found = find_default(ldesc, i, &dft);
        }

        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "\n  \"%s\" ", ldesc->PortNames[i]);

        if (LADSPA_IS_PORT_INPUT(ldesc->PortDescriptors[i])
                && LADSPA_IS_PORT_OUTPUT(ldesc->PortDescriptors[i]))
            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: INPUT AND OUTPUT");
        else if (LADSPA_IS_PORT_INPUT(ldesc->PortDescriptors[i]))
            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "input");
        else if (LADSPA_IS_PORT_OUTPUT(ldesc->PortDescriptors[i]))
            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "output");
        else
            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "ERROR: NEITHER INPUT NOR OUTPUT");

        if (LADSPA_IS_PORT_CONTROL(ldesc->PortDescriptors[i])
                && LADSPA_IS_PORT_AUDIO(ldesc->PortDescriptors[i]))
            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, ", ERROR: CONTROL AND AUDIO");
        else if (LADSPA_IS_PORT_CONTROL(ldesc->PortDescriptors[i]))
            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, ", control");
        else if (LADSPA_IS_PORT_AUDIO(ldesc->PortDescriptors[i]))
            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, ", audio");
        else
            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, ", ERROR: NEITHER CONTROL NOR AUDIO");

        if (LADSPA_IS_PORT_CONTROL(ldesc->PortDescriptors[i])) {
            if (found) {
                switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "\n    RANGE: %f-%f DEFAULT: %f\n",
                                  ldesc->PortRangeHints[i].LowerBound, ldesc->PortRangeHints[i].UpperBound, dft);
            } else {
                switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "\n    RANGE: %f-%f DEFAULT: none.\n",
                                  ldesc->PortRangeHints[i].LowerBound, ldesc->PortRangeHints[i].UpperBound);
            }
        }



    }

    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "\n\n");
}
Exemple #22
0
static switch_bool_t ladspa_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
    switch_ladspa_t *pvt = (switch_ladspa_t *) user_data;
    //switch_frame_t *frame = NULL;
    switch_channel_t *channel = switch_core_session_get_channel(pvt->session);

    switch (type) {
    case SWITCH_ABC_TYPE_INIT:
    {
        switch_codec_implementation_t read_impl = { 0 };
        LADSPA_PortDescriptor port_desc;
        int i = 0, j = 0, k = 0, str_idx = 0;

        switch_core_session_get_read_impl(pvt->session, &read_impl);

        if (!(pvt->library_handle = loadLADSPAPluginLibrary(pvt->plugin_name))) {
            return SWITCH_FALSE;
        }

        if (!(pvt->ldesc = findLADSPAPluginDescriptor(pvt->library_handle, pvt->plugin_name, pvt->label_name))) {
            return SWITCH_FALSE;
        }


        pvt->handle = pvt->ldesc->instantiate(pvt->ldesc, read_impl.actual_samples_per_second);

        dump_info(pvt->ldesc);


        for (i = 0; i < pvt->ldesc->PortCount; i++) {
            port_desc = pvt->ldesc->PortDescriptors[i];

            if (LADSPA_IS_PORT_CONTROL(port_desc) && LADSPA_IS_PORT_INPUT(port_desc)) {
                LADSPA_Data dft = 0.0f;
                int found = find_default(pvt->ldesc, i, &dft);

                if (found && !pvt->has_config[j]) {
                    pvt->config[j] = dft;
                    pvt->has_config[j] = 1;
                }

                if (pvt->has_config[j]) {
                    if (!check_range(pvt->ldesc, i, pvt->config[j])) {
                        pvt->config[j] = dft;
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_WARNING, "FALLING TO DEFAULT PARAM %d [%s] (%f)\n",
                                          j+1,
                                          pvt->ldesc->PortNames[i],
                                          pvt->config[j]);
                    }

                    switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "ADDING PARAM %d [%s] (%f)\n",
                                      j+1,
                                      pvt->ldesc->PortNames[i],
                                      pvt->config[j]);
                    pvt->ldesc->connect_port(pvt->handle, i, &pvt->config[j++]);
                    usleep(10000);
                }
            }

            if (LADSPA_IS_PORT_INPUT(port_desc) && LADSPA_IS_PORT_AUDIO(port_desc)) {
                int mapped = 0;

                if (pvt->str_idx && !zstr(pvt->str_config[str_idx])) {

                    if (!strcasecmp(pvt->str_config[str_idx], "none")) {
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "CONNECT NOTHING to port: %s\n",
                                          pvt->ldesc->PortNames[i]
                                         );
                        mapped = 1;
                    } else if (!strncasecmp(pvt->str_config[str_idx], "file:", 5)) {
                        char *file = pvt->str_config[str_idx] + 5;

                        if (switch_test_flag((&pvt->fh), SWITCH_FILE_OPEN)) {
                            switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session),
                                              SWITCH_LOG_ERROR, "CAN'T CONNECT FILE [%s] File already mapped\n", file);
                        } else {
                            if (switch_core_file_open(&pvt->fh,
                                                      file,
                                                      read_impl.number_of_channels,
                                                      read_impl.actual_samples_per_second,
                                                      SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_ERROR, "Cannot open file: %s\n", file);
                                return SWITCH_FALSE;
                            }


                            switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "CONNECT FILE [%s] to port: %s\n",
                                              file,
                                              pvt->ldesc->PortNames[i]
                                             );

                            pvt->ldesc->connect_port(pvt->handle, i, pvt->file_buf);
                            mapped = 1;
                        }
                    }

                    str_idx++;
                }

                if (!mapped) {
                    pvt->ldesc->connect_port(pvt->handle, i, pvt->in_buf);
                    switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "CONNECT CHANNEL AUDIO to port: %s\n",
                                      pvt->ldesc->PortNames[i]
                                     );
                }

            }

            if (LADSPA_IS_PORT_OUTPUT(port_desc)) {
                if (LADSPA_IS_PORT_AUDIO(port_desc)) {
                    pvt->ldesc->connect_port(pvt->handle, i, pvt->out_buf);
                } else if (k < MAX_INDEX) {
                    pvt->ldesc->connect_port(pvt->handle, i, &pvt->out_ports[k++]);
                }
            }
        }
    }

    break;

    case SWITCH_ABC_TYPE_CLOSE:
    {

        if (switch_test_flag((&pvt->fh), SWITCH_FILE_OPEN)) {
            switch_core_file_close(&pvt->fh);
        }

        if (pvt->handle && pvt->ldesc) {
            pvt->ldesc->cleanup(pvt->handle);
        }

        if (pvt->library_handle) {
            unloadLADSPAPluginLibrary(pvt->library_handle);
        }
    }
    break;

    case SWITCH_ABC_TYPE_WRITE_REPLACE:
    case SWITCH_ABC_TYPE_READ_REPLACE:
    {
        switch_frame_t *rframe;
        int16_t *slin, abuf[SWITCH_RECOMMENDED_BUFFER_SIZE] =  { 0 };
        switch_size_t olen = 0;


        if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
            rframe = switch_core_media_bug_get_read_replace_frame(bug);
        } else {
            rframe = switch_core_media_bug_get_write_replace_frame(bug);
        }

        slin = rframe->data;

        if (switch_channel_media_ready(channel)) {
            switch_short_to_float(slin, pvt->in_buf, rframe->samples);

            if (switch_test_flag((&pvt->fh), SWITCH_FILE_OPEN)) {
                olen = rframe->samples;
                if (switch_core_file_read(&pvt->fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
                    switch_codec_implementation_t read_impl = { 0 };
                    char *file = switch_core_session_strdup(pvt->session, pvt->fh.file_path);
                    switch_core_session_get_read_impl(pvt->session, &read_impl);

                    switch_core_file_close(&pvt->fh);

                    if (switch_core_file_open(&pvt->fh,
                                              file,
                                              read_impl.number_of_channels,
                                              read_impl.actual_samples_per_second,
                                              SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_ERROR, "Cannot open file: %s\n", file);
                        return SWITCH_FALSE;
                    }

                    olen = rframe->samples;
                    if (switch_core_file_read(&pvt->fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_ERROR, "Cannot READ file: %s\n", file);
                        return SWITCH_FALSE;
                    }
                }

                switch_short_to_float(abuf, pvt->file_buf, olen);
            }

            pvt->ldesc->run(pvt->handle, rframe->samples);

            switch_float_to_short(pvt->out_buf, slin, rframe->samples);
        }

        if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
            switch_core_media_bug_set_read_replace_frame(bug, rframe);
        } else {
            switch_core_media_bug_set_write_replace_frame(bug, rframe);
        }

        if (pvt->skip && !--pvt->skip) {
            return SWITCH_FALSE;
        }

    }
    break;
    case SWITCH_ABC_TYPE_WRITE:
    default:
        break;
    }

    return SWITCH_TRUE;
}
Exemple #23
0
static void
gst_ladspa_base_init (gpointer g_class)
{
  GstLADSPAClass *klass = (GstLADSPAClass *) g_class;
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
  GstSignalProcessorClass *gsp_class = GST_SIGNAL_PROCESSOR_CLASS (g_class);
  LADSPA_Descriptor *desc;
  guint j, audio_in_count, audio_out_count, control_in_count, control_out_count;
  const gchar *klass_tags;
  gchar *longname, *author;
#ifdef HAVE_LRDF
  gchar *uri;
#endif
  gchar *extra_klass_tags = NULL;

  GST_DEBUG ("base_init %p", g_class);

  desc = (LADSPA_Descriptor *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
      descriptor_quark);
  g_assert (desc);
  klass->descriptor = desc;

  /* 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 < desc->PortCount; j++) {
    LADSPA_PortDescriptor p = desc->PortDescriptors[j];

    if (LADSPA_IS_PORT_AUDIO (p)) {
      gchar *name = g_strdup ((gchar *) desc->PortNames[j]);

      /* FIXME: group stereo pairs into a stereo pad
       * ladspa-fx have "XXX (Left)" and "XXX (Right)"
       * where XXX={In,Input,Out,Output}
       */

      GST_DEBUG ("LADSPA port name: \"%s\"", name);
      /* replaces all spaces with underscores, and then remaining special chars
       * with '-'
       * FIXME: why, pads can have any name
       */
      g_strdelimit (name, " ", '_');
      g_strcanon (name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "_-><=", '-');
      GST_DEBUG ("GStreamer pad name: \"%s\"", name);

      if (LADSPA_IS_PORT_INPUT (p))
        gst_signal_processor_class_add_pad_template (gsp_class, name,
            GST_PAD_SINK, gsp_class->num_audio_in++, 1);
      else
        gst_signal_processor_class_add_pad_template (gsp_class, name,
            GST_PAD_SRC, gsp_class->num_audio_out++, 1);

      g_free (name);
    } else if (LADSPA_IS_PORT_CONTROL (p)) {
      if (LADSPA_IS_PORT_INPUT (p))
        gsp_class->num_control_in++;
      else
        gsp_class->num_control_out++;
    }
  }

  longname = g_locale_to_utf8 (desc->Name, -1, NULL, NULL, NULL);
  if (!longname)
    longname = g_strdup ("no description available");
  author = g_locale_to_utf8 (desc->Maker, -1, NULL, NULL, NULL);
  if (!author)
    author = g_strdup ("no author available");

#ifdef HAVE_LRDF
  /* libldrf support, we want to get extra class information here */
  uri = g_strdup_printf (LADSPA_BASE "%ld", desc->UniqueID);
  if (uri) {
    lrdf_statement query = { 0, };
    lrdf_uris *uris;
    gchar *str, *base_type = NULL;

    GST_DEBUG ("uri (id=%d) : %s", desc->UniqueID, uri);
    /* we can take this directly from 'desc', keep this example for future
       attributes. 
       if ((str = lrdf_get_setting_metadata (uri, "title"))) {
       GST_DEBUG ("title : %s", str);
       }
       if ((str = lrdf_get_setting_metadata (uri, "creator"))) {
       GST_DEBUG ("creator : %s", str);
       }
     */

    /* get the rdf:type for this plugin */
    query.subject = uri;
    query.predicate = (char *) RDF_BASE "type";
    query.object = (char *) "?";
    query.next = NULL;
    uris = lrdf_match_multi (&query);
    if (uris) {
      if (uris->count == 1) {
        base_type = g_strdup (uris->items[0]);
        GST_DEBUG ("base_type :  %s", base_type);
      }
      lrdf_free_uris (uris);
    }

    /* query taxonomy */
    if (base_type) {
      uris = lrdf_get_all_superclasses (base_type);
      if (uris) {
        guint32 j;

        for (j = 0; j < uris->count; j++) {
          GST_LOG ("parent_type_uri : %s", uris->items[j]);
          if ((str = lrdf_get_label (uris->items[j]))) {
            GST_DEBUG ("parent_type_label : %s", str);
            if (extra_klass_tags) {
              gchar *old_tags = extra_klass_tags;
              extra_klass_tags = g_strconcat (extra_klass_tags, "/", str, NULL);
              g_free (old_tags);
            } else {
              extra_klass_tags = g_strconcat ("/", str, NULL);
            }
          }
        }
        lrdf_free_uris (uris);
      }
      g_free (base_type);
    }

    /* we can use this for the presets
       uris = lrdf_get_setting_uris (desc->UniqueID);
       if (uris) {
       guint32 j;

       for (j = 0; j < uris->count; j++) {
       GST_INFO ("setting_uri : %s", uris->items[j]);
       if ((str = lrdf_get_label (uris->items[j]))) {
       GST_INFO ("setting_label : %s", str);
       }
       }
       lrdf_free_uris (uris);
       }
     */

  }
  g_free (uri);
#endif

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

#ifdef HAVE_LRDF
  if (extra_klass_tags) {
    char *s = g_strconcat (klass_tags, extra_klass_tags, NULL);
    g_free (extra_klass_tags);
    extra_klass_tags = s;
  }
#endif
  GST_INFO ("tags : %s", klass_tags);
  gst_element_class_set_metadata (element_class, longname,
      extra_klass_tags ? extra_klass_tags : klass_tags, longname, author);
  g_free (longname);
  g_free (author);
  g_free (extra_klass_tags);

  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 < desc->PortCount; j++) {
    LADSPA_PortDescriptor p = desc->PortDescriptors[j];

    if (LADSPA_IS_PORT_AUDIO (p)) {
      if (LADSPA_IS_PORT_INPUT (p))
        klass->audio_in_portnums[audio_in_count++] = j;
      else
        klass->audio_out_portnums[audio_out_count++] = j;
    } else if (LADSPA_IS_PORT_CONTROL (p)) {
      if (LADSPA_IS_PORT_INPUT (p))
        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 (!LADSPA_IS_INPLACE_BROKEN (desc->Properties))
    GST_SIGNAL_PROCESSOR_CLASS_SET_CAN_PROCESS_IN_PLACE (klass);

  klass->descriptor = desc;
}
Exemple #24
0
static av_cold int init(AVFilterContext *ctx)
{
    LADSPAContext *s = ctx->priv;
    LADSPA_Descriptor_Function descriptor_fn;
    const LADSPA_Descriptor *desc;
    LADSPA_PortDescriptor pd;
    AVFilterPad pad = { NULL };
    char *p, *arg, *saveptr = NULL;
    unsigned long nb_ports;
    int i;

    if (!s->dl_name) {
        av_log(ctx, AV_LOG_ERROR, "No plugin name provided\n");
        return AVERROR(EINVAL);
    }

    if (s->dl_name[0] == '/' || s->dl_name[0] == '.') {
        // argument is a path
        s->dl_handle = dlopen(s->dl_name, RTLD_LOCAL|RTLD_NOW);
    } else {
        // argument is a shared object name
        char *paths = av_strdup(getenv("LADSPA_PATH"));
        const char *separator = ":";

        if (paths) {
            p = paths;
            while ((arg = av_strtok(p, separator, &saveptr)) && !s->dl_handle) {
                s->dl_handle = try_load(arg, s->dl_name);
                p = NULL;
            }
        }

        av_free(paths);
        if (!s->dl_handle && (paths = av_asprintf("%s/.ladspa/lib", getenv("HOME")))) {
            s->dl_handle = try_load(paths, s->dl_name);
            av_free(paths);
        }

        if (!s->dl_handle)
            s->dl_handle = try_load("/usr/local/lib/ladspa", s->dl_name);

        if (!s->dl_handle)
            s->dl_handle = try_load("/usr/lib/ladspa", s->dl_name);
    }
    if (!s->dl_handle) {
        av_log(ctx, AV_LOG_ERROR, "Failed to load '%s'\n", s->dl_name);
        return AVERROR(EINVAL);
    }

    descriptor_fn = dlsym(s->dl_handle, "ladspa_descriptor");
    if (!descriptor_fn) {
        av_log(ctx, AV_LOG_ERROR, "Could not find ladspa_descriptor: %s\n", dlerror());
        return AVERROR(EINVAL);
    }

    // Find the requested plugin, or list plugins
    if (!s->plugin) {
        av_log(ctx, AV_LOG_INFO, "The '%s' library contains the following plugins:\n", s->dl_name);
        av_log(ctx, AV_LOG_INFO, "I = Input Channels\n");
        av_log(ctx, AV_LOG_INFO, "O = Output Channels\n");
        av_log(ctx, AV_LOG_INFO, "I:O %-25s %s\n", "Plugin", "Description");
        av_log(ctx, AV_LOG_INFO, "\n");
        for (i = 0; desc = descriptor_fn(i); i++) {
            unsigned long inputs = 0, outputs = 0;

            count_ports(desc, &inputs, &outputs);
            av_log(ctx, AV_LOG_INFO, "%lu:%lu %-25s %s\n", inputs, outputs, desc->Label,
                                     av_x_if_null(desc->Name, "?"));
            av_log(ctx, AV_LOG_VERBOSE, "Maker: %s\n", av_x_if_null(desc->Maker, "?"));
            av_log(ctx, AV_LOG_VERBOSE, "Copyright: %s\n", av_x_if_null(desc->Copyright, "?"));
        }
        return AVERROR_EXIT;
    } else {
        for (i = 0;; i++) {
            desc = descriptor_fn(i);
            if (!desc) {
                av_log(ctx, AV_LOG_ERROR, "Could not find plugin: %s\n", s->plugin);
                return AVERROR(EINVAL);
            }

            if (desc->Label && !strcmp(desc->Label, s->plugin))
                break;
        }
    }

    s->desc  = desc;
    nb_ports = desc->PortCount;

    s->ipmap = av_calloc(nb_ports, sizeof(*s->ipmap));
    s->opmap = av_calloc(nb_ports, sizeof(*s->opmap));
    s->icmap = av_calloc(nb_ports, sizeof(*s->icmap));
    s->ocmap = av_calloc(nb_ports, sizeof(*s->ocmap));
    s->ictlv = av_calloc(nb_ports, sizeof(*s->ictlv));
    s->octlv = av_calloc(nb_ports, sizeof(*s->octlv));
    s->ctl_needs_value = av_calloc(nb_ports, sizeof(*s->ctl_needs_value));
    if (!s->ipmap || !s->opmap || !s->icmap ||
        !s->ocmap || !s->ictlv || !s->octlv || !s->ctl_needs_value)
        return AVERROR(ENOMEM);

    for (i = 0; i < nb_ports; i++) {
        pd = desc->PortDescriptors[i];

        if (LADSPA_IS_PORT_AUDIO(pd)) {
            if (LADSPA_IS_PORT_INPUT(pd)) {
                s->ipmap[s->nb_inputs] = i;
                s->nb_inputs++;
            } else if (LADSPA_IS_PORT_OUTPUT(pd)) {
                s->opmap[s->nb_outputs] = i;
                s->nb_outputs++;
            }
        } else if (LADSPA_IS_PORT_CONTROL(pd)) {
            if (LADSPA_IS_PORT_INPUT(pd)) {
                s->icmap[s->nb_inputcontrols] = i;

                if (LADSPA_IS_HINT_HAS_DEFAULT(desc->PortRangeHints[i].HintDescriptor))
                    set_default_ctl_value(s, s->nb_inputcontrols, s->icmap, s->ictlv);
                else
                    s->ctl_needs_value[s->nb_inputcontrols] = 1;

                s->nb_inputcontrols++;
            } else if (LADSPA_IS_PORT_OUTPUT(pd)) {
                s->ocmap[s->nb_outputcontrols] = i;
                s->nb_outputcontrols++;
            }
        }
    }

    // List Control Ports if "help" is specified
    if (s->options && !strcmp(s->options, "help")) {
        if (!s->nb_inputcontrols) {
            av_log(ctx, AV_LOG_INFO,
                   "The '%s' plugin does not have any input controls.\n",
                   desc->Label);
        } else {
            av_log(ctx, AV_LOG_INFO,
                   "The '%s' plugin has the following input controls:\n",
                   desc->Label);
            for (i = 0; i < s->nb_inputcontrols; i++)
                print_ctl_info(ctx, AV_LOG_INFO, s, i, s->icmap, s->ictlv, 0);
        }
        return AVERROR_EXIT;
    }

    // Parse control parameters
    p = s->options;
    while (s->options) {
        LADSPA_Data val;
        int ret;

        if (!(arg = av_strtok(p, "|", &saveptr)))
            break;
        p = NULL;

        if (sscanf(arg, "c%d=%f", &i, &val) != 2) {
            av_log(ctx, AV_LOG_ERROR, "Invalid syntax.\n");
            return AVERROR(EINVAL);
        }

        if ((ret = set_control(ctx, i, val)) < 0)
            return ret;
        s->ctl_needs_value[i] = 0;
    }

    // Check if any controls are not set
    for (i = 0; i < s->nb_inputcontrols; i++) {
        if (s->ctl_needs_value[i]) {
            av_log(ctx, AV_LOG_ERROR, "Control c%d must be set.\n", i);
            print_ctl_info(ctx, AV_LOG_ERROR, s, i, s->icmap, s->ictlv, 0);
            return AVERROR(EINVAL);
        }
    }

    pad.type = AVMEDIA_TYPE_AUDIO;

    if (s->nb_inputs) {
        pad.name = av_asprintf("in0:%s%lu", desc->Label, s->nb_inputs);
        if (!pad.name)
            return AVERROR(ENOMEM);

        pad.filter_frame = filter_frame;
        pad.config_props = config_input;
        if (ff_insert_inpad(ctx, ctx->nb_inputs, &pad) < 0) {
            av_freep(&pad.name);
            return AVERROR(ENOMEM);
        }
    }

    av_log(ctx, AV_LOG_DEBUG, "ports: %lu\n", nb_ports);
    av_log(ctx, AV_LOG_DEBUG, "inputs: %lu outputs: %lu\n",
                              s->nb_inputs, s->nb_outputs);
    av_log(ctx, AV_LOG_DEBUG, "input controls: %lu output controls: %lu\n",
                              s->nb_inputcontrols, s->nb_outputcontrols);

    return 0;
}
Exemple #25
0
LadspaEffect::LadspaEffect(const LADSPA_Descriptor *data,
                           const std::set<wxString>& categories)
    : mCategories(categories) {

    mData = data;
    pluginName = LAT1CTOWX(mData->Name);

    fInBuffer = NULL;
    fOutBuffer = NULL;

    inputs = 0;
    outputs = 0;
    numInputControls = 0;
    mLength = 0;

    unsigned long p;

    inputPorts = new unsigned long [mData->PortCount];
    outputPorts = new unsigned long [mData->PortCount];
    inputControls = new float [mData->PortCount];
    outputControls = new float [mData->PortCount];

    for(p=0; p<mData->PortCount; p++) {
        LADSPA_PortDescriptor d = mData->PortDescriptors[p];
        if (LADSPA_IS_PORT_AUDIO(d)) {
            if (LADSPA_IS_PORT_INPUT(d)) {
                inputPorts[inputs] = p;
                inputs++;
            }
            else if (LADSPA_IS_PORT_OUTPUT(d)) {
                outputPorts[outputs] = p;
                outputs++;
            }
        }
        if (LADSPA_IS_PORT_CONTROL(d) &&
                LADSPA_IS_PORT_INPUT(d)) {
            numInputControls++;

            float val = float(1.0);
            LADSPA_PortRangeHint hint = mData->PortRangeHints[p];

            if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) &&
                    val < hint.LowerBound)
                val = hint.LowerBound;

            if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
                    val > hint.UpperBound)
                val = hint.UpperBound;

            if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hint.HintDescriptor))
                val = hint.LowerBound;

            if (LADSPA_IS_HINT_DEFAULT_LOW(hint.HintDescriptor))
                val = hint.LowerBound * 0.75f + hint.UpperBound * 0.25f;

            if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint.HintDescriptor))
                val = hint.LowerBound * 0.5f + hint.UpperBound * 0.5f;

            if (LADSPA_IS_HINT_DEFAULT_HIGH(hint.HintDescriptor))
                val = hint.LowerBound * 0.25f + hint.UpperBound * 0.75f;

            if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint.HintDescriptor))
                val = hint.UpperBound;

            if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor))
                val *= mProjectRate;

            if (LADSPA_IS_HINT_DEFAULT_0(hint.HintDescriptor))
                val = 0.0f;

            if (LADSPA_IS_HINT_DEFAULT_1(hint.HintDescriptor))
                val = 1.0f;

            if (LADSPA_IS_HINT_DEFAULT_100(hint.HintDescriptor))
                val = 100.0f;

            if (LADSPA_IS_HINT_DEFAULT_440(hint.HintDescriptor))
                val = 440.0f;

            inputControls[p] = val;
        }
    }

    flags = PLUGIN_EFFECT;
    if (inputs == 0)
        flags |= INSERT_EFFECT;
    else if (outputs == 0)
        flags |= ANALYZE_EFFECT;
    else
        flags |= PROCESS_EFFECT;
}
Exemple #26
0
static int af_ladspa_parse_plugin(af_ladspa_t *setup) {
    int p, i;
    const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
    LADSPA_PortDescriptor d;
    LADSPA_PortRangeHint hint;

    if (!setup->libhandle)
        return AF_ERROR; /* only call parse after a succesful load */
    if (!setup->plugin_descriptor)
        return AF_ERROR; /* same as above */

    /* let's do it */

    setup->nports = pdes->PortCount;

    /* allocate memory for all inputs/outputs/controls */

    setup->inputs = calloc(setup->nports, sizeof(int));
    if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname);

    setup->outputs = calloc(setup->nports, sizeof(int));
    if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname);

    setup->inputcontrolsmap = calloc(setup->nports, sizeof(int));
    if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);

    setup->inputcontrols = calloc(setup->nports, sizeof(float));
    if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname);

    setup->outputcontrolsmap = calloc(setup->nports, sizeof(int));
    if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);

    setup->outputcontrols = calloc(setup->nports, sizeof(float));
    if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname);

    /* set counts to zero */

    setup->ninputs = 0;
    setup->noutputs = 0;
    setup->ninputcontrols = 0;
    setup->noutputcontrols = 0;

    /* check all ports, see what type it is and set variables according to
     * what we have found
     */

    for (p=0; p<setup->nports; p++) {
        d = pdes->PortDescriptors[p];

        if (LADSPA_IS_PORT_AUDIO(d)) {
            if (LADSPA_IS_PORT_INPUT(d)) {
                setup->inputs[setup->ninputs] = p;
                setup->ninputs++;
            } else if (LADSPA_IS_PORT_OUTPUT(d)) {
                setup->outputs[setup->noutputs] = p;
                setup->noutputs++;
            }
        }

        if (LADSPA_IS_PORT_CONTROL(d)) {
            if (LADSPA_IS_PORT_INPUT(d)) {
                setup->inputcontrolsmap[setup->ninputcontrols] = p;
                setup->ninputcontrols++;
                /* set control to zero. set values after reading the rest
                 * of the suboptions and check LADSPA_?_HINT's later.
                 */
                setup->inputcontrols[p] = 0.0f;
            } else if (LADSPA_IS_PORT_OUTPUT(d)) {
                /* read and handle these too, otherwise filters that have them
                 * will sig11
                 */
                setup->outputcontrolsmap[setup->noutputcontrols]=p;
                setup->noutputcontrols++;
                setup->outputcontrols[p] = 0.0f;
            }
        }

    }

    if (setup->ninputs == 0) {
        mp_msg(MSGT_AFILTER, MSGL_WARN, "%s: %s\n", setup->myname,
                                                MSGTR_AF_LADSPA_WarnNoInputs);
    } else if (setup->ninputs == 1) {
        mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a mono effect\n", setup->myname);
    } else if (setup->ninputs == 2) {
        mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a stereo effect\n", setup->myname);
    } else {
        mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a %i-channel effect, "
               "support is experimental\n", setup->myname, setup->ninputs);
    }

    if (setup->noutputs == 0) {
        mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
                                                MSGTR_AF_LADSPA_ErrNoOutputs);
        return AF_ERROR;
    }

    if (setup->noutputs != setup->ninputs ) {
        mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
                                                MSGTR_AF_LADSPA_ErrInOutDiff);
        return AF_ERROR;
    }

    mp_msg(MSGT_AFILTER, MSGL_V, "%s: this plugin has %d input control(s)\n",
                                        setup->myname, setup->ninputcontrols);

    /* Print list of controls and its range of values it accepts */

    for (i=0; i<setup->ninputcontrols; i++) {
        p = setup->inputcontrolsmap[i];
        hint = pdes->PortRangeHints[p];
        mp_msg(MSGT_AFILTER, MSGL_V, "  --- %d %s [", i, pdes->PortNames[p]);

        if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
            mp_msg(MSGT_AFILTER, MSGL_V, "%0.2f , ", hint.LowerBound);
        } else {
            mp_msg(MSGT_AFILTER, MSGL_V, "... , ");
        }

        if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
            mp_msg(MSGT_AFILTER, MSGL_V, "%0.2f]\n", hint.UpperBound);
        } else {
            mp_msg(MSGT_AFILTER, MSGL_V, "...]\n");
        }

    }

    return AF_OK;
}
/* Note that this procedure leaks memory like mad. */
static void
applyPlugin(const char               * pcInputFilename,
	    const char               * pcOutputFilename,
	    const LADSPA_Data          fExtraSeconds,
	    const unsigned long        lPluginCount,
	    const LADSPA_Descriptor ** ppsPluginDescriptors,
	    LADSPA_Data             ** ppfPluginControlValues) {

  LADSPA_PortDescriptor iPortDescriptor;
  LADSPA_Handle * ppsPlugins;
  LADSPA_Data ** ppfBuffers;
  long lFrameSize;
  unsigned long lAudioInputCount;
  unsigned long lAudioOutputCount;
  unsigned long lPreviousAudioOutputCount;
  unsigned long lBufferCount;
  unsigned long lBufferIndex;
  unsigned long lControlIndex;
  unsigned long lInputFileChannelCount;
  unsigned long lInputFileLength;
  unsigned long lOutputFileChannelCount;
  unsigned long lOutputFileLength;
  unsigned long lPluginIndex;
  unsigned long lPortIndex;
  unsigned long lSampleRate;
  unsigned long lTimeAt;
  LADSPA_Data fDummyControlOutput;

  /* Open input file and output file: 
     -------------------------------- */

  lOutputFileChannelCount
    = getPortCountByType(ppsPluginDescriptors[lPluginCount - 1],
			 LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT);
  if (lOutputFileChannelCount == 0) {
    fprintf(stderr,
	    "The last plugin in the chain has no audio outputs.\n");
    exit(1);
  }

  openWaveFile(pcInputFilename, 
	       &lInputFileChannelCount, 
	       &lSampleRate,
	       &lInputFileLength);
  if (lInputFileChannelCount
      != getPortCountByType(ppsPluginDescriptors[0],
			    LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT)) {
    fprintf(stderr,
	    "Mismatch between channel count in input file and audio inputs "
	    "on first plugin in chain.\n");
    exit(1);
  }

  lOutputFileLength 
    = lInputFileLength + (unsigned long)(fExtraSeconds * lSampleRate);

  createWaveFile(pcOutputFilename,
		 lOutputFileChannelCount,
		 lSampleRate,
		 lOutputFileLength);

  /* Count buffers and sanity-check the flow graph:
     ---------------------------------------------- */

  lBufferCount = 0;
  lPreviousAudioOutputCount = 0;
  for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) {

    lAudioInputCount
      = getPortCountByType(ppsPluginDescriptors[lPluginIndex],
			   LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT);
    lAudioOutputCount
      = getPortCountByType(ppsPluginDescriptors[lPluginIndex],
			   LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT);

    if (lBufferCount < lAudioInputCount)
      lBufferCount = lAudioInputCount;

    if (lPluginIndex > 0) 
      if (lAudioInputCount != lPreviousAudioOutputCount) {
	fprintf(stderr,
		"There is a mismatch between the number of output channels "
		"on plugin \"%s\" (%ld) and the number of input channels on "
		"plugin \"%s\" (%ld).\n",
		ppsPluginDescriptors[lPluginIndex - 1]->Name,
		lPreviousAudioOutputCount,
		ppsPluginDescriptors[lPluginIndex]->Name,
		lAudioInputCount);
	exit(1);
      }

    lPreviousAudioOutputCount = lAudioOutputCount;

    if (lBufferCount < lAudioOutputCount)
      lBufferCount = lAudioOutputCount;
  }

  /* Create the buffers, create instances, wire them up:
     --------------------------------------------------- */

  ppsPlugins = (LADSPA_Handle *)calloc(lPluginCount, sizeof(LADSPA_Handle));
  ppfBuffers = (LADSPA_Data **)calloc(lBufferCount, sizeof(LADSPA_Data *));
  for (lBufferIndex = 0; lBufferIndex < lBufferCount; lBufferIndex++)
    ppfBuffers[lBufferIndex] 
      = (LADSPA_Data *)calloc(BUFFER_SIZE, sizeof(LADSPA_Data));

  for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) {

    ppsPlugins[lPluginIndex]
      = ppsPluginDescriptors[lPluginIndex]
      ->instantiate(ppsPluginDescriptors[lPluginIndex],
		    lSampleRate);
    if (!ppsPlugins[lPluginIndex]) {
      fprintf(stderr,
	      "Failed to instantiate plugin of type \"%s\".\n",
	      ppsPluginDescriptors[lPluginIndex]->Name);
      exit(1);
    }

    /* Controls:
       --------- */

    lControlIndex = 0;
    for (lPortIndex = 0;
	 lPortIndex < ppsPluginDescriptors[lPluginIndex]->PortCount; 
	 lPortIndex++) {

      iPortDescriptor 
	= ppsPluginDescriptors[lPluginIndex]->PortDescriptors[lPortIndex];
      
      if (LADSPA_IS_PORT_CONTROL(iPortDescriptor)) {
	if (LADSPA_IS_PORT_INPUT(iPortDescriptor))
	  ppsPluginDescriptors[lPluginIndex]->connect_port
	    (ppsPlugins[lPluginIndex],
	     lPortIndex,
	     ppfPluginControlValues[lPluginIndex] + (lControlIndex++));
	if (LADSPA_IS_PORT_OUTPUT(iPortDescriptor))
	  ppsPluginDescriptors[lPluginIndex]->connect_port
	    (ppsPlugins[lPluginIndex],
	     lPortIndex,
	     &fDummyControlOutput);
      }
    }

    /* Input Buffers:
       -------------- */

    lBufferIndex = 0;
    for (lPortIndex = 0;
	 lPortIndex < ppsPluginDescriptors[lPluginIndex]->PortCount; 
	 lPortIndex++) {
      iPortDescriptor 
	= ppsPluginDescriptors[lPluginIndex]->PortDescriptors[lPortIndex];
      if (LADSPA_IS_PORT_INPUT(iPortDescriptor) 
	  && LADSPA_IS_PORT_AUDIO(iPortDescriptor))
	ppsPluginDescriptors[lPluginIndex]->connect_port
	  (ppsPlugins[lPluginIndex],
	   lPortIndex,
	   ppfBuffers[lBufferIndex++]);
    }
    

    /* Output Buffers:
       --------------- */

    lBufferIndex = 0;
    for (lPortIndex = 0;
	 lPortIndex < ppsPluginDescriptors[lPluginIndex]->PortCount; 
	 lPortIndex++) {
      iPortDescriptor 
	= ppsPluginDescriptors[lPluginIndex]->PortDescriptors[lPortIndex];
      if (LADSPA_IS_PORT_OUTPUT(iPortDescriptor) 
	  && LADSPA_IS_PORT_AUDIO(iPortDescriptor))
	ppsPluginDescriptors[lPluginIndex]->connect_port
	  (ppsPlugins[lPluginIndex],
	   lPortIndex,
	   ppfBuffers[lBufferIndex++]);
    }
  }

  /* Activate:
     --------- */

  for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) 
    if (ppsPluginDescriptors[lPluginIndex]->activate != NULL)
      ppsPluginDescriptors[lPluginIndex]->activate(ppsPlugins[lPluginIndex]);

  /* Run:
     ---- */

  lTimeAt = 0;
  while (lTimeAt < lOutputFileLength) {

    lFrameSize = lInputFileLength - lTimeAt;
    if (lFrameSize > BUFFER_SIZE)
      lFrameSize = BUFFER_SIZE;
    else {
      /* We've reached or are reaching the end of the file. We're not
         going to fill the buffer from file. Could just memset the end
         part, but there's only one frame where this is worth the
         effort. */
      for (lBufferIndex = 0; lBufferIndex < lBufferCount; lBufferIndex++)
	memset(ppfBuffers[lBufferIndex], 0, sizeof(LADSPA_Data) * BUFFER_SIZE);
    }

    if (lFrameSize > 0) {
      /* Read from disk. */
      readIntoBuffers(ppfBuffers, lFrameSize);
    }

    /* Run the plugins: */
    lFrameSize = lOutputFileLength - lTimeAt;
    if (lFrameSize > BUFFER_SIZE)
      lFrameSize = BUFFER_SIZE;

    for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) 
      ppsPluginDescriptors[lPluginIndex]
	->run(ppsPlugins[lPluginIndex],
	      lFrameSize);
    
    /* Write the output to disk. */
    writeFromBuffers(ppfBuffers, lFrameSize);

    lTimeAt += lFrameSize;
  }

  /* Deactivate:
     ----------- */

  for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) 
    if (ppsPluginDescriptors[lPluginIndex]->deactivate != NULL)
      ppsPluginDescriptors[lPluginIndex]->deactivate(ppsPlugins[lPluginIndex]);

  /* Cleanup:
     -------- */

  for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) 
    ppsPluginDescriptors[lPluginIndex]->cleanup(ppsPlugins[lPluginIndex]);

  /* Close the input and output files:
     --------------------------------- */

  closeFiles();

}
int pa__init(pa_module*m) {
    struct userdata *u;
    pa_sample_spec ss;
    pa_channel_map map;
    pa_modargs *ma;
    char *t;
    pa_sink *master;
    pa_sink_input_new_data sink_input_data;
    pa_sink_new_data sink_data;
    const char *plugin, *label, *input_ladspaport_map, *output_ladspaport_map;
    LADSPA_Descriptor_Function descriptor_func;
    unsigned long input_ladspaport[PA_CHANNELS_MAX], output_ladspaport[PA_CHANNELS_MAX];
    const char *e, *cdata;
    const LADSPA_Descriptor *d;
    unsigned long p, h, j, n_control, c;
    pa_bool_t *use_default = NULL;

    pa_assert(m);

    pa_assert_cc(sizeof(LADSPA_Data) == sizeof(float));

    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
        pa_log("Failed to parse module arguments.");
        goto fail;
    }

    if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK))) {
        pa_log("Master sink not found");
        goto fail;
    }

    ss = master->sample_spec;
    ss.format = PA_SAMPLE_FLOAT32;
    map = master->channel_map;
    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
        pa_log("Invalid sample format specification or channel map");
        goto fail;
    }

    if (!(plugin = pa_modargs_get_value(ma, "plugin", NULL))) {
        pa_log("Missing LADSPA plugin name");
        goto fail;
    }

    if (!(label = pa_modargs_get_value(ma, "label", NULL))) {
        pa_log("Missing LADSPA plugin label");
        goto fail;
    }

    if (!(input_ladspaport_map = pa_modargs_get_value(ma, "input_ladspaport_map", NULL)))
        pa_log_debug("Using default input ladspa port mapping");

    if (!(output_ladspaport_map = pa_modargs_get_value(ma, "output_ladspaport_map", NULL)))
        pa_log_debug("Using default output ladspa port mapping");

    cdata = pa_modargs_get_value(ma, "control", NULL);

    u = pa_xnew0(struct userdata, 1);
    u->module = m;
    m->userdata = u;
    u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
    u->max_ladspaport_count = 1; /*to avoid division by zero etc. in pa__done when failing before this value has been set*/
    u->channels = 0;
    u->input = NULL;
    u->output = NULL;

    if (!(e = getenv("LADSPA_PATH")))
        e = LADSPA_PATH;

    /* FIXME: This is not exactly thread safe */
    t = pa_xstrdup(lt_dlgetsearchpath());
    lt_dlsetsearchpath(e);
    m->dl = lt_dlopenext(plugin);
    lt_dlsetsearchpath(t);
    pa_xfree(t);

    if (!m->dl) {
        pa_log("Failed to load LADSPA plugin: %s", lt_dlerror());
        goto fail;
    }

    if (!(descriptor_func = (LADSPA_Descriptor_Function) pa_load_sym(m->dl, NULL, "ladspa_descriptor"))) {
        pa_log("LADSPA module lacks ladspa_descriptor() symbol.");
        goto fail;
    }

    for (j = 0;; j++) {

        if (!(d = descriptor_func(j))) {
            pa_log("Failed to find plugin label '%s' in plugin '%s'.", label, plugin);
            goto fail;
        }

        if (strcmp(d->Label, label) == 0)
            break;
    }

    u->descriptor = d;

    pa_log_debug("Module: %s", plugin);
    pa_log_debug("Label: %s", d->Label);
    pa_log_debug("Unique ID: %lu", d->UniqueID);
    pa_log_debug("Name: %s", d->Name);
    pa_log_debug("Maker: %s", d->Maker);
    pa_log_debug("Copyright: %s", d->Copyright);

    n_control = 0;
    u->channels = ss.channels;

    /*
    * Enumerate ladspa ports
    * Default mapping is in order given by the plugin
    */
    for (p = 0; p < d->PortCount; p++) {
        if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) {
            if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p])) {
                pa_log_debug("Port %lu is input: %s", p, d->PortNames[p]);
                input_ladspaport[u->input_count] = p;
                u->input_count++;
            } else if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) {
                pa_log_debug("Port %lu is output: %s", p, d->PortNames[p]);
                output_ladspaport[u->output_count] = p;
                u->output_count++;
            }
        } else if (LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p]) && LADSPA_IS_PORT_INPUT(d->PortDescriptors[p])) {
            pa_log_debug("Port %lu is control: %s", p, d->PortNames[p]);
            n_control++;
        } else
            pa_log_debug("Ignored port %s", d->PortNames[p]);
        /* XXX: Has anyone ever seen an in-place plugin with non-equal number of input and output ports? */
        /* Could be if the plugin is for up-mixing stereo to 5.1 channels */
        /* Or if the plugin is down-mixing 5.1 to two channel stereo or binaural encoded signal */
        if (u->input_count > u->max_ladspaport_count)
            u->max_ladspaport_count = u->input_count;
        else
            u->max_ladspaport_count = u->output_count;
    }

    if (u->channels % u->max_ladspaport_count) {
        pa_log("Cannot handle non-integral number of plugins required for given number of channels");
        goto fail;
    }

    pa_log_debug("Will run %lu plugin instances", u->channels / u->max_ladspaport_count);

    /* Parse data for input ladspa port map */
    if (input_ladspaport_map) {
        const char *state = NULL;
        char *pname;
        c = 0;
        while ((pname = pa_split(input_ladspaport_map, ",", &state))) {
            if (c == u->input_count) {
                pa_log("Too many ports in input ladspa port map");
                goto fail;
            }


            for (p = 0; p < d->PortCount; p++) {
                if (strcmp(d->PortNames[p], pname) == 0) {
                    if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p]) && LADSPA_IS_PORT_INPUT(d->PortDescriptors[p])) {
                        input_ladspaport[c] = p;
                    } else {
                        pa_log("Port %s is not an audio input ladspa port", pname);
                        pa_xfree(pname);
                        goto fail;
                    }
                }
            }
            c++;
            pa_xfree(pname);
        }
    }

    /* Parse data for output port map */
    if (output_ladspaport_map) {
        const char *state = NULL;
        char *pname;
        c = 0;
        while ((pname = pa_split(output_ladspaport_map, ",", &state))) {
            if (c == u->output_count) {
                pa_log("Too many ports in output ladspa port map");
                goto fail;
            }
            for (p = 0; p < d->PortCount; p++) {
                if (strcmp(d->PortNames[p], pname) == 0) {
                    if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p]) && LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) {
                        output_ladspaport[c] = p;
                    } else {
                        pa_log("Port %s is not an output ladspa port", pname);
                        pa_xfree(pname);
                        goto fail;
                    }
                }
            }
            c++;
            pa_xfree(pname);
        }
    }


    u->block_size = pa_frame_align(pa_mempool_block_size_max(m->core->mempool), &ss);

    /* Create buffers */
    if (LADSPA_IS_INPLACE_BROKEN(d->Properties)) {
        u->input = (LADSPA_Data**) pa_xnew(LADSPA_Data*, (unsigned) u->input_count);
        for (c = 0; c < u->input_count; c++)
            u->input[c] = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
        u->output = (LADSPA_Data**) pa_xnew(LADSPA_Data*, (unsigned) u->output_count);
        for (c = 0; c < u->output_count; c++)
            u->output[c] = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
    } else {
Exemple #29
0
CAMLprim value ocaml_ladspa_port_is_audio(value d, value n)
{
  return Val_bool(LADSPA_IS_PORT_AUDIO(LADSPA_descr_val(d)->PortDescriptors[Int_val(n)]));
}
int lp_ladspa_audio_ports::init(const LADSPA_Descriptor *descriptor, int channels, int buf_size, int samplerate)
{
	//mutex.lock();
	if(descriptor == 0){
		std::cerr << "lp_ladspa_audio_ports::" << __FUNCTION__ << ": descriptor is Null\n";
		return -1;
	}

	// Only 1 and 2 channels are possible
	if((channels < 1)||(channels > 2)){
		std::cerr << "lp_ladspa_ctl_port::" << __FUNCTION__ << ": only 1 or 2 channels are supported\n";
		return -1;
	}
	pv_channels = channels;

	if(buf_size == 0){
		std::cerr << "lp_ladspa_audio_ports::" << __FUNCTION__ << ": buffer size is not set\n";
		return -1;
	}

	if(samplerate == 0){
		std::cerr << "lp_ladspa_audio_ports::" << __FUNCTION__ << ": samplerate is not set\n";
		return -1;
	}
	pv_descriptor = descriptor;

	// Count audio ports
	unsigned long pcount, i;
	int nb_in, nb_out;
	pcount = pv_descriptor->PortCount;

	nb_in = 0;
	nb_out = 0;
	for(i=0; i<pcount; i++){
		if((LADSPA_IS_PORT_AUDIO(descriptor->PortDescriptors[i]))&&(LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i]))){
			nb_in++;
		}
		if((LADSPA_IS_PORT_AUDIO(descriptor->PortDescriptors[i]))&&(LADSPA_IS_PORT_OUTPUT(descriptor->PortDescriptors[i]))){
			nb_out++;
		}
	}
	pv_nb_in = nb_in;
	pv_nb_out = nb_out;
	std::cout << "Audio in: " << pv_nb_in << " - out: " << pv_nb_out << std::endl;


	// Search the best routing type
	if(channels == 1){ // 1 channel mode
		if((nb_in == 1)&&(nb_out == 1)){
			pv_routing = MONO_NORMAL;	// One handle - 1 I/O port
			pv_handles_count = 1;
			pv_nb_in = 1;
			pv_nb_out = 1;
		}else if((nb_in == 2)&&(nb_out == 2)){
			pv_routing = MONO_HALF_USED;	// One handle - 2 I/O ports
			pv_handles_count = 1;
			pv_nb_in = 2;
			pv_nb_out = 2;
		}else if((nb_in == 1)&&(nb_out == 2)){
			pv_routing = MONO_1H_MERGE_OUTPUT; // One handle - One I port - 2 O ports
			pv_handles_count = 1;
			pv_nb_in = 1;
			pv_nb_out = 2;
		}else if((nb_in == 2)&&(nb_out == 1)){
			pv_routing = MONO_1H_SPLIT_INPUT; // One handle - 2 I ports - One O port
			pv_handles_count = 1;
			pv_nb_in = 2;
			pv_nb_out = 1;
		}else if((nb_in == 0)&&(nb_out == 1)){
			pv_routing = MONO_1H_NO_INPUT;	// One handle - 0 I port - 1 O port
			pv_handles_count = 1;
			pv_nb_in = 0;
			pv_nb_out = 1;
		}else if((nb_in == 0)&&(nb_out == 2)){
			pv_routing = MONO_1H_NO_INPUT_MERGE_OUTPUT; // One handle - 0 I port - 2 O ports
			pv_handles_count = 1;
			pv_nb_in = 0;
			pv_nb_out = 2;
		}else{
			pv_routing = UNSUPPORTED;
			std::cerr << "lp_ladspa_audio_ports::" << __FUNCTION__ << ": cannot find audio routing\n";
		}
	}else if(channels == 2){ // 2 channels mode
		if((nb_in == 2)&&(nb_out == 2)){
			pv_routing = STEREO_NORMAL;		// One handle - 2 I/O ports
			pv_handles_count = 1;
			pv_nb_in = 2;
			pv_nb_out = 2;
		}else if((nb_in == 1)&&(nb_out == 1)){
			pv_routing = STEREO_2H;			// Two handles - 2 I/O ports
			pv_handles_count = 2;
			pv_nb_in = 2;
			pv_nb_out = 2;
		}else if((nb_in == 1)&&(nb_out == 2)){
			pv_routing = STEREO_2H_MERGE_OUTPUT;	// Two handles - 2 I ports - 4 O ports
			pv_handles_count = 2;		
			pv_nb_in = 2;
			pv_nb_out = 4;
			pv_nb_tmp = 2;
		}else if((nb_in == 2)&&(nb_out == 1)){
			pv_routing = STEREO_2H_MERGE_INPUT;	// Two handles - 4 I ports - 2 O port
			pv_handles_count = 2;
			pv_nb_in = 4;
			pv_nb_out = 2;
		}else if((nb_in == 0)&&(nb_out == 1)){
			pv_routing = STEREO_2H_NO_INPUT;	// Two handles - 0 I port - 2 O ports
			pv_handles_count = 2;
			pv_nb_in = 0;
			pv_nb_out = 2;
		}else if((nb_in == 0)&&(nb_out == 2)){
			pv_routing = STEREO_1H_NO_INPUT;	// One handle - 0 I port - 2 O ports
			pv_handles_count = 1;
			pv_nb_in = 0;
			pv_nb_out = 2;
		}else{
			pv_routing = UNSUPPORTED;
			std::cerr << "lp_ladspa_audio_ports::" << __FUNCTION__ << ": cannot find audio routing\n";
		}
	}else{
			pv_routing = UNSUPPORTED;
			std::cerr << "lp_ladspa_audio_ports::" << __FUNCTION__ << ": cannot find audio routing\n";
	}

	// Allocate in and out tabs NOTE: review buffer size ! To big in stereo mode !
	if(pv_nb_in > 0){
		pv_in_data = new lp_ladspa_audio_data[pv_nb_in];
		if(pv_in_data == 0){
			std::cerr << "lp_ladspa_audio_ports::" << __FUNCTION__ << ": memory allocation failed\n";
			return -1;
		}
		for(i=0; i<(unsigned long)pv_nb_in; i++){
			if(pv_in_data[i].alloc(buf_size)<0){
				return -1;
			}
			pv_in_data[i].set_descriptor(pv_descriptor);
		}
	}
	if(pv_nb_out > 0){
		pv_out_data = new lp_ladspa_audio_data[pv_nb_out];
		if(pv_out_data == 0){
			std::cerr << "lp_ladspa_audio_ports::" << __FUNCTION__ << ": memory allocation failed\n";
			return -1;
		}
		for(i=0; i<(unsigned long)pv_nb_out; i++){
			if(pv_out_data[i].alloc(buf_size)<0){
				return -1;
			}
			pv_out_data[i].set_descriptor(pv_descriptor);
		}
	}
	if(pv_nb_tmp > 0){
		pv_tmp_data = new lp_ladspa_audio_data[pv_nb_tmp];
		if(pv_tmp_data == 0){
			std::cerr << "lp_ladspa_audio_ports::" << __FUNCTION__ << ": memory allocation failed\n";
			return -1;
		}
		for(i=0; i<(unsigned long)pv_nb_tmp; i++){
			if(pv_tmp_data[i].alloc(buf_size)<0){
				return -1;
			}
		}
	}

	//mutex.unlock();
	return 0;
}