microphone check one two what is this

This commit is contained in:
Connor Olding 2013-05-22 15:56:59 -07:00
commit 1b26a973af
7 changed files with 633 additions and 0 deletions

22
LICENSE Normal file
View File

@ -0,0 +1,22 @@
Copyright (C) 2013 Connor Olding
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

57
Makefile Normal file
View File

@ -0,0 +1,57 @@
DISTNAME = crap
VERSION = git
SHOBJ = crap_eq.so
MID = crap_util.o
OBJ = ${SHOBJ:.so=.o} ${MID}
SRC = ${OBJ:.o=.c}
HEADERS = crap_util.h ladspa.h
PLACEBO_FLAGS = -fomit-frame-pointer -fstrength-reduce -funroll-loops -ffast-math
ALL_CFLAGS = -O3 ${PLACEBO_FLAGS} -std=c99 -fPIC -Wall ${CFLAGS}
ALL_LDFLAGS = -nostartfiles -shared ${LDFLAGS}
PREFIX ?= /usr/local
EXEC_PREFIX ?= ${PREFIX}
LIBDIR ?= ${EXEC_PREFIX}/lib
LADSPADIR ?= ${LIBDIR}/ladspa
# should CFLAGS really be used in linking too? seems odd
FULLNAME = ${DISTNAME}-${VERSION}
ALL = ${OBJ} ${SHOBJ}
LADSPADEST = ${DESTDIR}${LADSPADIR}
all: options ${ALL}
.PHONY: options
options:
@echo "ALL_CFLAGS = ${ALL_CFLAGS}"
@echo "CPPFLAGS = ${CPPFLAGS}"
@echo "ALL_LDFLAGS = ${ALL_LDFLAGS}"
@echo "CC = ${CC}"
%.so: %.o
@echo LD $< ${MID} -o $@
@${CC} ${ALL_LDFLAGS} $< ${MID} -o $@
%.o: %.c ${HEADERS}
@echo CC $< -o $@
@${CC} -c ${ALL_CFLAGS} ${CPPFLAGS} $< -o $@
install: all
mkdir -p ${LADSPADEST}
install -d ${LADSPADEST}
install -m 644 ${SHOBJ} ${LADSPADEST}
clean:
-rm -f ${ALL}
dist:
-rm -f ${FULLNAME}.tar.gz
mkdir -p ${FULLNAME}
cp LICENSE README.md Makefile ${HEADERS} ${SRC} ${FULLNAME}
tar -cf ${FULLNAME}.tar ${FULLNAME}
gzip ${FULLNAME}.tar
rm -rf ${FULLNAME}

12
README.md Normal file
View File

@ -0,0 +1,12 @@
# crap
connor's rancid audio plugins. LADSPA.
alternatively, crazy-revealing androgynous panties
### crap_eq
multiband parametric EQ. try redefining BANDS.
### crap_eq_const
workinonit...

232
crap_eq.c Normal file
View File

@ -0,0 +1,232 @@
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include "ladspa.h"
#include "crap_util.h"
typedef unsigned long ulong;
/* Ports:
* BANDS*0 to BANDS*1-1: gain
* BANDS*1 to BANDS*2-1: frequency
* BANDS*2 to BANDS*3-1: bandwidth
*/
#ifndef BANDS
#define BANDS 4
#endif
#define EQ_INPUT (BANDS*3+0)
#define EQ_OUTPUT (BANDS*3+1)
#define PCOUNT (BANDS*3+2)
#define GAIN_MIN -60
#define GAIN_MAX 18
#define FREQ_MIN 1
#define FREQ_MAX 20000
#define BW_MIN 0.02
#define BW_MAX 8
LADSPA_PortDescriptor p_discs[PCOUNT];
LADSPA_PortRangeHint p_hints[PCOUNT];
const char *p_names[PCOUNT];
static LADSPA_Descriptor eqDescriptor = {
.UniqueID = 0xCAFED,
.Label = "crap_eq",
.Properties = 0,
.Name = "crap Parametric Equalizer",
.Maker = "Connor Olding",
.Copyright = "MIT",
.PortCount = PCOUNT,
.PortDescriptors = p_discs,
.PortRangeHints = p_hints,
.PortNames = p_names
};
typedef struct {
LADSPA_Data *chg[BANDS];
LADSPA_Data *chf[BANDS];
LADSPA_Data *chb[BANDS];
LADSPA_Data old_chg[BANDS];
LADSPA_Data old_chf[BANDS];
LADSPA_Data old_chb[BANDS];
LADSPA_Data *input;
LADSPA_Data *output;
biquad filters[BANDS];
LADSPA_Data fs;
LADSPA_Data run_adding_gain;
} eq_t;
const LADSPA_Descriptor *
ladspa_descriptor(ulong index) {
if (index != 0)
return NULL;
return &eqDescriptor;
}
static void
activate_eq(LADSPA_Handle instance) {
eq_t *eq = (eq_t *)instance;
biquad *filters = eq->filters;
for (int i = 0; i < BANDS; i++)
biquad_init(&filters[i]);
}
static void
cleanup_eq(LADSPA_Handle instance) {
free(instance);
}
static void
connect_port_eq(LADSPA_Handle instance, ulong port, LADSPA_Data *data) {
eq_t *eq = (eq_t *)instance;
if (port < BANDS)
eq->chg[port - BANDS*0] = data;
else if (port < BANDS*2)
eq->chf[port - BANDS*1] = data;
else if (port < BANDS*3)
eq->chb[port - BANDS*2] = data;
else if (port == EQ_INPUT)
eq->input = data;
else if (port == EQ_OUTPUT)
eq->output = data;
}
static LADSPA_Handle
instantiate_eq(const LADSPA_Descriptor *descriptor, ulong s_rate) {
eq_t *eq = (eq_t *) calloc(1, sizeof(eq_t));
biquad *filters = eq->filters;
LADSPA_Data fs = s_rate;
eq->fs = fs;
eq->run_adding_gain = 1;
const LADSPA_Data g = 0;
const LADSPA_Data f = 440;
const LADSPA_Data b = 1;
for (int i = 0; i < BANDS; i++) {
eq->old_chg[i] = g;
eq->old_chf[i] = f;
eq->old_chb[i] = b;
biquad_gen(&filters[i], 1, f, g, b, fs);
}
return (LADSPA_Handle) eq;
}
static void
run_eq_for_real(LADSPA_Handle instance, ulong sample_count, int running) {
eq_t *eq = (eq_t *) instance;
const LADSPA_Data fs = eq->fs;
biquad *filters = eq->filters;
/* TODO: I don't think this should be here at all */
for (int i = 0; i < BANDS; i++) {
const LADSPA_Data rg = *(eq->chg[i]);
const LADSPA_Data rf = *(eq->chf[i]);
const LADSPA_Data rb = *(eq->chb[i]);
const LADSPA_Data g = LIMIT(rg, GAIN_MIN, GAIN_MAX);
const LADSPA_Data f = LIMIT(rf, FREQ_MIN, FREQ_MAX);
const LADSPA_Data b = LIMIT(rb, BW_MIN, BW_MAX);
if ((g != eq->old_chg[i])
|| (f != eq->old_chf[i])
|| (b != eq->old_chb[i])) {
eq->old_chg[i] = g;
eq->old_chf[i] = f;
eq->old_chb[i] = b;
biquad_gen(&filters[i], 1, f, g, b, fs);
}
}
const LADSPA_Data *input = eq->input;
LADSPA_Data *output = eq->output;
for (ulong pos = 0; pos < sample_count; pos++) {
LADSPA_Data samp = input[pos];
for (int i = 0; i < BANDS; i++) {
/* TODO: skip over 0 gains? */
samp = biquad_run(&filters[i], samp);
}
if (running)
output[pos] += eq->run_adding_gain * samp;
else
output[pos] = samp;
}
}
static void
run_eq(LADSPA_Handle instance, ulong sample_count) {
run_eq_for_real(instance, sample_count, 0);
}
static void
run_adding_eq(LADSPA_Handle instance, ulong sample_count) {
run_eq_for_real(instance, sample_count, 1);
}
void
set_run_adding_gain(LADSPA_Handle instance, LADSPA_Data gain) {
eq_t *eq = (eq_t *) instance;
eq->run_adding_gain = gain;
}
void
_init() {
#define INCTRL (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL)
#define BOUNDED (LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE)
for (int i = 0; i < BANDS; i++) {
const int gi = i;
const int fi = i + BANDS;
const int bi = i + BANDS*2;
p_discs[gi] = INCTRL;
p_discs[fi] = INCTRL;
p_discs[bi] = INCTRL;
/* TODO: generate strings per band */
p_names[gi] = "Band x Gain [dB]";
p_names[fi] = "Band x Freq [Hz]";
p_names[bi] = "Band x Bandwidth [octaves]";
p_hints[gi].HintDescriptor = BOUNDED
| LADSPA_HINT_DEFAULT_0;
p_hints[fi].HintDescriptor = BOUNDED
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_440;
p_hints[bi].HintDescriptor = BOUNDED
| LADSPA_HINT_DEFAULT_1;
p_hints[gi].LowerBound = GAIN_MIN;
p_hints[gi].UpperBound = GAIN_MAX;
p_hints[fi].LowerBound = FREQ_MIN;
p_hints[fi].UpperBound = FREQ_MAX;
p_hints[bi].LowerBound = BW_MIN;
p_hints[bi].UpperBound = BW_MAX;
}
p_discs[EQ_INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
p_names[EQ_INPUT] = "Input";
p_hints[EQ_INPUT].HintDescriptor = 0;
p_discs[EQ_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
p_names[EQ_OUTPUT] = "Output";
p_hints[EQ_OUTPUT].HintDescriptor = 0;
eqDescriptor.activate = activate_eq;
eqDescriptor.cleanup = cleanup_eq;
eqDescriptor.connect_port = connect_port_eq;
eqDescriptor.deactivate = NULL;
eqDescriptor.instantiate = instantiate_eq;
eqDescriptor.run = run_eq;
eqDescriptor.run_adding = run_adding_eq;
eqDescriptor.set_run_adding_gain = set_run_adding_gain;
}
void
_fini() {
}

135
crap_util.c Normal file
View File

@ -0,0 +1,135 @@
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include "crap_util.h"
/* used to resemble https://github.com/swh/ladspa/blob/master/util/biquad.h */
void
biquad_init(biquad *bq) {
bq->x1 = 0;
bq->x2 = 0;
bq->y1 = 0;
bq->y2 = 0;
}
biquad_interim
peaking(double cw, double Gf, double g) {
double GB = sqrt(Gf);
return (biquad_interim) {
.b0 = 1 + g * GB,
.b1 = -2 * cw,
.b2 = 1 - g * GB,
.a0 = 1 + g / GB,
.a1 = -2 * cw,
.a2 = 1 - g / GB
};
}
biquad_interim
highpass(double cw, double g) {
return (biquad_interim) {
.b0 = 1 + cw*0.5,
.b1 = -cw - 1,
.b2 = 1 + cw*0.5,
.a0 = 1 + g,
.a1 = -2*cw,
.a2 = 1 - g
};
}
/* TODO: rename */
biquad_interim
orfanidi(double w0, double Gf, double g) {
/* simplified http://ece.rutgers.edu/~orfanidi/intro2sp/mdir/peq.m */
double Dw, GfS, F, G00, F00, term1, term2, num, den;
double G1S, G1, G01, G11, F01, F11, W2, DO, coeff, C, D, A, B;
double v;
Dw = atan(g)*2;
GfS = SQR(Gf);
v = (Gf > 1) ? 1 : -1;
F = v*(GfS - Gf);
G00 = v*(GfS - 1);
F00 = v*(Gf - 1);
term1 = SQR(SQR(w0) - SQR(M_PI));
term2 = F00 * SQR(M_PI) * SQR(Dw) / F;
num = term1 + term2 * GfS;
den = term1 + term2;
G1S = num/den;
G1 = sqrt(G1S);
G01 = v*(GfS - G1);
G11 = v*(GfS - G1S);
F01 = v*(Gf - G1);
F11 = fabs(Gf - G1S);
/* bandwidth compensation goes nuts
* skip |= v*(Gf - G1S) < 0; */
W2 = sqrt(G11 / G00) * SQR(tan(w0/2));
DO = (1 + sqrt(F00 / F11) * W2) * g;
coeff = 2 * W2 / F;
C = F11 * SQR(DO) / F - coeff * (F01 - sqrt(F00 * F11));
D = coeff * (G01 - sqrt(G00 * G11));
A = sqrt( C + D);
B = sqrt(GfS * C + Gf * D);
return (biquad_interim) {
.b0 = -(G1 + W2 + B),
.b1 = 2*(G1 - W2),
.b2 = -(G1 - B + W2),
.a0 = -(1 + W2 + A),
.a1 = 2*(1 - W2),
.a2 = -(1 + W2 - A)
};
}
void
biquad_gen(biquad *bq, int type, double fc, double gain, double bw, double fs) {
/* TODO: use enum for type instead of just int */
double w0, cw, sw, Gf, Q, a_peak, a_pass;
w0 = ANGULAR_LIM(fc, fs);
cw = cos(w0);
sw = sin(w0);
Gf = DB2LIN(gain);
Q = 1/(2 * sinh(LN_2_2 * bw * w0/sw));
a_peak = sw * (2 / Q);
a_pass = sw / (1 * Q);
/* skip = (fabs(Gf - 1) <= TINY); */
biquad_interim bqi;
if (type == 0) bqi = peaking(cw, Gf, a_peak);
if (type == 1) bqi = orfanidi(w0, Gf, a_peak);
if (type == 2) bqi = highpass(cw, a_pass);
double a0r = 1/bqi.a0;
bq->b0 = a0r * bqi.b0;
bq->b1 = a0r * bqi.b1;
bq->b2 = a0r * bqi.b2;
bq->a1 = -a0r * bqi.a1;
bq->a2 = -a0r * bqi.a2;
}
bq_t
biquad_run(biquad *bq, bq_t x) {
bq_t y;
y = bq->b0 * x + bq->b1 * bq->x1 + bq->b2 * bq->x2
+ bq->a1 * bq->y1 + bq->a2 * bq->y2;
if (IS_DENORMAL(y)) y = 0;
bq->x2 = bq->x1;
bq->x1 = x;
bq->y2 = bq->y1;
bq->y1 = y;
return y;
}

59
crap_util.h Normal file
View File

@ -0,0 +1,59 @@
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327
#endif
#ifndef M_LN2
#define M_LN2 0.69314718055994530942
#endif
/* ln(2)/2 */
#define LN_2_2 0.3465735902799726547086
#define SQR(x) ((x)*(x))
#define DB2LIN(x) ((x) > -90 ? pow(10, (x) * 0.05) : 0)
/* branchless, supposedly kills denormals when l=1 u=1 */
#define CLIP(v,l,u) (fabs(v-l)+(l+u)-fabs(v-u))*0.5;
/* branches, but smaller and generic with no side effects */
#define LIMIT(v,l,u) ((v)<(l)?(l):((v)>(u)?(u):(v)))
/* frequency to rads/sec (angular frequency) */
#define ANGULAR(fc, fs) (2 * M_PI / (fs) * (fc))
#define ANGULAR_LIM(fc, fs) (2 * M_PI / (fs) * LIMIT((fc), 1, (fs)/2))
/* http://musicdsp.org/showone.php?id=51 */
/* http://musicdsp.org/files/denormal.pdf */
#ifdef BIQUAD_DOUBLE
typedef double bq_t;
#define IS_DENORMAL(f) (((*(uint64_t *)&f)&0x7FF0000000000000)==0)
#else
typedef float bq_t;
#define IS_DENORMAL(f) (((*(uint32_t *)&f)&0x7F800000)==0)
#endif
typedef struct {
bq_t a1, a2, b0, b1, b2, x1, x2, y1, y2;
} biquad;
typedef struct {
double b0, b1, b2, a0, a1, a2;
} biquad_interim;
void
biquad_init(biquad *bq);
biquad_interim
peaking(double cw, double Gf, double g);
biquad_interim
highpass(double cw, double g);
biquad_interim
orfanidi(double w0, double Gf, double g);
void
biquad_gen(biquad *bq, int type, double fc, double gain, double bw, double fs);
bq_t
biquad_run(biquad *bq, bq_t x);

116
ladspa.h Normal file
View File

@ -0,0 +1,116 @@
/* ladspa.h
* Linux Audio Developer's Simple Plugin API Version 1.1[LGPL].
* Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis,
* This program is licensed under the terms of the LGPL 2.1 License,
* and is distributed without any warranty. A copy of the license is
* available at <https://gnu.org/licenses/lgpl-2.1.txt>.
*/
#ifndef LADSPA_INCLUDED
#define LADSPA_INCLUDED
#define LADSPA_VERSION "1.1"
#define LADSPA_VERSION_MAJOR 1
#define LADSPA_VERSION_MINOR 1
#ifdef __cplusplus
extern "C" {
#endif
typedef float LADSPA_Data;
typedef int LADSPA_Properties;
#define LADSPA_PROPERTY_REALTIME 0x1
#define LADSPA_PROPERTY_INPLACE_BROKEN 0x2
#define LADSPA_PROPERTY_HARD_RT_CAPABLE 0x4
#define LADSPA_IS_REALTIME(x) ((x) & LADSPA_PROPERTY_REALTIME)
#define LADSPA_IS_INPLACE_BROKEN(x) ((x) & LADSPA_PROPERTY_INPLACE_BROKEN)
#define LADSPA_IS_HARD_RT_CAPABLE(x) ((x) & LADSPA_PROPERTY_HARD_RT_CAPABLE)
typedef int LADSPA_PortDescriptor;
#define LADSPA_PORT_INPUT 0x1
#define LADSPA_PORT_OUTPUT 0x2
#define LADSPA_PORT_CONTROL 0x4
#define LADSPA_PORT_AUDIO 0x8
#define LADSPA_IS_PORT_INPUT(x) ((x) & LADSPA_PORT_INPUT)
#define LADSPA_IS_PORT_OUTPUT(x) ((x) & LADSPA_PORT_OUTPUT)
#define LADSPA_IS_PORT_CONTROL(x) ((x) & LADSPA_PORT_CONTROL)
#define LADSPA_IS_PORT_AUDIO(x) ((x) & LADSPA_PORT_AUDIO)
typedef int LADSPA_PortRangeHintDescriptor;
#define LADSPA_HINT_BOUNDED_BELOW 0x1
#define LADSPA_HINT_BOUNDED_ABOVE 0x2
#define LADSPA_HINT_TOGGLED 0x4
#define LADSPA_HINT_SAMPLE_RATE 0x8
#define LADSPA_HINT_LOGARITHMIC 0x10
#define LADSPA_HINT_INTEGER 0x20
#define LADSPA_HINT_DEFAULT_MASK 0x3C0
#define LADSPA_HINT_DEFAULT_NONE 0x0
#define LADSPA_HINT_DEFAULT_MINIMUM 0x40
#define LADSPA_HINT_DEFAULT_LOW 0x80
#define LADSPA_HINT_DEFAULT_MIDDLE 0xC0
#define LADSPA_HINT_DEFAULT_HIGH 0x100
#define LADSPA_HINT_DEFAULT_MAXIMUM 0x140
#define LADSPA_HINT_DEFAULT_0 0x200
#define LADSPA_HINT_DEFAULT_1 0x240
#define LADSPA_HINT_DEFAULT_100 0x280
#define LADSPA_HINT_DEFAULT_440 0x2C0
#define LADSPA_IS_HINT_BOUNDED_BELOW(x) ((x) & LADSPA_HINT_BOUNDED_BELOW)
#define LADSPA_IS_HINT_BOUNDED_ABOVE(x) ((x) & LADSPA_HINT_BOUNDED_ABOVE)
#define LADSPA_IS_HINT_TOGGLED(x) ((x) & LADSPA_HINT_TOGGLED)
#define LADSPA_IS_HINT_SAMPLE_RATE(x) ((x) & LADSPA_HINT_SAMPLE_RATE)
#define LADSPA_IS_HINT_LOGARITHMIC(x) ((x) & LADSPA_HINT_LOGARITHMIC)
#define LADSPA_IS_HINT_INTEGER(x) ((x) & LADSPA_HINT_INTEGER)
#define LADSPA_IS_HINT_HAS_DEFAULT(x) ((x) & LADSPA_HINT_DEFAULT_MASK)
#define LADSPA_IS_HINT_DEFAULT_MINIMUM(x) \
(((x) & LADSPA_HINT_DEFAULT_MASK) == LADSPA_HINT_DEFAULT_MINIMUM)
#define LADSPA_IS_HINT_DEFAULT_LOW(x) \
(((x) & LADSPA_HINT_DEFAULT_MASK) == LADSPA_HINT_DEFAULT_LOW)
#define LADSPA_IS_HINT_DEFAULT_MIDDLE(x) \
(((x) & LADSPA_HINT_DEFAULT_MASK) == LADSPA_HINT_DEFAULT_MIDDLE)
#define LADSPA_IS_HINT_DEFAULT_HIGH(x) \
(((x) & LADSPA_HINT_DEFAULT_MASK) == LADSPA_HINT_DEFAULT_HIGH)
#define LADSPA_IS_HINT_DEFAULT_MAXIMUM(x) \
(((x) & LADSPA_HINT_DEFAULT_MASK) == LADSPA_HINT_DEFAULT_MAXIMUM)
#define LADSPA_IS_HINT_DEFAULT_0(x) \
(((x) & LADSPA_HINT_DEFAULT_MASK) == LADSPA_HINT_DEFAULT_0)
#define LADSPA_IS_HINT_DEFAULT_1(x) \
(((x) & LADSPA_HINT_DEFAULT_MASK) == LADSPA_HINT_DEFAULT_1)
#define LADSPA_IS_HINT_DEFAULT_100(x) \
(((x) & LADSPA_HINT_DEFAULT_MASK) == LADSPA_HINT_DEFAULT_100)
#define LADSPA_IS_HINT_DEFAULT_440(x) \
(((x) & LADSPA_HINT_DEFAULT_MASK) == LADSPA_HINT_DEFAULT_440)
typedef struct _LADSPA_PortRangeHint {
LADSPA_PortRangeHintDescriptor HintDescriptor;
LADSPA_Data LowerBound;
LADSPA_Data UpperBound;
} LADSPA_PortRangeHint;
typedef void * LADSPA_Handle;
typedef struct _LADSPA_Descriptor {
unsigned long UniqueID;
const char * Label;
LADSPA_Properties Properties;
const char * Name;
const char * Maker;
const char * Copyright;
unsigned long PortCount;
const LADSPA_PortDescriptor * PortDescriptors;
const char * const * PortNames;
const LADSPA_PortRangeHint * PortRangeHints;
void * ImplementationData;
LADSPA_Handle (*instantiate)(
const struct _LADSPA_Descriptor * Descriptor,
unsigned long SampleRate
);
void (*connect_port)(
LADSPA_Handle Instance,
unsigned long Port,
LADSPA_Data * DataLocation
);
void (*activate)(LADSPA_Handle Instance);
void (*run)(LADSPA_Handle Instance, unsigned long SampleCount);
void (*run_adding)(LADSPA_Handle Instance, unsigned long SampleCount);
void (*set_run_adding_gain)(LADSPA_Handle Instance, LADSPA_Data Gain);
void (*deactivate)(LADSPA_Handle Instance);
void (*cleanup)(LADSPA_Handle Instance);
} LADSPA_Descriptor;
const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index);
typedef const LADSPA_Descriptor *
(*LADSPA_Descriptor_Function)(unsigned long Index);
#ifdef __cplusplus
}
#endif
#endif