Add automatable click-free bypass/enable feature to a-eq

This commit is contained in:
Robin Gareus 2016-08-27 13:23:25 +02:00
parent 094d08dc2b
commit 935fd3b32f
3 changed files with 29 additions and 12 deletions

View file

@ -1095,8 +1095,8 @@ LV2Plugin::get_layout (uint32_t which, UILayoutHint& h) const
case 15: h.x0 = 13; h.x1 = 14; h.y0 = 0; h.y1 = 1; break; // Gain H case 15: h.x0 = 13; h.x1 = 14; h.y0 = 0; h.y1 = 1; break; // Gain H
case 22: h.x0 = 13; h.x1 = 14; h.y0 = 5; h.y1 = 6; break; // enable H case 22: h.x0 = 13; h.x1 = 14; h.y0 = 5; h.y1 = 6; break; // enable H
case 16: h.x0 = 14; h.x1 = 15; h.y0 = 1; h.y1 = 3; break; // Master Gain
case 16: h.x0 = 14; h.x1 = 15; h.y0 = 4; h.y1 = 6; break; // Master Gain case 23: h.x0 = 14; h.x1 = 15; h.y0 = 5; h.y1 = 6; break; // Master Enable
default: default:
return false; return false;
} }

View file

@ -60,6 +60,7 @@ typedef enum {
AEQ_FILTOG3, AEQ_FILTOG3,
AEQ_FILTOG4, AEQ_FILTOG4,
AEQ_FILTOGH, AEQ_FILTOGH,
AEQ_ENABLE,
AEQ_INPUT, AEQ_INPUT,
AEQ_OUTPUT, AEQ_OUTPUT,
} PortIndex; } PortIndex;
@ -97,6 +98,7 @@ typedef struct {
float* bw[BANDS]; float* bw[BANDS];
float* filtog[BANDS]; float* filtog[BANDS];
float* master; float* master;
float* enable;
float srate; float srate;
float tau; float tau;
@ -128,7 +130,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 aeq->tau = 1.0 - expf (-2.f * M_PI * 64.f * 25.f / 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) {
@ -157,6 +159,9 @@ connect_port(LV2_Handle instance,
Aeq* aeq = (Aeq*)instance; Aeq* aeq = (Aeq*)instance;
switch ((PortIndex)port) { switch ((PortIndex)port) {
case AEQ_ENABLE:
aeq->enable = (float*)data;
break;
case AEQ_FREQL: case AEQ_FREQL:
aeq->f0[0] = (float*)data; aeq->f0[0] = (float*)data;
break; break;
@ -355,16 +360,17 @@ run(LV2_Handle instance, uint32_t n_samples)
const float tau = aeq->tau; const float tau = aeq->tau;
uint32_t offset = 0; uint32_t offset = 0;
const float target_gain = *aeq->enable <= 0 ? 0 : *aeq->master; // dB
while (n_samples > 0) { while (n_samples > 0) {
uint32_t block = n_samples; uint32_t block = n_samples;
bool any_changed = false; bool any_changed = false;
// TODO global en/disable if (!is_eq(aeq->v_master, target_gain, 0.1)) {
if (!is_eq(aeq->v_master, *aeq->master, 0.1)) { aeq->v_master += tau * (target_gain - aeq->v_master);
aeq->v_master += tau * (*aeq->master - aeq->v_master);
any_changed = true; any_changed = true;
} else { } else {
aeq->v_master = *aeq->master; aeq->v_master = target_gain;
} }
for (int i = 0; i < BANDS; ++i) { for (int i = 0; i < BANDS; ++i) {
@ -377,7 +383,7 @@ run(LV2_Handle instance, uint32_t n_samples)
aeq->v_f0[i] = *aeq->f0[i]; aeq->v_f0[i] = *aeq->f0[i];
} }
if (*aeq->filtog[i] <= 0) { if (*aeq->filtog[i] <= 0 || *aeq->enable <= 0) {
if (!is_eq(aeq->v_g[i], 0.f, 0.05)) { if (!is_eq(aeq->v_g[i], 0.f, 0.05)) {
aeq->v_g[i] += tau * (0.0 - aeq->v_g[i]); aeq->v_g[i] += tau * (0.0 - aeq->v_g[i]);
changed = true; changed = true;
@ -420,7 +426,7 @@ run(LV2_Handle instance, uint32_t n_samples)
for (uint32_t j = 0; j < BANDS; j++) { for (uint32_t j = 0; j < BANDS; j++) {
out = run_linear_svf(&aeq->v_filter[j], out); out = run_linear_svf(&aeq->v_filter[j], out);
} }
output[i + offset] = out * from_dB(*(aeq->master)); output[i + offset] = out * from_dB(aeq->v_master);
} }
n_samples -= block; n_samples -= block;
offset += block; offset += block;

View file

@ -264,18 +264,29 @@ unit:hz0
lv2:minimum 0.000000 ; lv2:minimum 0.000000 ;
lv2:maximum 1.000000 ; lv2:maximum 1.000000 ;
lv2:portProperty lv2:toggled ; lv2:portProperty lv2:toggled ;
] ; ],
[
a lv2:InputPort, lv2:ControlPort ;
lv2:index 23 ;
lv2:name "Enable" ;
lv2:symbol "enable" ;
lv2:default 1 ;
lv2:minimum 0 ;
lv2:maximum 1 ;
lv2:portProperty lv2:integer, lv2:toggled ;
lv2:designation <http://ardour.org/lv2/processing#enable>;
];
lv2:port [ lv2:port [
a lv2:InputPort, lv2:AudioPort ; a lv2:InputPort, lv2:AudioPort ;
lv2:index 23 ; lv2:index 24 ;
lv2:symbol "in_1" ; lv2:symbol "in_1" ;
lv2:name "Audio Input 1" ; lv2:name "Audio Input 1" ;
] ; ] ;
lv2:port [ lv2:port [
a lv2:OutputPort, lv2:AudioPort ; a lv2:OutputPort, lv2:AudioPort ;
lv2:index 24 ; lv2:index 25 ;
lv2:symbol "out_1" ; lv2:symbol "out_1" ;
lv2:name "Audio Output 1" ; lv2:name "Audio Output 1" ;
] ; ] ;