ladspa_example/ladex.c
2024-03-01 10:03:26 -06:00

139 lines
3.8 KiB
C

#include<ladspa.h>
#include<limits.h>
#include<stdint.h>
#include<stdlib.h>
#include<string.h>
#ifndef __cplusplus
# if __GNUC__
# define ON_LOAD_ROUTINE static void __attribute__ ((constructor)) init()
# define ON_UNLOAD_ROUTINE static void __attribute__ ((destructor)) fini()
# else
# define ON_LOAD_ROUTINE void init()
# define ON_UNLOAD_ROUTINE void fini()
# endif
#endif
// Port numbers for the plugin
#define LADEX_PORT_COUNT 3
#define LADEX_PORT_AMPLITUDE 0x0
#define LADEX_PORT_OUTPUT 0x1
#define LADEX_PORT_INPUT 0x2
// Port connection information and state
typedef struct Ladex
{
LADSPA_Data*amp;
LADSPA_Data*output;
LADSPA_Data*input;
} Ladex;
// Descriptor for plugin
static LADSPA_Descriptor*ladspa_desc;
// Run plugin over block
static void ladex_run(LADSPA_Handle handle,unsigned long samplecount)
{
Ladex*ladex=(Ladex*)handle;
LADSPA_Data amp=*(ladex->amp)*(LADSPA_Data)(2.0/INT_MAX);
for(uint32_t i=0;i<samplecount;i++)
ladex->output[i]=(ladex->input[i]+((i%500>250)?(INT_MAX):(-INT_MAX))*amp)/2.0f;
}
// Construct a new plugin instance
static LADSPA_Handle ladex_instantiate(const LADSPA_Descriptor*desc,unsigned long samplerate)
{
desc=desc;
samplerate=samplerate;
return calloc(1,sizeof(Ladex));
}
// Connect a port to a data location
static void ladex_connect_port(LADSPA_Handle handle,unsigned long port,LADSPA_Data*dataloc)
{
Ladex*ladex=(Ladex*)handle;
switch(port)
{
case LADEX_PORT_AMPLITUDE:
ladex->amp=dataloc;
break;
case LADEX_PORT_OUTPUT:
ladex->output=dataloc;
break;
case LADEX_PORT_INPUT:
ladex->input=dataloc;
break;
}
}
// Free memory
static void ladex_cleanup(LADSPA_Handle handle)
{
free(handle);
}
// Called automatically when the plugin library is first loaded
ON_LOAD_ROUTINE
{
char**portnames;
LADSPA_PortDescriptor*portdesc;
LADSPA_PortRangeHint*hints;
ladspa_desc=(LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
if(ladspa_desc)
{
ladspa_desc->UniqueID=999;
ladspa_desc->Label="lad_ex";
ladspa_desc->Properties=LADSPA_PROPERTY_HARD_RT_CAPABLE;
ladspa_desc->Name="LADSPA example";
ladspa_desc->Maker="LADSPA example";
ladspa_desc->Copyright="Corey Dunn";
ladspa_desc->PortCount=LADEX_PORT_COUNT;
portdesc=(LADSPA_PortDescriptor*)calloc(LADEX_PORT_COUNT,sizeof(LADSPA_PortDescriptor));
ladspa_desc->PortDescriptors=(const LADSPA_PortDescriptor*)portdesc;
portdesc[LADEX_PORT_AMPLITUDE]=(LADSPA_PORT_INPUT|LADSPA_PORT_CONTROL);
portdesc[LADEX_PORT_OUTPUT]=LADSPA_PORT_OUTPUT|LADSPA_PORT_AUDIO;
portdesc[LADEX_PORT_INPUT]=LADSPA_PORT_INPUT|LADSPA_PORT_AUDIO;
portnames=(char**)calloc(LADEX_PORT_COUNT,sizeof(char*));
ladspa_desc->PortNames=(const char**)portnames;
portnames[LADEX_PORT_AMPLITUDE]="Amplitude";
portnames[LADEX_PORT_OUTPUT]="Output";
hints=((LADSPA_PortRangeHint*)calloc(LADEX_PORT_COUNT,sizeof(LADSPA_PortRangeHint)));
ladspa_desc->PortRangeHints=(const LADSPA_PortRangeHint*)hints;
hints[LADEX_PORT_AMPLITUDE].HintDescriptor=(LADSPA_HINT_BOUNDED_BELOW|LADSPA_HINT_LOGARITHMIC|LADSPA_HINT_DEFAULT_LOW);
hints[LADEX_PORT_AMPLITUDE].LowerBound=0;
hints[LADEX_PORT_OUTPUT].HintDescriptor=0;
ladspa_desc->instantiate=ladex_instantiate;
ladspa_desc->connect_port=ladex_connect_port;
ladspa_desc->activate=NULL;
ladspa_desc->run=ladex_run;
ladspa_desc->run_adding=NULL;
ladspa_desc->set_run_adding_gain=NULL;
ladspa_desc->deactivate=NULL;
ladspa_desc->cleanup=ladex_cleanup;
}
}
// Called automatically when the library is unloaded
ON_UNLOAD_ROUTINE
{
if(ladspa_desc)
{
free((LADSPA_PortDescriptor*)ladspa_desc->PortDescriptors);
free((char**)ladspa_desc->PortNames);
free((LADSPA_PortRangeHint*)ladspa_desc->PortRangeHints);
free(ladspa_desc);
}
}
// Return a descriptor of the requested plugin type
const LADSPA_Descriptor*ladspa_descriptor(unsigned long index)
{
if(index==0)
return ladspa_desc;
else
return NULL;
}