Fix a-EQ when parameter changes are very slow
[ardour.git] / libs / plugins / a-eq.lv2 / a-eq.c
1 /* a-eq
2  * Copyright (C) 2016 Damien Zammit <damien@zamaudio.com>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #ifndef _GNU_SOURCE
16 #define _GNU_SOURCE // needed for M_PI
17 #endif
18
19 #include <math.h>
20 #include <complex.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdbool.h>
24 #include <stdio.h>
25
26 #ifdef COMPILER_MSVC
27 #include <float.h>
28 #define isfinite_local(val) (bool)_finite((double)val)
29 #else
30 #define isfinite_local isfinite
31 #endif
32
33 #include "lv2/lv2plug.in/ns/lv2core/lv2.h"
34
35 #ifdef LV2_EXTENDED
36 #include <cairo/cairo.h>
37 #include "ardour/lv2_extensions.h"
38 #endif
39
40 #define AEQ_URI "urn:ardour:a-eq"
41 #define BANDS   6
42 #ifndef MIN
43 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
44 #endif
45
46 typedef enum {
47         AEQ_FREQL = 0,
48         AEQ_GAINL,
49         AEQ_FREQ1,
50         AEQ_GAIN1,
51         AEQ_BW1,
52         AEQ_FREQ2,
53         AEQ_GAIN2,
54         AEQ_BW2,
55         AEQ_FREQ3,
56         AEQ_GAIN3,
57         AEQ_BW3,
58         AEQ_FREQ4,
59         AEQ_GAIN4,
60         AEQ_BW4,
61         AEQ_FREQH,
62         AEQ_GAINH,
63         AEQ_MASTER,
64         AEQ_FILTOGL,
65         AEQ_FILTOG1,
66         AEQ_FILTOG2,
67         AEQ_FILTOG3,
68         AEQ_FILTOG4,
69         AEQ_FILTOGH,
70         AEQ_ENABLE,
71         AEQ_INPUT,
72         AEQ_OUTPUT,
73 } PortIndex;
74
75 static inline double
76 to_dB(double g) {
77         return (20.0*log10(g));
78 }
79
80 static inline double
81 from_dB(double gdb) {
82         return (exp(gdb/20.0*log(10.0)));
83 }
84
85 static inline bool
86 is_eq(float a, float b, float small) {
87         return (fabsf(a - b) < small);
88 }
89
90 struct linear_svf {
91         double g, k;
92         double a[3];
93         double m[3];
94         double s[2];
95 };
96
97 static void linear_svf_reset(struct linear_svf *self)
98 {
99         self->s[0] = self->s[1] = 0.0;
100 }
101
102 static void linear_svf_protect(struct linear_svf *self)
103 {
104         if (!isfinite_local (self->s[0]) || !isfinite_local (self->s[1])) {
105                 linear_svf_reset (self);
106         }
107 }
108
109 typedef struct {
110         float* f0[BANDS];
111         float* g[BANDS];
112         float* bw[BANDS];
113         float* filtog[BANDS];
114         float* master;
115         float* enable;
116
117         float srate;
118         float tau;
119
120         float* input;
121         float* output;
122
123         struct linear_svf v_filter[BANDS];
124         float v_g[BANDS];
125         float v_bw[BANDS];
126         float v_f0[BANDS];
127         float v_master;
128
129         bool need_expose;
130
131 #ifdef LV2_EXTENDED
132         LV2_Inline_Display_Image_Surface surf;
133         cairo_surface_t*                 display;
134         LV2_Inline_Display*              queue_draw;
135         uint32_t                         w, h;
136 #endif
137 } Aeq;
138
139 static LV2_Handle
140 instantiate(const LV2_Descriptor* descriptor,
141             double rate,
142             const char* bundle_path,
143             const LV2_Feature* const* features)
144 {
145         Aeq* aeq = (Aeq*)calloc(1, sizeof(Aeq));
146         aeq->srate = rate;
147         aeq->tau = 1.0 - expf (-2.f * M_PI * 64.f * 25.f / aeq->srate); // 25Hz time constant @ 64fpp
148
149 #ifdef LV2_EXTENDED
150         for (int i=0; features[i]; ++i) {
151                 if (!strcmp(features[i]->URI, LV2_INLINEDISPLAY__queue_draw)) {
152                         aeq->queue_draw = (LV2_Inline_Display*) features[i]->data;
153                 }
154         }
155 #endif
156
157         for (int i = 0; i < BANDS; i++)
158                 linear_svf_reset(&aeq->v_filter[i]);
159
160         aeq->need_expose = true;
161 #ifdef LV2_EXTENDED
162         aeq->display = NULL;
163 #endif
164
165         return (LV2_Handle)aeq;
166 }
167
168 static void
169 connect_port(LV2_Handle instance,
170              uint32_t port,
171              void* data)
172 {
173         Aeq* aeq = (Aeq*)instance;
174
175         switch ((PortIndex)port) {
176         case AEQ_ENABLE:
177                 aeq->enable = (float*)data;
178                 break;
179         case AEQ_FREQL:
180                 aeq->f0[0] = (float*)data;
181                 break;
182         case AEQ_GAINL:
183                 aeq->g[0] = (float*)data;
184                 break;
185         case AEQ_FREQ1:
186                 aeq->f0[1] = (float*)data;
187                 break;
188         case AEQ_GAIN1:
189                 aeq->g[1] = (float*)data;
190                 break;
191         case AEQ_BW1:
192                 aeq->bw[1] = (float*)data;
193                 break;
194         case AEQ_FREQ2:
195                 aeq->f0[2] = (float*)data;
196                 break;
197         case AEQ_GAIN2:
198                 aeq->g[2] = (float*)data;
199                 break;
200         case AEQ_BW2:
201                 aeq->bw[2] = (float*)data;
202                 break;
203         case AEQ_FREQ3:
204                 aeq->f0[3] = (float*)data;
205                 break;
206         case AEQ_GAIN3:
207                 aeq->g[3] = (float*)data;
208                 break;
209         case AEQ_BW3:
210                 aeq->bw[3] = (float*)data;
211                 break;
212         case AEQ_FREQ4:
213                 aeq->f0[4] = (float*)data;
214                 break;
215         case AEQ_GAIN4:
216                 aeq->g[4] = (float*)data;
217                 break;
218         case AEQ_BW4:
219                 aeq->bw[4] = (float*)data;
220                 break;
221         case AEQ_FREQH:
222                 aeq->f0[5] = (float*)data;
223                 break;
224         case AEQ_GAINH:
225                 aeq->g[5] = (float*)data;
226                 break;
227         case AEQ_MASTER:
228                 aeq->master = (float*)data;
229                 break;
230         case AEQ_FILTOGL:
231                 aeq->filtog[0] = (float*)data;
232                 break;
233         case AEQ_FILTOG1:
234                 aeq->filtog[1] = (float*)data;
235                 break;
236         case AEQ_FILTOG2:
237                 aeq->filtog[2] = (float*)data;
238                 break;
239         case AEQ_FILTOG3:
240                 aeq->filtog[3] = (float*)data;
241                 break;
242         case AEQ_FILTOG4:
243                 aeq->filtog[4] = (float*)data;
244                 break;
245         case AEQ_FILTOGH:
246                 aeq->filtog[5] = (float*)data;
247                 break;
248         case AEQ_INPUT:
249                 aeq->input = (float*)data;
250                 break;
251         case AEQ_OUTPUT:
252                 aeq->output = (float*)data;
253                 break;
254         }
255 }
256
257 static void
258 activate(LV2_Handle instance)
259 {
260         int i;
261         Aeq* aeq = (Aeq*)instance;
262
263         for (i = 0; i < BANDS; i++)
264                 linear_svf_reset(&aeq->v_filter[i]);
265 }
266
267 // SVF filters
268 // http://www.cytomic.com/files/dsp/SvfLinearTrapOptimised2.pdf
269
270 static void linear_svf_set_peq(struct linear_svf *self, float gdb, float sample_rate, float cutoff, float bandwidth)
271 {
272         double f0 = (double)cutoff;
273         double q = (double)pow(2.0, 1.0 / bandwidth) / (pow(2.0, bandwidth) - 1.0);
274         double sr = (double)sample_rate;
275         double A = pow(10.0, gdb/40.0);
276
277         self->g = tan(M_PI * (f0 / sr));
278         self->k = 1.0 / (q * A);
279
280         self->a[0] = 1.0 / (1.0 + self->g * (self->g + self->k));
281         self->a[1] = self->g * self->a[0];
282         self->a[2] = self->g * self->a[1];
283
284         self->m[0] = 1.0;
285         self->m[1] = self->k * (A * A - 1.0);
286         self->m[2] = 0.0;
287 }
288
289 static void linear_svf_set_highshelf(struct linear_svf *self, float gdb, float sample_rate, float cutoff, float resonance)
290 {
291         double f0 = (double)cutoff;
292         double q = (double)resonance;
293         double sr = (double)sample_rate;
294         double A = pow(10.0, gdb/40.0);
295
296         self->g = tan(M_PI * (f0 / sr));
297         self->k = 1.0 / q;
298
299         self->a[0] = 1.0 / (1.0 + self->g * (self->g + self->k));
300         self->a[1] = self->g * self->a[0];
301         self->a[2] = self->g * self->a[1];
302
303         self->m[0] = A * A;
304         self->m[1] = self->k * (1.0 - A) * A;
305         self->m[2] = 1.0 - A * A;
306 }
307
308 static void linear_svf_set_lowshelf(struct linear_svf *self, float gdb, float sample_rate, float cutoff, float resonance)
309 {
310         double f0 = (double)cutoff;
311         double q = (double)resonance;
312         double sr = (double)sample_rate;
313         double A = pow(10.0, gdb/40.0);
314
315         self->g = tan(M_PI * (f0 / sr));
316         self->k = 1.0 / q;
317
318         self->a[0] = 1.0 / (1.0 + self->g * (self->g + self->k));
319         self->a[1] = self->g * self->a[0];
320         self->a[2] = self->g * self->a[1];
321
322         self->m[0] = 1.0;
323         self->m[1] = self->k * (A - 1.0);
324         self->m[2] = A * A - 1.0;
325 }
326
327 static float run_linear_svf(struct linear_svf *self, float in)
328 {
329         double v[3];
330         double din = (double)in;
331         double out;
332
333         v[2] = din - self->s[1];
334         v[0] = (self->a[0] * self->s[0]) + (self->a[1] * v[2]);
335         v[1] = self->s[1] + (self->a[1] * self->s[0]) + (self->a[2] * v[2]);
336
337         self->s[0] = (2.0 * v[0]) - self->s[0];
338         self->s[1] = (2.0 * v[1]) - self->s[1];
339
340         out = (self->m[0] * din)
341                 + (self->m[1] * v[0])
342                 + (self->m[2] * v[1]);
343
344         return (float)out;
345 }
346
347 static void set_params(LV2_Handle instance, int band) {
348         Aeq* aeq = (Aeq*)instance;
349
350         switch (band) {
351         case 0:
352                 linear_svf_set_lowshelf(&aeq->v_filter[0], aeq->v_g[0], aeq->srate, aeq->v_f0[0], 0.7071068);
353                 break;
354         case 1:
355         case 2:
356         case 3:
357         case 4:
358                 linear_svf_set_peq(&aeq->v_filter[band], aeq->v_g[band], aeq->srate, aeq->v_f0[band], aeq->v_bw[band]);
359                 break;
360         case 5:
361                 linear_svf_set_highshelf(&aeq->v_filter[5], aeq->v_g[5], aeq->srate, aeq->v_f0[5], 0.7071068);
362                 break;
363         }
364 }
365
366 static void
367 run(LV2_Handle instance, uint32_t n_samples)
368 {
369         Aeq* aeq = (Aeq*)instance;
370
371         const float* const input = aeq->input;
372         float* const output = aeq->output;
373
374         const float tau = aeq->tau;
375         uint32_t offset = 0;
376
377         const float target_gain = *aeq->enable <= 0 ? 0 : *aeq->master; // dB
378
379         while (n_samples > 0) {
380                 uint32_t block = n_samples;
381                 bool any_changed = false;
382
383                 if (!is_eq(aeq->v_master, target_gain, 0.1)) {
384                         aeq->v_master += tau * (target_gain - aeq->v_master);
385                         any_changed = true;
386                 } else {
387                         aeq->v_master = target_gain;
388                 }
389
390                 for (int i = 0; i < BANDS; ++i) {
391                         bool changed = false;
392
393                         if (!is_eq(aeq->v_f0[i], *aeq->f0[i], 0.1)) {
394                                 aeq->v_f0[i] += tau * (*aeq->f0[i] - aeq->v_f0[i]);
395                                 changed = true;
396                         }
397
398                         if (*aeq->filtog[i] <= 0 || *aeq->enable <= 0) {
399                                 if (!is_eq(aeq->v_g[i], 0.f, 0.05)) {
400                                         aeq->v_g[i] += tau * (0.0 - aeq->v_g[i]);
401                                         changed = true;
402                                 }
403                         } else {
404                                 if (!is_eq(aeq->v_g[i], *aeq->g[i], 0.05)) {
405                                         aeq->v_g[i] += tau * (*aeq->g[i] - aeq->v_g[i]);
406                                         changed = true;
407                                 }
408                         }
409
410                         if (i != 0 && i != 5) {
411                                 if (!is_eq(aeq->v_bw[i], *aeq->bw[i], 0.001)) {
412                                         aeq->v_bw[i] += tau * (*aeq->bw[i] - aeq->v_bw[i]);
413                                         changed = true;
414                                 }
415                         }
416
417                         if (changed) {
418                                 set_params(aeq, i);
419                                 any_changed = true;
420                         }
421                 }
422
423                 if (any_changed) {
424                         aeq->need_expose = true;
425                         block = MIN (64, n_samples);
426                 }
427
428                 for (uint32_t i = 0; i < block; ++i) {
429                         float in0, out;
430                         in0 = input[i + offset];
431                         out = in0;
432                         for (uint32_t j = 0; j < BANDS; j++) {
433                                 out = run_linear_svf(&aeq->v_filter[j], out);
434                         }
435                         output[i + offset] = out * from_dB(aeq->v_master);
436                 }
437                 n_samples -= block;
438                 offset += block;
439         }
440
441         for (uint32_t j = 0; j < BANDS; j++) {
442                 linear_svf_protect(&aeq->v_filter[j]);
443         }
444
445 #ifdef LV2_EXTENDED
446         if (aeq->need_expose && aeq->queue_draw) {
447                 aeq->need_expose = false;
448                 aeq->queue_draw->queue_draw (aeq->queue_draw->handle);
449         }
450 #endif
451 }
452
453 static double
454 calc_peq(Aeq* self, int i, double omega) {
455         double complex H = 0.0;
456         double complex z = cexp(I * omega);
457         double complex zz = cexp(2. * I * omega);
458         double complex zm = z - 1.0;
459         double complex zp = z + 1.0;
460         double complex zzm = zz - 1.0;
461
462         double A = pow(10.0, self->v_g[i]/40.0);
463         double g = self->v_filter[i].g;
464         double k = self->v_filter[i].k * A;
465         double m1 = k * (A * A - 1.0) / A;
466
467         H = (g*k*zzm + A*(g*zp*(m1*zm) + (zm*zm + g*g*zp*zp))) / (g*k*zzm + A*(zm*zm + g*g*zp*zp));
468         return cabs(H);
469 }
470
471 static double
472 calc_lowshelf(Aeq* self, double omega) {
473         double complex H = 0.0;
474         double complex z = cexp(I * omega);
475         double complex zz = cexp(2. * I * omega);
476         double complex zm = z - 1.0;
477         double complex zp = z + 1.0;
478         double complex zzm = zz - 1.0;
479
480         double A = pow(10.0, self->v_g[0]/40.0);
481         double g = self->v_filter[0].g;
482         double k = self->v_filter[0].k;
483         double m0 = self->v_filter[0].m[0];
484         double m1 = self->v_filter[0].m[1];
485         double m2 = self->v_filter[0].m[2];
486
487         H = (A*m0*zm*zm + g*g*(m0+m2)*zp*zp + sqrt(A)*g*(k*m0+m1) * zzm) / (A*zm*zm + g*g*zp*zp + sqrt(A)*g*k*zzm);
488         return cabs(H);
489 }
490
491 static double
492 calc_highshelf(Aeq* self, double omega) {
493         double complex H = 0.0;
494         double complex z = cexp(I * omega);
495         double complex zz = cexp(2. * I * omega);
496         double complex zm = z - 1.0;
497         double complex zp = z + 1.0;
498         double complex zzm = zz - 1.0;
499
500         double A = pow(10.0, self->v_g[5]/40.0);
501         double g = self->v_filter[5].g;
502         double k = self->v_filter[5].k;
503         double m0 = self->v_filter[5].m[0];
504         double m1 = self->v_filter[5].m[1];
505         double m2 = self->v_filter[5].m[2];
506
507         H = ( sqrt(A) * g * zp * (m1 * zm + sqrt(A)*g*m2*zp) + m0 * ( zm*zm + A*g*g*zp*zp + sqrt(A)*g*k*zzm)) / (zm*zm + A*g*g*zp*zp + sqrt(A)*g*k*zzm);
508         return cabs(H);
509 }
510
511 #ifdef LV2_EXTENDED
512 static float
513 eq_curve (Aeq* self, float f) {
514         double response = 1.0;
515         double SR = (double)self->srate;
516         double omega = f * 2. * M_PI / SR;
517
518         // lowshelf
519         response *= calc_lowshelf(self, omega);
520
521         // peq 1 - 4:
522         response *= calc_peq(self, 1, omega);
523         response *= calc_peq(self, 2, omega);
524         response *= calc_peq(self, 3, omega);
525         response *= calc_peq(self, 4, omega);
526
527         // highshelf:
528         response *= calc_highshelf(self, omega);
529
530         return (float)response;
531 }
532
533 static LV2_Inline_Display_Image_Surface *
534 render_inline (LV2_Handle instance, uint32_t w, uint32_t max_h)
535 {
536         Aeq* self = (Aeq*)instance;
537         uint32_t h = MIN (1 | (uint32_t)ceilf (w * 9.f / 16.f), max_h);
538
539         if (!self->display || self->w != w || self->h != h) {
540                 if (self->display) cairo_surface_destroy(self->display);
541                 self->display = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
542                 self->w = w;
543                 self->h = h;
544         }
545
546         cairo_t* cr = cairo_create (self->display);
547
548         // clear background
549         cairo_rectangle (cr, 0, 0, w, h);
550         cairo_set_source_rgba (cr, .2, .2, .2, 1.0);
551         cairo_fill (cr);
552
553         cairo_set_line_width(cr, 1.0);
554
555         // prepare grid drawing
556         cairo_save (cr);
557         const double dash2[] = {1, 3};
558         //cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
559         cairo_set_dash(cr, dash2, 2, 2);
560         cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.5);
561
562         // draw x-grid 6dB steps
563         for (int32_t d = -18; d <= 18; d+=6) {
564                 float y = (float)h * (d / 40.0 + 0.5);
565                 y = rint (y) - .5;
566                 cairo_move_to (cr, 0, y);
567                 cairo_line_to (cr, w, y);
568                 cairo_stroke (cr);
569         }
570         // draw y-axis grid 100, 1k, 10K
571         for (int32_t f = 100; f <= 10000; f *= 10) {
572                 float x = w * log10 (f / 20.0) / log10 (1000.0);
573                 x = rint (x) - .5;
574                 cairo_move_to (cr, x, 0);
575                 cairo_line_to (cr, x, h);
576                 cairo_stroke (cr);
577         }
578
579         cairo_restore (cr);
580
581
582         // draw curve
583         cairo_set_source_rgba (cr, .8, .8, .8, 1.0);
584         cairo_move_to (cr, 0, h);
585
586         for (uint32_t x = 0; x < w; ++x) {
587                 // plot 20..20kHz +-20dB
588                 const float x_hz = 20.f * powf (1000.f, (float)x / (float)w);
589                 const float y_db = to_dB(eq_curve(self, x_hz)) + self->v_master;
590                 const float y = (float)h * (-y_db / 40.0 + 0.5);
591                 cairo_line_to (cr, x, y);
592         }
593         cairo_stroke_preserve (cr);
594
595         cairo_line_to (cr, w, h);
596         cairo_close_path (cr);
597         cairo_clip (cr);
598
599         // create RGBA surface
600         cairo_destroy (cr);
601         cairo_surface_flush (self->display);
602         self->surf.width = cairo_image_surface_get_width (self->display);
603         self->surf.height = cairo_image_surface_get_height (self->display);
604         self->surf.stride = cairo_image_surface_get_stride (self->display);
605         self->surf.data = cairo_image_surface_get_data  (self->display);
606
607         return &self->surf;
608 }
609 #endif
610
611 static const void*
612 extension_data(const char* uri)
613 {
614 #ifdef LV2_EXTENDED
615         static const LV2_Inline_Display_Interface display  = { render_inline };
616         if (!strcmp(uri, LV2_INLINEDISPLAY__interface)) {
617                 return &display;
618         }
619 #endif
620         return NULL;
621 }
622
623 static void
624 cleanup(LV2_Handle instance)
625 {
626 #ifdef LV2_EXTENDED
627         Aeq* aeq = (Aeq*)instance;
628         if (aeq->display) {
629                 cairo_surface_destroy (aeq->display);
630         }
631 #endif
632         free(instance);
633 }
634
635 static const LV2_Descriptor descriptor = {
636         AEQ_URI,
637         instantiate,
638         connect_port,
639         activate,
640         run,
641         NULL,
642         cleanup,
643         extension_data
644 };
645
646 LV2_SYMBOL_EXPORT
647 const LV2_Descriptor*
648 lv2_descriptor(uint32_t index)
649 {
650         switch (index) {
651         case 0:
652                 return &descriptor;
653         default:
654                 return NULL;
655         }
656 }