mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 00:34:59 +01:00
fix a-eq interpolation
This commit is contained in:
parent
b620e5ab3f
commit
2b262dbfdd
1 changed files with 66 additions and 40 deletions
|
|
@ -32,8 +32,6 @@
|
||||||
|
|
||||||
#define AEQ_URI "urn:ardour:a-eq"
|
#define AEQ_URI "urn:ardour:a-eq"
|
||||||
#define BANDS 6
|
#define BANDS 6
|
||||||
#define SMALL 0.0001f
|
|
||||||
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(A,B) ((A) < (B)) ? (A) : (B)
|
#define MIN(A,B) ((A) < (B)) ? (A) : (B)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -77,8 +75,8 @@ from_dB(double gdb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
is_eq(float a, float b) {
|
is_eq(float a, float b, float small) {
|
||||||
return (fabsf(a - b) < SMALL);
|
return (fabsf(a - b) < small);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct linear_svf {
|
struct linear_svf {
|
||||||
|
|
@ -101,6 +99,7 @@ typedef struct {
|
||||||
float* master;
|
float* master;
|
||||||
|
|
||||||
float srate;
|
float srate;
|
||||||
|
float tau;
|
||||||
|
|
||||||
float* input;
|
float* input;
|
||||||
float* output;
|
float* output;
|
||||||
|
|
@ -109,7 +108,6 @@ typedef struct {
|
||||||
float v_g[BANDS];
|
float v_g[BANDS];
|
||||||
float v_bw[BANDS];
|
float v_bw[BANDS];
|
||||||
float v_f0[BANDS];
|
float v_f0[BANDS];
|
||||||
float v_filtog[BANDS];
|
|
||||||
float v_master;
|
float v_master;
|
||||||
|
|
||||||
bool need_expose;
|
bool need_expose;
|
||||||
|
|
@ -130,6 +128,7 @@ instantiate(const LV2_Descriptor* descriptor,
|
||||||
{
|
{
|
||||||
Aeq* aeq = (Aeq*)calloc(1, sizeof(Aeq));
|
Aeq* aeq = (Aeq*)calloc(1, sizeof(Aeq));
|
||||||
aeq->srate = rate;
|
aeq->srate = rate;
|
||||||
|
aeq->tau = (1.0 - exp(-2.0 * M_PI * 64 * 25. / aeq->srate)); // 25Hz time constant @ 64fpp
|
||||||
|
|
||||||
#ifdef LV2_EXTENDED
|
#ifdef LV2_EXTENDED
|
||||||
for (int i=0; features[i]; ++i) {
|
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;
|
const float* const input = aeq->input;
|
||||||
float* const output = aeq->output;
|
float* const output = aeq->output;
|
||||||
|
|
||||||
float in0, out;
|
const float tau = aeq->tau;
|
||||||
uint32_t i, j;
|
uint32_t offset = 0;
|
||||||
|
|
||||||
// 15Hz time constant
|
while (n_samples > 0) {
|
||||||
const float tau = (1.0 - exp(-2.0 * M_PI * n_samples * 15. / aeq->srate));
|
uint32_t block = n_samples;
|
||||||
|
bool any_changed = false;
|
||||||
|
|
||||||
for (i = 0; i < n_samples; i++) {
|
// TODO global en/disable
|
||||||
in0 = input[i];
|
if (!is_eq(aeq->v_master, *aeq->master, 0.1)) {
|
||||||
out = in0;
|
aeq->v_master += tau * (*aeq->master - aeq->v_master);
|
||||||
for (j = 0; j < BANDS; j++) {
|
any_changed = true;
|
||||||
out = run_linear_svf(&aeq->v_filter[j], out);
|
} else {
|
||||||
|
aeq->v_master = *aeq->master;
|
||||||
}
|
}
|
||||||
output[i] = out * from_dB(*(aeq->master));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < BANDS; i++) {
|
for (int i = 0; i < BANDS; ++i) {
|
||||||
if (!is_eq(aeq->v_filtog[i], *aeq->filtog[i])) {
|
bool changed = false;
|
||||||
aeq->v_filtog[i] = *(aeq->filtog[i]);
|
|
||||||
}
|
if (!is_eq(aeq->v_f0[i], *aeq->f0[i], 0.1)) {
|
||||||
if (!is_eq(aeq->v_f0[i], *aeq->f0[i])) {
|
aeq->v_f0[i] += tau * (*aeq->f0[i] - aeq->v_f0[i]);
|
||||||
aeq->v_f0[i] += tau * (*aeq->f0[i] - aeq->v_f0[i]);
|
changed = true;
|
||||||
aeq->need_expose = true;
|
} else {
|
||||||
}
|
aeq->v_f0[i] = *aeq->f0[i];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
} else if (aeq->v_filtog[i] >= 0.5) {
|
|
||||||
if (!is_eq(aeq->v_g[i], *aeq->g[i])) {
|
if (*aeq->filtog[i] <= 0) {
|
||||||
aeq->v_g[i] += tau * (*aeq->g[i] - aeq->v_g[i]);
|
if (!is_eq(aeq->v_g[i], 0.f, 0.05)) {
|
||||||
aeq->need_expose = true;
|
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]);
|
if (any_changed) {
|
||||||
aeq->need_expose = true;
|
aeq->need_expose = true;
|
||||||
|
block = MIN (64, n_samples);
|
||||||
}
|
}
|
||||||
if (!is_eq(aeq->v_master, *aeq->master)) {
|
|
||||||
aeq->v_master = *(aeq->master);
|
for (uint32_t i = 0; i < block; ++i) {
|
||||||
aeq->need_expose = true;
|
float in0, out;
|
||||||
}
|
in0 = input[i + offset];
|
||||||
if (aeq->need_expose == true) {
|
out = in0;
|
||||||
set_params(aeq, i);
|
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
|
#ifdef LV2_EXTENDED
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue