crap/util/bench.cpp

139 lines
2.9 KiB
C++
Raw Normal View History

2015-04-04 02:06:13 -07:00
#include <alloca.h>
2013-11-11 08:26:22 -08:00
#include <stdlib.h>
#include <stdio.h>
2013-11-11 08:26:22 -08:00
#include <assert.h>
#include <time.h>
2015-04-04 02:44:33 -07:00
#include <math.h>
2013-11-11 08:26:22 -08:00
#include "dlfcn.h"
2015-06-06 10:42:14 -07:00
#include "ladspa.hpp"
#include "util.hpp"
2013-11-11 08:26:22 -08:00
2015-06-10 23:53:13 -07:00
#define BENCH_BLOCK 2048
2013-11-11 08:26:22 -08:00
void *plug = NULL;
static float *audio_buffer;
static int audio_count = 0;
2013-11-11 08:26:22 -08:00
2015-04-04 06:48:27 -07:00
INNER void
2014-02-05 23:47:16 -08:00
cleanup()
{
2013-11-11 08:26:22 -08:00
dlclose(plug);
if (audio_count) free(audio_buffer);
2013-11-11 08:26:22 -08:00
}
2015-04-04 06:48:27 -07:00
INNER const LADSPA_Descriptor*
2014-02-05 23:47:16 -08:00
load_ladspa(char *path)
{
2013-11-11 08:26:22 -08:00
plug = dlopen(path, RTLD_NOW);
2015-06-07 13:22:26 -07:00
if (!plug) {
puts(dlerror());
exit(1);
}
2013-11-11 08:26:22 -08:00
atexit(cleanup);
2015-06-06 10:42:14 -07:00
LADSPA_Descriptor_Function df;
2015-06-06 17:25:18 -07:00
df = (decltype(df)) dlsym(plug, "ladspa_descriptor");
2015-06-07 13:22:26 -07:00
if (!df) {
puts(dlerror());
exit(1);
}
2013-11-11 08:26:22 -08:00
const LADSPA_Descriptor *d = df(0);
assert(d);
return d;
}
2015-04-04 06:48:27 -07:00
INNER float
2015-04-04 02:44:33 -07:00
between(float percent, float min, float max, int logscale)
{
if (logscale)
return log(min/percent)/log(min/max);
else
return (min - percent)/(min - max);
}
2015-04-04 06:48:27 -07:00
INNER float
2015-04-04 02:44:33 -07:00
get_default(LADSPA_PortRangeHint hint)
{
float x = 0;
int hd = hint.HintDescriptor;
float min = hint.LowerBound;
float max = hint.UpperBound;
float logscale = LADSPA_IS_HINT_LOGARITHMIC(hd);
if (LADSPA_IS_HINT_DEFAULT_0(hd))
x = 0;
if (LADSPA_IS_HINT_DEFAULT_1(hd))
x = 1;
if (LADSPA_IS_HINT_DEFAULT_100(hd))
x = 100;
if (LADSPA_IS_HINT_DEFAULT_440(hd))
x = 440;
if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hd))
x = min;
if (LADSPA_IS_HINT_DEFAULT_LOW(hd))
x = between(0.25, min, max, logscale);
if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hd))
x = between(0.50, min, max, logscale);
if (LADSPA_IS_HINT_DEFAULT_HIGH(hd))
x = between(0.75, min, max, logscale);
if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hd))
x = max;
if (LADSPA_IS_HINT_INTEGER(hd))
x = round(x);
if (LADSPA_IS_HINT_TOGGLED(hd)) {
float mid = between(0.50, min, max, logscale);
x = x >= mid ? max : min;
}
if (x < min) x = min;
if (x > max) x = max;
return x;
}
2013-11-11 08:26:22 -08:00
int
2014-02-05 23:47:16 -08:00
main(int argc, char **argv)
{
2015-06-07 13:22:26 -07:00
if (argc < 2) {
fprintf(stderr, "Please supply a path to the plugin to test.\n");
return 1;
}
2013-11-11 08:26:22 -08:00
const LADSPA_Descriptor *d = load_ladspa(argv[1]);
LADSPA_Handle h = d->instantiate(d, 44100);
assert(h);
// we're lazy so we don't distinguish inputs and outputs
for (int i = 0; i < d->PortCount; i++)
if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[i]))
audio_count++;
2015-06-10 23:53:13 -07:00
audio_buffer = (decltype(audio_buffer)) calloc(audio_count*BENCH_BLOCK, sizeof(float));
int a = 0;
2015-04-04 02:06:13 -07:00
for (int i = 0; i < d->PortCount; i++) {
if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[i])) {
2015-06-10 23:53:13 -07:00
d->connect_port(h, i, audio_buffer + a++*BENCH_BLOCK);
2015-04-04 02:06:13 -07:00
} else {
2015-06-06 10:42:14 -07:00
float *x;
2015-06-06 17:25:18 -07:00
x = (decltype(x)) alloca(sizeof(float));
2015-04-04 02:44:33 -07:00
*x = get_default(d->PortRangeHints[i]);
2015-04-04 02:06:13 -07:00
d->connect_port(h, i, x);
}
}
2013-11-11 08:26:22 -08:00
2015-06-08 11:44:06 -07:00
unsigned int mirand = time(NULL);
2015-06-10 23:53:13 -07:00
for (int i = 0; i < audio_count*BENCH_BLOCK; i++)
2015-06-08 11:44:06 -07:00
audio_buffer[i] = whitenoise(mirand);
2013-11-11 08:26:22 -08:00
if (d->activate) d->activate(h);
for (int i = 0; i < 64*64*8; i++)
2015-06-10 23:53:13 -07:00
d->run(h, BENCH_BLOCK);
2013-11-11 08:26:22 -08:00
if (d->deactivate) d->deactivate(h);
d->cleanup(h);
return 0;
}