1 /* a-reverb -- based on b_reverb (setBfree) and FreeVerb
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>
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)
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.
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/>.
23 #define _GNU_SOURCE // needed for M_PI
33 #define DENORMAL_PROTECT (1e-14)
36 float* delays[2][RV_NZ]; /**< delay line buffer */
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[]*/
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 */
50 float inputGain; /**< Input gain value */
51 float fbk; /**< Feedback gain */
52 float wet; /**< Output dry gain */
53 float dry; /**< Output wet gain */
57 setReverbPointers (b_reverb *r, int i, int c, const double rate)
59 int e = (r->end[c][i] * rate / 25000.0);
61 r->delays[c][i] = (float*)realloc ((void*)r->delays[c][i], (e + 2) * sizeof (float));
62 if (!r->delays[c][i]) {
65 memset (r->delays[c][i], 0 , (e + 2) * sizeof (float));
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]);
74 initReverb (b_reverb *r, const double rate)
79 r->inputGain = powf (10.0, .05 * -20.0); // -20dB
80 r->fbk = -0.015; /* Feedback gain */
84 /* feedback combfilter */
91 r->gain[4] = sqrtf (0.5);
92 r->gain[5] = sqrtf (0.5);
93 r->gain[6] = sqrtf (0.5);
95 /* delay lines left */
101 /* all pass filters left */
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;
112 /* all pass filters right */
113 r->end[0][4] = 347 + stereowidth;
114 r->end[0][5] = 113 + stereowidth;
115 r->end[0][6] = 37 + stereowidth;
117 for (int i = 0; i < RV_NZ; ++i) {
118 r->delays[0][i] = NULL;
119 r->delays[1][i] = NULL;
127 for (int i = 0; i < RV_NZ; i++) {
128 err |= setReverbPointers (r, i, 0, rate);
129 err |= setReverbPointers (r, i, 1, rate);
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;
154 const float* xp0 = inbuf0;
155 const float* xp1 = inbuf1;
156 float* yp0 = outbuf0;
157 float* yp1 = outbuf1;
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;
164 for (size_t i = 0; i < n_samples; ++i) {
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);
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) */
176 for (j = 0; j < 4; ++j) {
178 *idxp0[j] = x0 + (gain[j] * y);
179 if (endp0[j] <= ++(idxp0[j])) {
186 *idxp0[j] = gain[j] * (xa + y);
187 if (endp0[j] <= ++(idxp0[j])) {
193 y = 0.5f * (xa + yy1_0);
197 *yp0++ = ((wet * y) + (dry * xo0));
199 for (j = 0; j < 4; ++j) {
201 *idxp1[j] = x1 + (gain[j] * y);
202 if (endp1[j] <= ++(idxp1[j])) {
209 *idxp1[j] = gain[j] * (xb + y);
210 if (endp1[j] <= ++(idxp1[j])) {
216 y = 0.5f * (xb + yy1_1);
220 *yp1++ = ((wet * y) + (dry * xo1));
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;
229 /******************************************************************************
233 #include "lv2/lv2plug.in/ns/lv2core/lv2.h"
261 instantiate (const LV2_Descriptor* descriptor,
263 const char* bundle_path,
264 const LV2_Feature* const* features)
266 AReverb* self = (AReverb*)calloc (1, sizeof (AReverb));
270 if (initReverb (&self->r, rate)) {
274 // these are set in initReverb()
275 self->v_roomsz = 0.75;
279 return (LV2_Handle)self;
283 connect_port (LV2_Handle instance,
287 AReverb* self = (AReverb*)instance;
289 switch ((PortIndex)port) {
291 self->input0 = (float*)data;
294 self->input1 = (float*)data;
297 self->output0 = (float*)data;
300 self->output1 = (float*)data;
303 self->mix = (float*)data;
306 self->roomsz = (float*)data;
312 run (LV2_Handle instance, uint32_t n_samples)
314 AReverb* self = (AReverb*)instance;
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;
322 const float tau = (1.0 - exp(-2.0 * M_PI * n_samples * 25 / self->srate));
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;
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;
337 reverb (&self->r, input0, input1, output0, output1, n_samples);
341 activate (LV2_Handle instance)
343 AReverb* self = (AReverb*)instance;
349 for (int i = 0; i < RV_NZ; ++i) {
350 self->r.delays[0][i] = NULL;
351 self->r.delays[1][i] = NULL;
356 deactivate (LV2_Handle instance)
362 cleanup (LV2_Handle instance)
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]);
373 extension_data (const char* uri)
378 static const LV2_Descriptor descriptor = {
379 "urn:ardour:a-reverb",
390 const LV2_Descriptor*
391 lv2_descriptor (uint32_t index)