eliminate plugin globals from ladspa

i don't know why this is valid,
but it is and it bloody works
This commit is contained in:
Connor Olding 2015-06-07 19:45:35 -07:00
parent 2ffb2902d9
commit d590355896
3 changed files with 77 additions and 92 deletions

View File

@ -1,6 +1,3 @@
#define BANDS 4
#define PARAMETERS (BANDS*3)
#define BLOCK_SIZE 256 #define BLOCK_SIZE 256
#include <stdio.h> #include <stdio.h>
@ -23,8 +20,8 @@ struct Crap_eq
static constexpr ulong bands = 4; static constexpr ulong bands = 4;
static constexpr ulong parameters = bands*3; static constexpr ulong parameters = bands*3;
biquad filters_L[BANDS]; biquad filters_L[bands];
biquad filters_R[BANDS]; biquad filters_R[bands];
inline void inline void
process2(v2df *buf, ulong rem) process2(v2df *buf, ulong rem)
@ -32,7 +29,7 @@ struct Crap_eq
biquad *f0, *f1; biquad *f0, *f1;
f0 = filters_L; f0 = filters_L;
f1 = filters_R; f1 = filters_R;
for (ulong i = 0; i < BANDS; i++) { for (ulong i = 0; i < bands; i++) {
biquad_run_block_stereo(f0, f1, buf, rem); biquad_run_block_stereo(f0, f1, buf, rem);
f0++; f0++;
f1++; f1++;
@ -46,7 +43,7 @@ struct Crap_eq
inline void inline void
resume() resume()
{ {
for (int i = 0; i < BANDS; i++) { for (int i = 0; i < bands; i++) {
biquad_init(&filters_L[i]); biquad_init(&filters_L[i]);
biquad_init(&filters_R[i]); biquad_init(&filters_R[i]);
} }
@ -55,7 +52,7 @@ struct Crap_eq
static inline void static inline void
construct_params(Param *params) construct_params(Param *params)
{ {
for (int i = 0; i < BANDS; i++) { for (int i = 0; i < bands; i++) {
sprintf(params[0].name, "Band %i Frequency", i + 1); sprintf(params[0].name, "Band %i Frequency", i + 1);
params[0].min = 20; params[0].min = 20;
params[0].max = 20000; params[0].max = 20000;
@ -84,7 +81,7 @@ struct Crap_eq
inline void inline void
adjust_all(Param *params) adjust_all(Param *params)
{ {
for (int i = 0; i < BANDS; i++) { for (int i = 0; i < bands; i++) {
filters_L[i] = biquad_gen(FILT_PEAKING, filters_L[i] = biquad_gen(FILT_PEAKING,
params[0].value, params[1].value, params[2].value, (double) fs); params[0].value, params[1].value, params[2].value, (double) fs);
params += 3; params += 3;

View File

@ -1,5 +1,3 @@
#define PARAMETERS 0
#define BLOCK_SIZE 256 #define BLOCK_SIZE 256
#include <string.h> #include <string.h>

View File

@ -8,88 +8,42 @@
#define PARAM_NAME_LEN 24 #define PARAM_NAME_LEN 24
#endif #endif
#define PLUG_INPUT_L 0 enum {
#define PLUG_INPUT_R 1 PLUG_INPUT_L,
#define PLUG_OUTPUT_L 2 PLUG_INPUT_R,
#define PLUG_OUTPUT_R 3 PLUG_OUTPUT_L,
#define PCOUNT (PARAMETERS + 4) PLUG_OUTPUT_R,
IO_PLUGS
// LADSPA is a jerk and won't let us initialize anything };
// before asking for a descriptor.
// in reality we could use a crap-ton of constexprs,
// but i just need something functional for now
static void __attribute__ ((constructor)) plug_init();
static void __attribute__ ((destructor)) plug_cleanup();
#define ALLOC(type, amount) (type *) calloc(amount, sizeof(type)) #define ALLOC(type, amount) (type *) calloc(amount, sizeof(type))
char p_default_strings[4][PARAM_NAME_LEN + 1] = { char p_default_strings[IO_PLUGS][PARAM_NAME_LEN + 1] = {
"Input L", "Input R", "Input L", "Input R",
"Output L", "Output R" "Output L", "Output R"
}; };
LADSPA_PortDescriptor p_descs[PCOUNT]; int
LADSPA_PortRangeHint p_hints[PCOUNT]; param2hint(Param *p)
static Param *global_params;
char **p_name_strings;
char *p_names[PCOUNT];
static void
plug_cleanup()
{ {
for (int i = 0; i < PARAMETERS; i++) { int hint = LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
free(p_name_strings[i]); if (p->scale == SCALE_INT) hint |= LADSPA_HINT_INTEGER;
} if (p->scale == SCALE_TOGGLE) hint |= LADSPA_HINT_TOGGLED;
free(p_name_strings); if (p->scale >= SCALE_LOG) hint |= LADSPA_HINT_LOGARITHMIC;
free(global_params);
}
static void switch (p->def) {
plug_init() case DEFAULT_0: hint |= LADSPA_HINT_DEFAULT_0; break;
{ case DEFAULT_1: hint |= LADSPA_HINT_DEFAULT_1; break;
for (int i = 0; i < 4; i++) { case DEFAULT_100: hint |= LADSPA_HINT_DEFAULT_100; break;
p_names[i] = p_default_strings[i]; case DEFAULT_440: hint |= LADSPA_HINT_DEFAULT_440; break;
p_descs[i] = LADSPA_PORT_AUDIO; case DEFAULT_MIN: hint |= LADSPA_HINT_DEFAULT_MINIMUM; break;
p_descs[i] |= (i < 2) ? LADSPA_PORT_INPUT : LADSPA_PORT_OUTPUT; case DEFAULT_LOW: hint |= LADSPA_HINT_DEFAULT_LOW; break;
p_hints[i] = (LADSPA_PortRangeHint){.HintDescriptor = 0}; case DEFAULT_HIGH: hint |= LADSPA_HINT_DEFAULT_HIGH; break;
case DEFAULT_MAX: hint |= LADSPA_HINT_DEFAULT_MAXIMUM; break;
case DEFAULT_HALF: hint |= LADSPA_HINT_DEFAULT_MIDDLE; break;
} }
global_params = ALLOC(Param, PARAMETERS); return hint;
p_name_strings = ALLOC(char *, PARAMETERS);
CrapPlug::construct_params(global_params);
for (int i = 0; i < PARAMETERS; i++) {
p_name_strings[i] = ALLOC(char, PARAM_NAME_LEN + 1);
int j = i + 4;
Param *p = &global_params[i];
memcpy(p_name_strings[i], p->name, PARAM_NAME_LEN + 1);
p_names[j] = p_name_strings[i];
p_descs[j] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
int hint = LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
p_hints[j].LowerBound = p->min;
p_hints[j].UpperBound = p->max;
if (p->scale == SCALE_INT) hint |= LADSPA_HINT_INTEGER;
if (p->scale == SCALE_TOGGLE) hint |= LADSPA_HINT_TOGGLED;
if (p->scale >= SCALE_LOG) hint |= LADSPA_HINT_LOGARITHMIC;
switch (p->def) {
case DEFAULT_0: hint |= LADSPA_HINT_DEFAULT_0; break;
case DEFAULT_1: hint |= LADSPA_HINT_DEFAULT_1; break;
case DEFAULT_100: hint |= LADSPA_HINT_DEFAULT_100; break;
case DEFAULT_440: hint |= LADSPA_HINT_DEFAULT_440; break;
case DEFAULT_MIN: hint |= LADSPA_HINT_DEFAULT_MINIMUM; break;
case DEFAULT_LOW: hint |= LADSPA_HINT_DEFAULT_LOW; break;
case DEFAULT_HIGH: hint |= LADSPA_HINT_DEFAULT_HIGH; break;
case DEFAULT_MAX: hint |= LADSPA_HINT_DEFAULT_MAXIMUM; break;
case DEFAULT_HALF: hint |= LADSPA_HINT_DEFAULT_MIDDLE; break;
}
p_hints[j].HintDescriptor = hint;
}
} }
struct plug_t { struct plug_t {
@ -105,15 +59,45 @@ struct plug_t {
TEMPLATE TEMPLATE
struct LADSPA_Plugin : public T { struct LADSPA_Plugin : public T {
static Param default_params[T::parameters];
static LADSPA_PortDescriptor descs[IO_PLUGS + T::parameters];
static LADSPA_PortRangeHint hints[IO_PLUGS + T::parameters];
static char names[IO_PLUGS + T::parameters][PARAM_NAME_LEN + 1];
static void
init()
{
for (int i = 0; i < IO_PLUGS; i++) {
memcpy(names[i], p_default_strings[i], PARAM_NAME_LEN + 1);
descs[i] = LADSPA_PORT_AUDIO;
descs[i] |= (i < 2) ? LADSPA_PORT_INPUT : LADSPA_PORT_OUTPUT;
hints[i] = (LADSPA_PortRangeHint){.HintDescriptor = 0};
}
T::construct_params(default_params);
for (int i = 0; i < T::parameters; i++) {
int j = i + IO_PLUGS;
Param *p = &default_params[i];
memcpy(names[j], p->name, PARAM_NAME_LEN + 1);
descs[j] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
hints[j].LowerBound = p->min;
hints[j].UpperBound = p->max;
hints[j].HintDescriptor = param2hint(p);
}
};
static LADSPA_Handle static LADSPA_Handle
plug_construct(const LADSPA_Descriptor *descriptor, unsigned long fs) plug_construct(const LADSPA_Descriptor *descriptor, unsigned long fs)
{ {
plug_t *plug = ALLOC(plug_t, 1); plug_t *plug = ALLOC(plug_t, 1);
plug->crap = new CrapPlug(); plug->crap = new T();
if (T::parameters > 0) { if (T::parameters > 0) {
plug->values = ALLOC(LADSPA_Data *, T::parameters); plug->values = ALLOC(LADSPA_Data *, T::parameters);
plug->params = ALLOC(Param, T::parameters); plug->params = ALLOC(Param, T::parameters);
memcpy(plug->params, global_params, sizeof(Param)*T::parameters); memcpy(plug->params, default_params, sizeof(Param)*T::parameters);
plug->crap->adjust(plug->params, fs); plug->crap->adjust(plug->params, fs);
} else { } else {
plug->crap->adjust(NULL, fs); plug->crap->adjust(NULL, fs);
@ -143,8 +127,8 @@ struct LADSPA_Plugin : public T {
plug->output_L = data; plug->output_L = data;
else if (port == PLUG_OUTPUT_R) else if (port == PLUG_OUTPUT_R)
plug->output_R = data; plug->output_R = data;
else if (T::parameters > 0 && port < T::parameters + 4) else if (T::parameters > 0 && port < T::parameters + IO_PLUGS)
plug->values[port - 4] = data; plug->values[port - IO_PLUGS] = data;
} }
static void static void
@ -180,8 +164,14 @@ struct LADSPA_Plugin : public T {
} }
}; };
TEMPLATE static constexpr TEMPLATE Param LADSPA_Plugin<T>::default_params[T::parameters];
TEMPLATE LADSPA_PortDescriptor LADSPA_Plugin<T>::descs[IO_PLUGS + T::parameters];
TEMPLATE LADSPA_PortRangeHint LADSPA_Plugin<T>::hints[IO_PLUGS + T::parameters];
TEMPLATE char LADSPA_Plugin<T>::names[IO_PLUGS + T::parameters][PARAM_NAME_LEN + 1];
TEMPLATE static
LADSPA_Descriptor gen_desc() { LADSPA_Descriptor gen_desc() {
T::init();
return LADSPA_Descriptor { return LADSPA_Descriptor {
.UniqueID = T::id, .UniqueID = T::id,
.Label = T::label, .Label = T::label,
@ -189,10 +179,10 @@ LADSPA_Descriptor gen_desc() {
.Name = T::name, .Name = T::name,
.Maker = T::author, .Maker = T::author,
.Copyright = T::copyright, .Copyright = T::copyright,
.PortCount = 4 + T::parameters, .PortCount = IO_PLUGS + T::parameters,
.PortDescriptors = p_descs, .PortDescriptors = T::descs,
.PortRangeHints = p_hints, .PortRangeHints = T::hints,
.PortNames = (const char * const *) p_names, .PortNames = (const char * const *) T::names,
.instantiate = T::plug_construct, .instantiate = T::plug_construct,
.cleanup = T::plug_destruct, .cleanup = T::plug_destruct,
@ -205,7 +195,7 @@ LADSPA_Descriptor gen_desc() {
}; };
} }
static constexpr LADSPA_Descriptor plug_descs[] = { static LADSPA_Descriptor plug_descs[] = {
gen_desc<LADSPA_Plugin<CrapPlug>>() gen_desc<LADSPA_Plugin<CrapPlug>>()
}; };