e2dd969bd6454d99df368c0ae24a44bc37e46414
[ardour.git] / libs / plugins / a-reverb.lv2 / a-reverb.c
1 /* a-reverb -- based on b_reverb (setBfree) and FreeVerb
2  *
3  * Copyright (C) 2003-2004 Fredrik Kilander <fk@dsv.su.se>
4  * Copyright (C) 2008-2016 Robin Gareus <robin@gareus.org>
5  * Copyright (C) 2012 Will Panther <pantherb@setbfree.org>
6  * Copyright (C) 2016 Damien Zammit <damien@zamaudio.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #ifndef _GNU_SOURCE
23 #define _GNU_SOURCE // needed for M_PI
24 #endif
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <ctype.h>
29 #include <math.h>
30 #include <string.h>
31
32 #define RV_NZ 7
33 #define DENORMAL_PROTECT (1e-14)
34
35 typedef struct {
36         float* delays[2][RV_NZ]; /**< delay line buffer */
37
38         float* idx0[2][RV_NZ];  /**< Reset pointer ref delays[]*/
39         float* idxp[2][RV_NZ];  /**< Index pointer ref delays[]*/
40         float* endp[2][RV_NZ];  /**< End pointer   ref delays[]*/
41
42         float gain[RV_NZ]; /**< feedback gains */
43         float yy1_0; /**< Previous output sample */
44         float y_1_0; /**< Feedback sample */
45         float yy1_1; /**< Previous output sample */
46         float y_1_1; /**< Feedback sample */
47
48         int end[2][RV_NZ];
49
50         float inputGain;        /**< Input gain value */
51         float fbk;      /**< Feedback gain */
52         float wet;      /**< Output dry gain */
53         float dry;      /**< Output wet gain */
54 } b_reverb;
55
56 static int
57 setReverbPointers (b_reverb *r, int i, int c, const double rate)
58 {
59         int e = (r->end[c][i] * rate / 25000.0);
60         e = e | 1;
61         r->delays[c][i] = (float*)realloc ((void*)r->delays[c][i], (e + 2) * sizeof (float));
62         if (!r->delays[c][i]) {
63                 return -1;
64         } else {
65                 memset (r->delays[c][i], 0 , (e + 2) * sizeof (float));
66         }
67         r->endp[c][i] = r->delays[c][i] + e + 1;
68         r->idx0[c][i] = r->idxp[c][i] = &(r->delays[c][i][0]);
69
70         return 0;
71 }
72
73 static int
74 initReverb (b_reverb *r, const double rate)
75 {
76         int err = 0;
77         int stereowidth = 7;
78
79         r->inputGain = powf (10.0, .05 * -20.0);  // -20dB
80         r->fbk = -0.015; /* Feedback gain */
81         r->wet = 0.3;
82         r->dry = 0.7;
83
84         /* feedback combfilter */
85         r->gain[0] = 0.773;
86         r->gain[1] = 0.802;
87         r->gain[2] = 0.753;
88         r->gain[3] = 0.733;
89
90         /* all-pass filter */
91         r->gain[4] = sqrtf (0.5);
92         r->gain[5] = sqrtf (0.5);
93         r->gain[6] = sqrtf (0.5);
94
95         /* delay lines left */
96         r->end[0][0] = 1687;
97         r->end[0][1] = 1601;
98         r->end[0][2] = 2053;
99         r->end[0][3] = 2251;
100
101         /* all pass filters left */
102         r->end[0][4] = 347;
103         r->end[0][5] = 113;
104         r->end[0][6] = 37;
105
106         /* delay lines right */
107         r->end[1][0] = 1687 + stereowidth;
108         r->end[1][1] = 1601 + stereowidth;
109         r->end[1][2] = 2053 + stereowidth;
110         r->end[1][3] = 2251 + stereowidth;
111
112         /* all pass filters right */
113         r->end[1][4] = 347 + stereowidth;
114         r->end[1][5] = 113 + stereowidth;
115         r->end[1][6] = 37 + stereowidth;
116
117         for (int i = 0; i < RV_NZ; ++i) {
118                 r->delays[0][i] = NULL;
119                 r->delays[1][i] = NULL;
120         }
121
122         r->yy1_0 = 0.0;
123         r->y_1_0 = 0.0;
124         r->yy1_1 = 0.0;
125         r->y_1_1 = 0.0;
126
127         for (int i = 0; i < RV_NZ; i++) {
128                 err |= setReverbPointers (r, i, 0, rate);
129                 err |= setReverbPointers (r, i, 1, rate);
130         }
131         return err;
132 }
133
134 static void
135 reverb (b_reverb* r,
136         const float* inbuf0,
137         const float* inbuf1,
138         float* outbuf0,
139         float* outbuf1,
140         size_t n_samples)
141 {
142         float** const idxp0 = r->idxp[0];
143         float** const idxp1 = r->idxp[1];
144         float* const* const endp0 = r->endp[0];
145         float* const* const endp1 = r->endp[1];
146         float* const* const idx00 = r->idx0[0];
147         float* const* const idx01 = r->idx0[1];
148         const float* const gain = r->gain;
149         const float inputGain = r->inputGain;
150         const float fbk = r->fbk;
151         const float wet = r->wet;
152         const float dry = r->dry;
153
154         const float* xp0 = inbuf0;
155         const float* xp1 = inbuf1;
156         float* yp0 = outbuf0;
157         float* yp1 = outbuf1;
158
159         float y_1_0 = r->y_1_0;
160         float yy1_0 = r->yy1_0;
161         float y_1_1 = r->y_1_1;
162         float yy1_1 = r->yy1_1;
163
164         for (size_t i = 0; i < n_samples; ++i) {
165                 int j;
166                 float y;
167                 const float xo0 = *xp0++;
168                 const float xo1 = *xp1++;
169                 const float x0 = y_1_0 + (inputGain * xo0);
170                 const float x1 = y_1_1 + (inputGain * xo1);
171                 float xa = 0.0;
172                 float xb = 0.0;
173                 /* First we do four feedback comb filters (ie parallel delay lines,
174                  * each with a single tap at the end that feeds back at the start) */
175
176                 for (j = 0; j < 4; ++j) {
177                         y = *idxp0[j];
178                         *idxp0[j] = x0 + (gain[j] * y);
179                         if (endp0[j] <= ++(idxp0[j])) {
180                                 idxp0[j] = idx00[j];
181                         }
182                         xa += y;
183                 }
184                 for (; j < 7; ++j) {
185                         y = *idxp0[j];
186                         *idxp0[j] = gain[j] * (xa + y);
187                         if (endp0[j] <= ++(idxp0[j])) {
188                                 idxp0[j] = idx00[j];
189                         }
190                         xa = y - xa;
191                 }
192
193                 y = 0.5f * (xa + yy1_0);
194                 yy1_0 = y;
195                 y_1_0 = fbk * xa;
196
197                 *yp0++ = ((wet * y) + (dry * xo0));
198
199                 for (j = 0; j < 4; ++j) {
200                         y = *idxp1[j];
201                         *idxp1[j] = x1 + (gain[j] * y);
202                         if (endp1[j] <= ++(idxp1[j])) {
203                                 idxp1[j] = idx01[j];
204                         }
205                         xb += y;
206                 }
207                 for (; j < 7; ++j) {
208                         y = *idxp1[j];
209                         *idxp1[j] = gain[j] * (xb + y);
210                         if (endp1[j] <= ++(idxp1[j])) {
211                                 idxp1[j] = idx01[j];
212                         }
213                         xb = y - xb;
214                 }
215
216                 y = 0.5f * (xb + yy1_1);
217                 yy1_1 = y;
218                 y_1_1 = fbk * xb;
219
220                 *yp1++ = ((wet * y) + (dry * xo1));
221         }
222
223         r->y_1_0 = y_1_0 + DENORMAL_PROTECT;
224         r->yy1_0 = yy1_0 + DENORMAL_PROTECT;
225         r->y_1_1 = y_1_1 + DENORMAL_PROTECT;
226         r->yy1_1 = yy1_1 + DENORMAL_PROTECT;
227 }
228
229 /******************************************************************************
230  * LV2 wrapper
231  */
232
233 #include "lv2/lv2plug.in/ns/lv2core/lv2.h"
234
235 typedef enum {
236         AR_INPUT0     = 0,
237         AR_INPUT1     = 1,
238         AR_OUTPUT0    = 2,
239         AR_OUTPUT1    = 3,
240         AR_MIX        = 4,
241         AR_ROOMSZ     = 5,
242 } PortIndex;
243
244 typedef struct {
245         float* input0;
246         float* input1;
247         float* output0;
248         float* output1;
249
250         float* mix;
251         float* roomsz;
252
253         float v_mix;
254         float v_roomsz;
255         float srate;
256
257         b_reverb r;
258 } AReverb;
259
260 static LV2_Handle
261 instantiate (const LV2_Descriptor*     descriptor,
262              double                    rate,
263              const char*               bundle_path,
264              const LV2_Feature* const* features)
265 {
266         AReverb* self = (AReverb*)calloc (1, sizeof (AReverb));
267         if (!self) {
268                 return NULL;
269         }
270         if (initReverb (&self->r, rate)) {
271                 return NULL;
272         }
273
274         // these are set in initReverb()
275         self->v_roomsz = 0.75;
276         self->v_mix = 0.1;
277         self->srate = rate;
278
279         return (LV2_Handle)self;
280 }
281
282 static void
283 connect_port (LV2_Handle instance,
284               uint32_t   port,
285               void*      data)
286 {
287         AReverb* self = (AReverb*)instance;
288
289         switch ((PortIndex)port) {
290                 case AR_INPUT0:
291                         self->input0 = (float*)data;
292                         break;
293                 case AR_INPUT1:
294                         self->input1 = (float*)data;
295                         break;
296                 case AR_OUTPUT0:
297                         self->output0 = (float*)data;
298                         break;
299                 case AR_OUTPUT1:
300                         self->output1 = (float*)data;
301                         break;
302                 case AR_MIX:
303                         self->mix = (float*)data;
304                         break;
305                 case AR_ROOMSZ:
306                         self->roomsz = (float*)data;
307                         break;
308         }
309 }
310
311 static void
312 run (LV2_Handle instance, uint32_t n_samples)
313 {
314         AReverb* self = (AReverb*)instance;
315
316         const float* const input0 = self->input0;
317         const float* const input1 = self->input1;
318         float* const      output0 = self->output0;
319         float* const      output1 = self->output1;
320
321         // 15Hz time constant
322         const float tau = (1.0 - exp(-2.0 * M_PI * n_samples * 15. / self->srate));
323
324         if (*self->mix != self->v_mix) {
325                 self->v_mix += tau * ( *self->mix - self->v_mix);
326                 self->r.wet = self->v_mix;
327                 self->r.dry = 1.0 - self->v_mix;
328         }
329         if (*self->roomsz != self->v_roomsz) {
330                 self->v_roomsz += tau * ( *self->roomsz - self->v_roomsz);
331                 self->r.gain[0] = 0.773 * self->v_roomsz;
332                 self->r.gain[1] = 0.802 * self->v_roomsz;
333                 self->r.gain[2] = 0.753 * self->v_roomsz;
334                 self->r.gain[3] = 0.733 * self->v_roomsz;
335         }
336
337         reverb (&self->r, input0, input1, output0, output1, n_samples);
338 }
339
340 static void
341 activate (LV2_Handle instance)
342 {
343         AReverb* self = (AReverb*)instance;
344
345         self->r.y_1_0 = 0;
346         self->r.yy1_0 = 0;
347         self->r.y_1_1 = 0;
348         self->r.yy1_1 = 0;
349         for (int i = 0; i < RV_NZ; ++i) {
350                 self->r.delays[0][i] = NULL;
351                 self->r.delays[1][i] = NULL;
352         }
353 }
354
355 static void
356 deactivate (LV2_Handle instance)
357 {
358         activate(instance);
359 }
360
361 static void
362 cleanup (LV2_Handle instance)
363 {
364         AReverb* self = (AReverb*)instance;
365         for (int i = 0; i < RV_NZ; ++i) {
366                 free (self->r.delays[0][i]);
367                 free (self->r.delays[1][i]);
368         }
369         free (instance);
370 }
371
372 static const void*
373 extension_data (const char* uri)
374 {
375         return NULL;
376 }
377
378 static const LV2_Descriptor descriptor = {
379         "urn:ardour:a-reverb",
380         instantiate,
381         connect_port,
382         activate,
383         run,
384         deactivate,
385         cleanup,
386         extension_data
387 };
388
389 LV2_SYMBOL_EXPORT
390 const LV2_Descriptor*
391 lv2_descriptor (uint32_t index)
392 {
393         switch (index) {
394                 case 0:
395                         return &descriptor;
396                 default:
397                         return NULL;
398         }
399 }