Add automatable click-free bypass/enable feature to a-eq
This commit is contained in:
parent
094d08dc2b
commit
935fd3b32f
@ -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 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 = 4; h.y1 = 6; break; // Master Gain
|
||||
case 16: h.x0 = 14; h.x1 = 15; h.y0 = 1; h.y1 = 3; break; // Master Gain
|
||||
case 23: h.x0 = 14; h.x1 = 15; h.y0 = 5; h.y1 = 6; break; // Master Enable
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ typedef enum {
|
||||
AEQ_FILTOG3,
|
||||
AEQ_FILTOG4,
|
||||
AEQ_FILTOGH,
|
||||
AEQ_ENABLE,
|
||||
AEQ_INPUT,
|
||||
AEQ_OUTPUT,
|
||||
} PortIndex;
|
||||
@ -97,6 +98,7 @@ typedef struct {
|
||||
float* bw[BANDS];
|
||||
float* filtog[BANDS];
|
||||
float* master;
|
||||
float* enable;
|
||||
|
||||
float srate;
|
||||
float tau;
|
||||
@ -128,7 +130,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
|
||||
aeq->tau = 1.0 - expf (-2.f * M_PI * 64.f * 25.f / aeq->srate); // 25Hz time constant @ 64fpp
|
||||
|
||||
#ifdef LV2_EXTENDED
|
||||
for (int i=0; features[i]; ++i) {
|
||||
@ -157,6 +159,9 @@ connect_port(LV2_Handle instance,
|
||||
Aeq* aeq = (Aeq*)instance;
|
||||
|
||||
switch ((PortIndex)port) {
|
||||
case AEQ_ENABLE:
|
||||
aeq->enable = (float*)data;
|
||||
break;
|
||||
case AEQ_FREQL:
|
||||
aeq->f0[0] = (float*)data;
|
||||
break;
|
||||
@ -355,16 +360,17 @@ run(LV2_Handle instance, uint32_t n_samples)
|
||||
const float tau = aeq->tau;
|
||||
uint32_t offset = 0;
|
||||
|
||||
const float target_gain = *aeq->enable <= 0 ? 0 : *aeq->master; // dB
|
||||
|
||||
while (n_samples > 0) {
|
||||
uint32_t block = n_samples;
|
||||
bool any_changed = false;
|
||||
|
||||
// TODO global en/disable
|
||||
if (!is_eq(aeq->v_master, *aeq->master, 0.1)) {
|
||||
aeq->v_master += tau * (*aeq->master - aeq->v_master);
|
||||
if (!is_eq(aeq->v_master, target_gain, 0.1)) {
|
||||
aeq->v_master += tau * (target_gain - aeq->v_master);
|
||||
any_changed = true;
|
||||
} else {
|
||||
aeq->v_master = *aeq->master;
|
||||
aeq->v_master = target_gain;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
if (*aeq->filtog[i] <= 0) {
|
||||
if (*aeq->filtog[i] <= 0 || *aeq->enable <= 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;
|
||||
@ -420,7 +426,7 @@ run(LV2_Handle instance, uint32_t n_samples)
|
||||
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));
|
||||
output[i + offset] = out * from_dB(aeq->v_master);
|
||||
}
|
||||
n_samples -= block;
|
||||
offset += block;
|
||||
|
@ -264,18 +264,29 @@ unit:hz0
|
||||
lv2:minimum 0.000000 ;
|
||||
lv2:maximum 1.000000 ;
|
||||
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 [
|
||||
a lv2:InputPort, lv2:AudioPort ;
|
||||
lv2:index 23 ;
|
||||
lv2:index 24 ;
|
||||
lv2:symbol "in_1" ;
|
||||
lv2:name "Audio Input 1" ;
|
||||
] ;
|
||||
|
||||
lv2:port [
|
||||
a lv2:OutputPort, lv2:AudioPort ;
|
||||
lv2:index 24 ;
|
||||
lv2:index 25 ;
|
||||
lv2:symbol "out_1" ;
|
||||
lv2:name "Audio Output 1" ;
|
||||
] ;
|
||||
|
Loading…
Reference in New Issue
Block a user