Repeat INSENSITIVE colors instead of relying on inheritance
[ardour.git] / libs / plugins / a-delay.lv2 / a-delay.c
index 40fd05c51f6fddcc0635908de19cce889cd5edcf..8ad42655387f96fdb5852124965ed888f27f43a4 100644 (file)
@@ -42,6 +42,7 @@ typedef enum {
        ADELAY_TIME,
        ADELAY_DIVISOR,
        ADELAY_WETDRY,
+       ADELAY_FEEDBACK,
        ADELAY_LPF,
        ADELAY_GAIN,
        
@@ -73,6 +74,7 @@ typedef struct {
        float* time;
        float* divisor;
        float* wetdry;
+       float* feedback;
        float* lpf;
        float* gain;
        
@@ -81,7 +83,6 @@ typedef struct {
        float srate;
        float bpm;
        float beatunit;
-       int beatuniti;
        int bpmvalid;
 
        uint32_t posz;
@@ -91,6 +92,7 @@ typedef struct {
        int next;
        float fbstate;
        float lpfold;
+       float feedbackold;
        float divisorold;
        float gainold;
        float invertold;
@@ -99,6 +101,7 @@ typedef struct {
        float syncold;
        float wetdryold;
        float delaysamplesold;
+       float tau;
 
        float A0, A1, A2, A3, A4, A5;
        float B0, B1, B2, B3, B4, B5;
@@ -151,6 +154,8 @@ instantiate(const LV2_Descriptor* descriptor,
 
        adelay->srate = rate;
        adelay->bpmvalid = 0;
+       // 25Hz time constant @ 64fpp
+       adelay->tau = (1.0 - exp(-2.0 * M_PI * 64. * 25. / adelay->srate));
 
        return (LV2_Handle)adelay;
 }
@@ -187,6 +192,9 @@ connect_port(LV2_Handle instance,
        case ADELAY_WETDRY:
                adelay->wetdry = (float*)data;
                break;
+       case ADELAY_FEEDBACK:
+               adelay->feedback = (float*)data;
+               break;
        case ADELAY_LPF:
                adelay->lpf = (float*)data;
                break;
@@ -217,6 +225,11 @@ to_dB(float g) {
        return (20.f*log10(g));
 }
 
+static inline bool
+is_eq(float a, float b, float small) {
+       return (fabsf(a - b) < small);
+}
+
 static void clearfilter(LV2_Handle instance)
 {
        ADelay* adelay = (ADelay*)instance;
@@ -340,10 +353,11 @@ run(LV2_Handle instance, uint32_t n_samples)
        float* const output = adelay->output;
 
        float srate = adelay->srate;
+       float tau = adelay->tau;
 
        uint32_t i;
        float in;
-       int delaysamples;
+       int delaysamples = 0;
        unsigned int tmp;
        float inv;
        float xfade;
@@ -364,17 +378,22 @@ run(LV2_Handle instance, uint32_t n_samples)
        if (*(adelay->time) != adelay->timeold) {
                recalc = 1;
        }
+       if (*(adelay->feedback) != adelay->feedbackold) {
+               recalc = 1;
+       }
        if (*(adelay->divisor) != adelay->divisorold) {
                recalc = 1;
        }
-       if (*(adelay->lpf) != adelay->lpfold) {
-               lpfRbj(adelay, *(adelay->lpf), srate);
+       if (!is_eq(adelay->lpfold, *adelay->lpf, 0.1)) {
+               adelay->lpfold += tau * (*adelay->lpf - adelay->lpfold);
+               recalc = 1;
        }
        if (*(adelay->gain) != adelay->gainold) {
                recalc = 1;
        }
        
        if (recalc) {
+               lpfRbj(adelay, adelay->lpfold, srate);
                if (*(adelay->sync) > 0.5f && adelay->bpmvalid) {
                        *(adelay->delaytime) = adelay->beatunit * 1000.f * 60.f / (adelay->bpm * *(adelay->divisor));
                } else {
@@ -387,7 +406,7 @@ run(LV2_Handle instance, uint32_t n_samples)
        xfade = 0.f;
        for (i = 0; i < n_samples; i++) {
                in = input[i];
-               adelay->z[adelay->posz] = in; // + feedb / 100. * fbstate;
+               adelay->z[adelay->posz] = in + *adelay->feedback / 100. * adelay->fbstate;
                adelay->fbstate = 0.f;
                int p = adelay->posz - adelay->tap[adelay->active]; // active line
                if (p<0) p += MAX_DELAY;
@@ -396,7 +415,7 @@ run(LV2_Handle instance, uint32_t n_samples)
                if (recalc) {
                        xfade += 1.0f / (float)n_samples;
                        adelay->fbstate *= (1.-xfade);
-                       int p = adelay->posz - adelay->tap[adelay->next]; // next line
+                       p = adelay->posz - adelay->tap[adelay->next]; // next line
                        if (p<0) p += MAX_DELAY;
                        adelay->fbstate += adelay->z[p] * xfade;
                }
@@ -405,7 +424,7 @@ run(LV2_Handle instance, uint32_t n_samples)
                        adelay->posz = 0;
                }
        }
-       adelay->lpfold = *(adelay->lpf);
+       adelay->feedbackold = *(adelay->feedback);
        adelay->divisorold = *(adelay->divisor);
        adelay->gainold = *(adelay->gain);
        adelay->invertold = *(adelay->inv);