click-free a-reverb bypass
authorRobin Gareus <robin@gareus.org>
Sat, 27 Aug 2016 12:09:47 +0000 (14:09 +0200)
committerRobin Gareus <robin@gareus.org>
Sat, 27 Aug 2016 12:09:47 +0000 (14:09 +0200)
libs/plugins/a-reverb.lv2/a-reverb.c
libs/plugins/a-reverb.lv2/a-reverb.ttl.in

index e2dd969bd6454d99df368c0ae24a44bc37e46414..ed4a2474068c32feed71631dd624c6057813d7e4 100644 (file)
@@ -239,6 +239,7 @@ typedef enum {
        AR_OUTPUT1    = 3,
        AR_MIX        = 4,
        AR_ROOMSZ     = 5,
+       AR_ENABLE     = 6,
 } PortIndex;
 
 typedef struct {
@@ -249,10 +250,12 @@ typedef struct {
 
        float* mix;
        float* roomsz;
+       float* enable;
 
        float v_mix;
        float v_roomsz;
        float srate;
+       float tau;
 
        b_reverb r;
 } AReverb;
@@ -275,6 +278,7 @@ instantiate (const LV2_Descriptor*     descriptor,
        self->v_roomsz = 0.75;
        self->v_mix = 0.1;
        self->srate = rate;
+       self->tau = 1.f - expf (-2.f * M_PI * 64.f * 15.f / self->srate); // 15Hz, 64fpp
 
        return (LV2_Handle)self;
 }
@@ -305,6 +309,9 @@ connect_port (LV2_Handle instance,
                case AR_ROOMSZ:
                        self->roomsz = (float*)data;
                        break;
+               case AR_ENABLE:
+                       self->enable = (float*)data;
+                       break;
        }
 }
 
@@ -318,23 +325,52 @@ run (LV2_Handle instance, uint32_t n_samples)
        float* const      output0 = self->output0;
        float* const      output1 = self->output1;
 
-       // 15Hz time constant
-       const float tau = (1.0 - exp(-2.0 * M_PI * n_samples * 15. / self->srate));
+       const float tau = self->tau;
+       const float mix = *self->enable <= 0 ? 0 : *self->mix;
+
+       uint32_t remain = n_samples;
+       uint32_t offset = 0;
+       uint32_t iterpolate = 0;
 
-       if (*self->mix != self->v_mix) {
-               self->v_mix += tau * ( *self->mix - self->v_mix);
-               self->r.wet = self->v_mix;
-               self->r.dry = 1.0 - self->v_mix;
+       if (fabsf (mix - self->v_mix) < .01) { // 40dB
+               self->v_mix = mix;
+       } else {
+               iterpolate |= 1;
        }
-       if (*self->roomsz != self->v_roomsz) {
-               self->v_roomsz += tau * ( *self->roomsz - self->v_roomsz);
-               self->r.gain[0] = 0.773 * self->v_roomsz;
-               self->r.gain[1] = 0.802 * self->v_roomsz;
-               self->r.gain[2] = 0.753 * self->v_roomsz;
-               self->r.gain[3] = 0.733 * self->v_roomsz;
+
+       if (fabsf (*self->roomsz  - self->v_roomsz) < .01) {
+               self->v_roomsz = *self->roomsz;
+       } else {
+               iterpolate |= 2;
        }
 
-       reverb (&self->r, input0, input1, output0, output1, n_samples);
+       while (remain > 0) {
+               uint32_t p_samples = remain;
+               if (iterpolate && p_samples > 64) {
+                       p_samples = 64;
+               }
+
+               if (iterpolate & 1) {
+                       self->v_mix += tau * (mix - self->v_mix);
+                       self->r.wet = self->v_mix;
+                       self->r.dry = 1.0 - self->v_mix;
+               }
+               if (iterpolate & 2) {
+                       self->v_roomsz += tau * ( *self->roomsz - self->v_roomsz);
+                       self->r.gain[0] = 0.773 * self->v_roomsz;
+                       self->r.gain[1] = 0.802 * self->v_roomsz;
+                       self->r.gain[2] = 0.753 * self->v_roomsz;
+                       self->r.gain[3] = 0.733 * self->v_roomsz;
+               }
+
+               reverb (&self->r,
+                               &input0[offset], &input1[offset],
+                               &output0[offset], &output1[offset],
+                               p_samples);
+
+               offset += p_samples;
+               remain -= p_samples;
+       }
 }
 
 static void
index 2f51d49487fe7001f30c672ca06ac9b15f2e0893..f6eb567464774707b487edc27bae092a5ae57e2f 100644 (file)
                lv2:default 0.5 ;
                lv2:minimum 0.5 ;
                lv2:maximum 1.0 ;
-       ] .
+       ],
+       [
+               a lv2:InputPort, lv2:ControlPort ;
+               lv2:index 6 ;
+               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>;
+       ];