Hi All,

I'm trying to write a LADSPA plugin to do the following:

Given n inputs (lets say 4), and one output, It should present the
highest "priority" input on the output. Input 1 is the lowest priority,
with Input 4 being the highest.

In order to write this in code, within the runPriomux function, I do
this:

   y=-1;
   for (i=0; i<=3; i++)
   {
      pfBuffer=*(pfInput[i]++);
      if (pfBuffer > -1.0f)
        y=i;
    }
    if (y!=-1)
      *(pfOutput++)=pfBuffer;

i is the input channel (0-3, not 1-4, but you know what I mean)
y is what is supposed to be the highest priority channel with audio
on it.


Now..here's where Im confused. I thought the values for audio samples
in LADSPA were -1.0f...1.0f (with -1.0f being infinity). This doesn't
seem to work, as the above code always appears to think that the 4th
input (i=3) has data on it, even if it's muted in ardour (via another
bus that's single output is connected to input 4...)

I've also looked at the code of meterbridge, and tried using -70.0f,
but with the same problem...Anyone want to plant me a clue on what
I'm doing wrong ?

I've attached the entire plugin source below. It's really been ripped
off of the example amp in the LADSPA SDK I'm afraid....

Thanks in advance for any help, this last bit is driving me mad, now
I've worked out how to code plugins!


All the Best

Iain

/* priomux.c */

/* Written by Iain Young, [EMAIL PROTECTED] (C) 2006 */

/* Based on amp.c by  Richard W.E. Furse. No Warranty. His Dire */
/* warnings  .h"
*/

/* This plugin selected the top most priority from it n inputs */
/* and outputs it to the single output. Currently mono only. */


#include <stdlib.h>
#include <string.h>

#include "ladspa.h"

/* Port Numbers */

#define PRIOMUX_OUTPUT1	0
#define PRIOMUX_OUTPUT2	1
#define PRIOMUX_OUTPUT3	2
#define PRIOMUX_OUTPUT4	3
#define PRIOMUX_INPUT1	4
#define PRIOMUX_INPUT2	5
#define PRIOMUX_INPUT3	6
#define PRIOMUX_INPUT4	7

typedef struct {
	LADSPA_Data * m_pfOutputBuffer1;
	LADSPA_Data * m_pfOutputBuffer2;
	LADSPA_Data * m_pfOutputBuffer3;
	LADSPA_Data * m_pfOutputBuffer4;
	LADSPA_Data * m_pfInputBuffer1;
	LADSPA_Data * m_pfInputBuffer2;
	LADSPA_Data * m_pfInputBuffer3;
	LADSPA_Data * m_pfInputBuffer4;
} Priomux;

/* Construct a new plugin instance */

LADSPA_Handle instantiatePriomux (const LADSPA_Descriptor * Descriptor, unsigned long SampleRate)
{
	return malloc(sizeof(Priomux));
}

/* Connect a port to a data location */

void connectPortToPriomux(LADSPA_Handle Instance, unsigned long Port, LADSPA_Data * DataLocation)
{

	Priomux * psPriomux;

	psPriomux = (Priomux *)Instance;
	switch (Port) {
		case PRIOMUX_OUTPUT1:
			psPriomux->m_pfOutputBuffer1 = DataLocation;
			break;
		case PRIOMUX_OUTPUT2:
			psPriomux->m_pfOutputBuffer2 = DataLocation;
			break;
		case PRIOMUX_OUTPUT3:
			psPriomux->m_pfOutputBuffer3 = DataLocation;
			break;
		case PRIOMUX_OUTPUT4:
			psPriomux->m_pfOutputBuffer4 = DataLocation;
			break;
		case PRIOMUX_INPUT1:
			psPriomux->m_pfInputBuffer1 = DataLocation;
			break;
		case PRIOMUX_INPUT2:
			psPriomux->m_pfInputBuffer2 = DataLocation;
			break;
		case PRIOMUX_INPUT3:
			psPriomux->m_pfInputBuffer3 = DataLocation;
			break;
		case PRIOMUX_INPUT4:
			psPriomux->m_pfInputBuffer4 = DataLocation;
			break;
	}
}

/* Actually run the priomux */

void runPriomux(LADSPA_Handle Instance, unsigned long SampleCount)
{

	signed int y=-1;
	int i;

	LADSPA_Data *pfOutput;
	LADSPA_Data *pfInput[4];
	float pfBuffer;

        Priomux * psPriomux;
	unsigned long lSampleIndex;

	psPriomux = (Priomux *)Instance;

	pfOutput = psPriomux->m_pfOutputBuffer1;
	pfInput[0] = psPriomux->m_pfInputBuffer1;
	pfInput[1] = psPriomux->m_pfInputBuffer2;
	pfInput[2] = psPriomux->m_pfInputBuffer3;
	pfInput[3] = psPriomux->m_pfInputBuffer4;

	for (lSampleIndex=0; lSampleIndex < SampleCount; lSampleIndex++)
	{
        	y=-1;
		for (i=0; i<=3; i++)
		{
			pfBuffer=*(pfInput[i]++);
			if (pfBuffer > -1.0f)
				y=i;
		}
		if (y!=-1)
			*(pfOutput++)=pfBuffer;
	}
}

void cleanupPriomux(LADSPA_Handle Instance)
{
	free(Instance);
}

LADSPA_Descriptor * g_psMonoDescriptor = NULL;

void _init()
{
	char ** pcPortNames;
	LADSPA_PortDescriptor * piPortDescriptors;
	LADSPA_PortRangeHint * psPortRangeHints;

	g_psMonoDescriptor = (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
	g_psMonoDescriptor->UniqueID = 9994;
	g_psMonoDescriptor->Label = strdup("priomux");
	g_psMonoDescriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
	g_psMonoDescriptor->Name = strdup("Priority Mux");
	g_psMonoDescriptor->Maker = strdup("Iain Young");

	g_psMonoDescriptor->Copyright = strdup("None");
	g_psMonoDescriptor->PortCount = 8;

	piPortDescriptors = (LADSPA_PortDescriptor *)calloc(8, sizeof(LADSPA_PortDescriptor));
	g_psMonoDescriptor->PortDescriptors = (const LADSPA_PortDescriptor *)piPortDescriptors;
	piPortDescriptors[PRIOMUX_OUTPUT1] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
	piPortDescriptors[PRIOMUX_OUTPUT2] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
	piPortDescriptors[PRIOMUX_OUTPUT3] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
	piPortDescriptors[PRIOMUX_OUTPUT4] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
	piPortDescriptors[PRIOMUX_INPUT1] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
	piPortDescriptors[PRIOMUX_INPUT2] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
	piPortDescriptors[PRIOMUX_INPUT3] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
	piPortDescriptors[PRIOMUX_INPUT4] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
	pcPortNames = (char **)calloc(8, sizeof(char *));
	g_psMonoDescriptor->PortNames = (const char **)pcPortNames;
	pcPortNames[PRIOMUX_OUTPUT1] = strdup("Output 1");
	pcPortNames[PRIOMUX_OUTPUT2] = strdup("Output 2");
	pcPortNames[PRIOMUX_OUTPUT3] = strdup("Output 3");
	pcPortNames[PRIOMUX_OUTPUT4] = strdup("Output 4");
	pcPortNames[PRIOMUX_INPUT1] = strdup("Input 1");
	pcPortNames[PRIOMUX_INPUT2] = strdup("Input 2");
	pcPortNames[PRIOMUX_INPUT3] = strdup("Input 3");
	pcPortNames[PRIOMUX_INPUT4] = strdup("Input 4");

	psPortRangeHints = ((LADSPA_PortRangeHint *) calloc(8, sizeof(LADSPA_PortRangeHint)));
	g_psMonoDescriptor->PortRangeHints = (const LADSPA_PortRangeHint *)psPortRangeHints;
	psPortRangeHints[PRIOMUX_OUTPUT1].HintDescriptor = 0;
	psPortRangeHints[PRIOMUX_OUTPUT2].HintDescriptor = 0;
	psPortRangeHints[PRIOMUX_OUTPUT3].HintDescriptor = 0;
	psPortRangeHints[PRIOMUX_OUTPUT4].HintDescriptor = 0;
	psPortRangeHints[PRIOMUX_INPUT1].HintDescriptor = 0;
	psPortRangeHints[PRIOMUX_INPUT2].HintDescriptor = 0;
	psPortRangeHints[PRIOMUX_INPUT3].HintDescriptor = 0;
	psPortRangeHints[PRIOMUX_INPUT4].HintDescriptor = 0;

	g_psMonoDescriptor->instantiate = instantiatePriomux;
	g_psMonoDescriptor->connect_port = connectPortToPriomux;
	g_psMonoDescriptor->activate  = NULL;
	g_psMonoDescriptor->run = runPriomux;

	g_psMonoDescriptor->run_adding = NULL;
	g_psMonoDescriptor->set_run_adding_gain = NULL;
	g_psMonoDescriptor->deactivate = NULL;
	g_psMonoDescriptor->cleanup = cleanupPriomux;
}

void deleteDescriptor(LADSPA_Descriptor * psDescriptor)
{
	unsigned long lIndex;
	if (psDescriptor)
	{
		free((char *)psDescriptor->Label);
		free((char *)psDescriptor->Name);
		free((char *)psDescriptor->Maker);
		free((char *)psDescriptor->Copyright);
		free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);

		for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
			free((char *)(psDescriptor->PortNames[lIndex]));

		free((char **)psDescriptor->PortNames);
		free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
		free(psDescriptor);
	}
}

void _fini()
{
	deleteDescriptor(g_psMonoDescriptor);
}

const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index)
{
	switch (Index) {
		case 0:
			return g_psMonoDescriptor;
		default:
			return NULL;
	}
}


Reply via email to