summaryrefslogtreecommitdiff
path: root/libs/plugins
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-07-14 20:42:07 +0200
committerRobin Gareus <robin@gareus.org>2016-07-14 20:44:47 +0200
commit2b262dbfdd25808471244ddc0edede34f8230231 (patch)
tree62f6d3f70d87cf3cdea1074452b1ef024b45cdc3 /libs/plugins
parentb620e5ab3fe49e96445f76af48dc88d445b10363 (diff)
fix a-eq interpolation
Diffstat (limited to 'libs/plugins')
-rw-r--r--libs/plugins/a-eq.lv2/a-eq.c106
1 files changed, 66 insertions, 40 deletions
diff --git a/libs/plugins/a-eq.lv2/a-eq.c b/libs/plugins/a-eq.lv2/a-eq.c
index a539c90825..bb9840d601 100644
--- a/libs/plugins/a-eq.lv2/a-eq.c
+++ b/libs/plugins/a-eq.lv2/a-eq.c
@@ -32,8 +32,6 @@
#define AEQ_URI "urn:ardour:a-eq"
#define BANDS 6
-#define SMALL 0.0001f
-
#ifndef MIN
#define MIN(A,B) ((A) < (B)) ? (A) : (B)
#endif
@@ -77,8 +75,8 @@ from_dB(double gdb) {
}
static inline bool
-is_eq(float a, float b) {
- return (fabsf(a - b) < SMALL);
+is_eq(float a, float b, float small) {
+ return (fabsf(a - b) < small);
}
struct linear_svf {
@@ -101,6 +99,7 @@ typedef struct {
float* master;
float srate;
+ float tau;
float* input;
float* output;
@@ -109,7 +108,6 @@ typedef struct {
float v_g[BANDS];
float v_bw[BANDS];
float v_f0[BANDS];
- float v_filtog[BANDS];
float v_master;
bool need_expose;
@@ -130,6 +128,7 @@ instantiate(const LV2_Descriptor* descriptor,
{
Aeq* aeq = (Aeq*)calloc(1, sizeof(Aeq));
aeq->srate = rate;
+ aeq->tau = (1.0 - exp(-2.0 * M_PI * 64 * 25. / aeq->srate)); // 25Hz time constant @ 64fpp
#ifdef LV2_EXTENDED
for (int i=0; features[i]; ++i) {
@@ -353,51 +352,78 @@ run(LV2_Handle instance, uint32_t n_samples)
const float* const input = aeq->input;
float* const output = aeq->output;
- float in0, out;
- uint32_t i, j;
+ const float tau = aeq->tau;
+ uint32_t offset = 0;
- // 15Hz time constant
- const float tau = (1.0 - exp(-2.0 * M_PI * n_samples * 15. / aeq->srate));
+ while (n_samples > 0) {
+ uint32_t block = n_samples;
+ bool any_changed = false;
- for (i = 0; i < n_samples; i++) {
- in0 = input[i];
- out = in0;
- for (j = 0; j < BANDS; j++) {
- out = run_linear_svf(&aeq->v_filter[j], out);
+ // TODO global en/disable
+ if (!is_eq(aeq->v_master, *aeq->master, 0.1)) {
+ aeq->v_master += tau * (*aeq->master - aeq->v_master);
+ any_changed = true;
+ } else {
+ aeq->v_master = *aeq->master;
}
- output[i] = out * from_dB(*(aeq->master));
- }
- for (i = 0; i < BANDS; i++) {
- if (!is_eq(aeq->v_filtog[i], *aeq->filtog[i])) {
- aeq->v_filtog[i] = *(aeq->filtog[i]);
- }
- if (!is_eq(aeq->v_f0[i], *aeq->f0[i])) {
- aeq->v_f0[i] += tau * (*aeq->f0[i] - aeq->v_f0[i]);
- aeq->need_expose = true;
- }
- if (aeq->v_filtog[i] < 0.5) {
- if (!is_eq(aeq->v_g[i], 0.f)) {
- aeq->v_g[i] += tau * (0.0 - aeq->v_g[i]);
- aeq->need_expose = true;
+ for (int i = 0; i < BANDS; ++i) {
+ bool changed = false;
+
+ if (!is_eq(aeq->v_f0[i], *aeq->f0[i], 0.1)) {
+ aeq->v_f0[i] += tau * (*aeq->f0[i] - aeq->v_f0[i]);
+ changed = true;
+ } else {
+ aeq->v_f0[i] = *aeq->f0[i];
}
- } else if (aeq->v_filtog[i] >= 0.5) {
- if (!is_eq(aeq->v_g[i], *aeq->g[i])) {
- aeq->v_g[i] += tau * (*aeq->g[i] - aeq->v_g[i]);
- aeq->need_expose = true;
+
+ if (*aeq->filtog[i] <= 0) {
+ if (!is_eq(aeq->v_g[i], 0.f, 0.05)) {
+ aeq->v_g[i] += tau * (0.0 - aeq->v_g[i]);
+ changed = true;
+ } else {
+ aeq->v_g[i] = 0.0;
+ }
+ } else {
+ if (!is_eq(aeq->v_g[i], *aeq->g[i], 0.05)) {
+ aeq->v_g[i] += tau * (*aeq->g[i] - aeq->v_g[i]);
+ changed = true;
+ } else {
+ aeq->v_g[i] = *aeq->g[i];
+ }
+ }
+
+ if (i != 0 && i != 5) {
+ if (!is_eq(aeq->v_bw[i], *aeq->bw[i], 0.001)) {
+ aeq->v_bw[i] += tau * (*aeq->bw[i] - aeq->v_bw[i]);
+ changed = true;
+ } else {
+ aeq->v_bw[i] = *aeq->bw[i];
+ }
+ }
+
+ if (changed) {
+ set_params(aeq, i);
+ any_changed = true;
}
}
- if (i != 0 && i != 5 && !is_eq(aeq->v_bw[i], *aeq->bw[i])) {
- aeq->v_bw[i] += tau * (*aeq->bw[i] - aeq->v_bw[i]);
- aeq->need_expose = true;
- }
- if (!is_eq(aeq->v_master, *aeq->master)) {
- aeq->v_master = *(aeq->master);
+
+ if (any_changed) {
aeq->need_expose = true;
+ block = MIN (64, n_samples);
}
- if (aeq->need_expose == true) {
- set_params(aeq, i);
+
+ for (uint32_t i = 0; i < block; ++i) {
+ float in0, out;
+ in0 = input[i + offset];
+ out = in0;
+ for (uint32_t j = 0; j < BANDS; j++) {
+ out = run_linear_svf(&aeq->v_filter[j], out);
+ }
+ output[i + offset] = out * from_dB(*(aeq->master));
}
+ n_samples -= block;
+ offset += block;
}
#ifdef LV2_EXTENDED