1 /* -*- linux-c -*-
2 Copyright (C) 2004 Tom Szilagyi
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (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 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 $Id: tap_reverb.c,v 1.13 2004/06/15 14:50:55 tszilagyi Exp $
19 */
20
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26
27 #include "ladspa.h"
28
29
30 /* ***** VERY IMPORTANT! *****
31 *
32 * If you enable this, the plugin will use float arithmetics in DSP
33 * calculations. This usually yields lower average CPU usage, but
34 * occasionaly may result in high CPU peaks which cause trouble to you
35 * and your JACK server. The default is to use fixpoint arithmetics
36 * (with the following #define commented out). But (depending on the
37 * processor on which you run the code) you may find floating point
38 * mode usable.
39 */
40 /* #define REVERB_CALC_FLOAT */
41
42
43
44 #ifndef REVERB_CALC_FLOAT
45 typedef signed int sample;
46 #endif
47
48 #ifndef REVERB_CALC_FLOAT
49 typedef sample rev_t;
50 #else
51 typedef LADSPA_Data rev_t;
52 #endif
53
54
55 #include "tap_reverb_presets.h"
56
57
58
59 #ifdef REVERB_CALC_FLOAT
60 #define DENORM(x) (((unsigned char)(((*(unsigned int*)&(x))&0x7f800000)>>23))<103)?0.0f:(x)
61 #else
62 /* coefficient for float to sample (signed int) conversion */
63 /* this allows for about 60 dB headroom above 0dB, if 0 dB is equivalent to 1.0f */
64 /* As 2^31 equals more than 180 dB, about 120 dB dynamics remains below 0 dB */
65 #define F2S 2147483
66 #endif
67
68
69 /* load plugin data from reverb_data[] into an instance */
70 void
load_plugin_data(LADSPA_Handle Instance)71 load_plugin_data(LADSPA_Handle Instance) {
72
73 Reverb * ptr = (Reverb *)Instance;
74 unsigned long m;
75 int i;
76
77
78 m = LIMIT(*(ptr->mode),0,NUM_MODES-1);
79
80 /* load combs data */
81 ptr->num_combs = 2 * reverb_data[m].num_combs;
82 for (i = 0; i < reverb_data[m].num_combs; i++) {
83 ((COMB_FILTER *)(ptr->combs + 2*i))->buflen =
84 reverb_data[m].combs[i].delay * ptr->sample_rate;
85 ((COMB_FILTER *)(ptr->combs + 2*i))->feedback =
86 reverb_data[m].combs[i].feedback;
87 ((COMB_FILTER *)(ptr->combs + 2*i))->freq_resp =
88 LIMIT(reverb_data[m].combs[i].freq_resp
89 * powf(ptr->sample_rate / 44100.0f, 0.8f),
90 0.0f, 1.0f);
91
92 ((COMB_FILTER *)(ptr->combs + 2*i+1))->buflen =
93 ((COMB_FILTER *)(ptr->combs + 2*i))->buflen;
94 ((COMB_FILTER *)(ptr->combs + 2*i+1))->feedback =
95 ((COMB_FILTER *)(ptr->combs + 2*i))->feedback;
96 ((COMB_FILTER *)(ptr->combs + 2*i+1))->feedback =
97 ((COMB_FILTER *)(ptr->combs + 2*i))->freq_resp;
98
99 /* set initial values: */
100 *(((COMB_FILTER *)(ptr->combs + 2*i))->buffer_pos) = 0;
101 *(((COMB_FILTER *)(ptr->combs + 2*i+1))->buffer_pos) = 0;
102 ((COMB_FILTER *)(ptr->combs + 2*i))->last_out = 0;
103 ((COMB_FILTER *)(ptr->combs + 2*i+1))->last_out = 0;
104
105 lp_set_params(((COMB_FILTER *)(ptr->combs + 2*i))->filter,
106 2000.0f + 13000.0f * (1 - reverb_data[m].combs[i].freq_resp)
107 * ptr->sample_rate / 44100.0f,
108 BANDPASS_BWIDTH, ptr->sample_rate);
109 lp_set_params(((COMB_FILTER *)(ptr->combs + 2*i+1))->filter,
110 2000.0f + 13000.0f * (1 - reverb_data[m].combs[i].freq_resp)
111 * ptr->sample_rate / 44100.0f,
112 BANDPASS_BWIDTH, ptr->sample_rate);
113 }
114
115 /* load allps data */
116 ptr->num_allps = 2 * reverb_data[m].num_allps;
117 for (i = 0; i < reverb_data[m].num_allps; i++) {
118 ((ALLP_FILTER *)(ptr->allps + 2*i))->buflen =
119 reverb_data[m].allps[i].delay * ptr->sample_rate;
120 ((ALLP_FILTER *)(ptr->allps + 2*i))->feedback =
121 reverb_data[m].allps[i].feedback;
122
123 ((ALLP_FILTER *)(ptr->allps + 2*i+1))->buflen =
124 ((ALLP_FILTER *)(ptr->allps + 2*i))->buflen;
125 ((ALLP_FILTER *)(ptr->allps + 2*i+1))->feedback =
126 ((ALLP_FILTER *)(ptr->allps + 2*i))->feedback;
127
128 /* set initial values: */
129 *(((ALLP_FILTER *)(ptr->allps + 2*i))->buffer_pos) = 0;
130 *(((ALLP_FILTER *)(ptr->allps + 2*i+1))->buffer_pos) = 0;
131 ((ALLP_FILTER *)(ptr->allps + 2*i))->last_out = 0;
132 ((ALLP_FILTER *)(ptr->allps + 2*i+1))->last_out = 0;
133 }
134
135 /* init bandpass filters */
136 lp_set_params((biquad *)(ptr->low_pass), reverb_data[m].bandpass_high,
137 BANDPASS_BWIDTH, ptr->sample_rate);
138 hp_set_params((biquad *)(ptr->high_pass), reverb_data[m].bandpass_low,
139 BANDPASS_BWIDTH, ptr->sample_rate);
140 lp_set_params((biquad *)(ptr->low_pass + 1), reverb_data[m].bandpass_high,
141 BANDPASS_BWIDTH, ptr->sample_rate);
142 hp_set_params((biquad *)(ptr->high_pass + 1), reverb_data[m].bandpass_low,
143 BANDPASS_BWIDTH, ptr->sample_rate);
144 }
145
146
147
148 /* push a sample into a comb filter and return the sample falling out */
149 rev_t
comb_run(rev_t insample,COMB_FILTER * comb)150 comb_run(rev_t insample, COMB_FILTER * comb) {
151
152 rev_t outsample;
153 rev_t pushin;
154
155 pushin = comb->fb_gain * insample + biquad_run(comb->filter, comb->fb_gain * comb->last_out);
156 #ifdef REVERB_CALC_FLOAT
157 pushin = DENORM(pushin);
158 #endif
159 outsample = push_buffer(pushin,
160 comb->ringbuffer, comb->buflen, comb->buffer_pos);
161 #ifdef REVERB_CALC_FLOAT
162 outsample = DENORM(outsample);
163 #endif
164 comb->last_out = outsample;
165
166 return outsample;
167 }
168
169
170 /* push a sample into an allpass filter and return the sample falling out */
171 rev_t
allp_run(rev_t insample,ALLP_FILTER * allp)172 allp_run(rev_t insample, ALLP_FILTER * allp) {
173
174 rev_t outsample;
175 rev_t pushin;
176 pushin = allp->in_gain * allp->fb_gain * insample + allp->fb_gain * allp->last_out;
177 #ifdef REVERB_CALC_FLOAT
178 pushin = DENORM(pushin);
179 #endif
180 outsample = push_buffer(pushin,
181 allp->ringbuffer, allp->buflen, allp->buffer_pos);
182 #ifdef REVERB_CALC_FLOAT
183 outsample = DENORM(outsample);
184 #endif
185 allp->last_out = outsample;
186
187 return outsample;
188 }
189
190
191 /* compute user-input-dependent reverberator coefficients */
192 void
comp_coeffs(LADSPA_Handle Instance)193 comp_coeffs(LADSPA_Handle Instance) {
194
195 Reverb * ptr = (Reverb *)Instance;
196 int i;
197
198
199 if (*(ptr->mode) != ptr->old_mode)
200 load_plugin_data(Instance);
201
202 for (i = 0; i < ptr->num_combs / 2; i++) {
203 ((COMB_FILTER *)(ptr->combs + 2*i))->fb_gain =
204 powf(0.001f,
205 1000.0f * ((COMB_FILTER *)(ptr->combs + 2*i))->buflen
206 * (1 + FR_R_COMP * ((COMB_FILTER *)(ptr->combs + 2*i))->freq_resp)
207 / powf(((COMB_FILTER *)(ptr->combs + 2*i))->feedback/100.0f, 0.89f)
208 / *(ptr->decay)
209 / ptr->sample_rate);
210
211 ((COMB_FILTER *)(ptr->combs + 2*i+1))->fb_gain =
212 ((COMB_FILTER *)(ptr->combs + 2*i))->fb_gain;
213
214 if (*(ptr->stereo_enh) > 0.0f) {
215 if (i % 2 == 0)
216 ((COMB_FILTER *)(ptr->combs + 2*i+1))->buflen =
217 ENH_STEREO_RATIO * ((COMB_FILTER *)(ptr->combs + 2*i))->buflen;
218 else
219 ((COMB_FILTER *)(ptr->combs + 2*i))->buflen =
220 ENH_STEREO_RATIO * ((COMB_FILTER *)(ptr->combs + 2*i+1))->buflen;
221 } else {
222 if (i % 2 == 0)
223 ((COMB_FILTER *)(ptr->combs + 2*i+1))->buflen =
224 ((COMB_FILTER *)(ptr->combs + 2*i))->buflen;
225 else
226 ((COMB_FILTER *)(ptr->combs + 2*i))->buflen =
227 ((COMB_FILTER *)(ptr->combs + 2*i+1))->buflen;
228 }
229 }
230
231 for (i = 0; i < ptr->num_allps / 2; i++) {
232 ((ALLP_FILTER *)(ptr->allps + 2*i))->fb_gain =
233 powf(0.001f, 11000.0f * ((ALLP_FILTER *)(ptr->allps + 2*i))->buflen
234 / powf(((ALLP_FILTER *)(ptr->allps + 2*i))->feedback/100.0f, 0.88f)
235 / *(ptr->decay)
236 / ptr->sample_rate);
237
238 ((ALLP_FILTER *)(ptr->allps + 2*i+1))->fb_gain =
239 ((ALLP_FILTER *)(ptr->allps + 2*i))->fb_gain;
240
241 ((ALLP_FILTER *)(ptr->allps + 2*i))->in_gain = -0.06f
242 / (((ALLP_FILTER *)(ptr->allps + 2 * i))->feedback/100.0f)
243 / powf((*(ptr->decay) + 3500.0f) / 10000.0f, 1.5f);
244
245 ((ALLP_FILTER *)(ptr->allps + 2*i+1))->in_gain =
246 ((ALLP_FILTER *)(ptr->allps + 2*i))->in_gain;
247
248 if (*(ptr->stereo_enh) > 0.0f) {
249 if (i % 2 == 0)
250 ((ALLP_FILTER *)(ptr->allps + 2*i+1))->buflen =
251 ENH_STEREO_RATIO * ((ALLP_FILTER *)(ptr->allps + 2*i))->buflen;
252 else
253 ((ALLP_FILTER *)(ptr->allps + 2*i))->buflen =
254 ENH_STEREO_RATIO * ((ALLP_FILTER *)(ptr->allps + 2*i+1))->buflen;
255 } else {
256 if (i % 2 == 0)
257 ((ALLP_FILTER *)(ptr->allps + 2*i+1))->buflen =
258 ((ALLP_FILTER *)(ptr->allps + 2*i))->buflen;
259 else
260 ((ALLP_FILTER *)(ptr->allps + 2*i))->buflen =
261 ((ALLP_FILTER *)(ptr->allps + 2*i+1))->buflen;
262 }
263 }
264 }
265
266
267
268 /* Construct a new plugin instance. */
269 LADSPA_Handle
instantiate_Reverb(const LADSPA_Descriptor * Descriptor,unsigned long SampleRate)270 instantiate_Reverb(const LADSPA_Descriptor * Descriptor,
271 unsigned long SampleRate) {
272
273 unsigned long i;
274 LADSPA_Handle * p;
275 Reverb * ptr = NULL;
276
277 if ((p = malloc(sizeof(Reverb))) != NULL) {
278 ((Reverb *)p)->sample_rate = SampleRate;
279 ((Reverb *)p)->run_adding_gain = 1.0f;
280
281 ptr = (Reverb *)p;
282
283 /* allocate memory for comb/allpass filters and other dynamic vars */
284 if ((ptr->combs =
285 calloc(2 * MAX_COMBS, sizeof(COMB_FILTER))) == NULL)
286 return NULL;
287 for (i = 0; i < 2 * MAX_COMBS; i++) {
288 if ((((COMB_FILTER *)(ptr->combs + i))->ringbuffer =
289 calloc((unsigned long)MAX_COMB_DELAY * ptr->sample_rate / 1000,
290 sizeof(LADSPA_Data))) == NULL)
291 return NULL;
292 if ((((COMB_FILTER *)(ptr->combs + i))->buffer_pos =
293 calloc(1, sizeof(unsigned long))) == NULL)
294 return NULL;
295 if ((((COMB_FILTER *)(ptr->combs + i))->filter =
296 calloc(1, sizeof(biquad))) == NULL)
297 return NULL;
298 }
299
300 if ((ptr->allps =
301 calloc(2 * MAX_ALLPS, sizeof(ALLP_FILTER))) == NULL)
302 return NULL;
303 for (i = 0; i < 2 * MAX_ALLPS; i++) {
304 if ((((ALLP_FILTER *)(ptr->allps + i))->ringbuffer =
305 calloc((unsigned long)MAX_ALLP_DELAY * ptr->sample_rate / 1000,
306 sizeof(LADSPA_Data))) == NULL)
307 return NULL;
308 if ((((ALLP_FILTER *)(ptr->allps + i))->buffer_pos =
309 calloc(1, sizeof(unsigned long))) == NULL)
310 return NULL;
311 }
312
313 if ((ptr->low_pass =
314 calloc(2, sizeof(biquad))) == NULL)
315 return NULL;
316 if ((ptr->high_pass =
317 calloc(2, sizeof(biquad))) == NULL)
318 return NULL;
319
320 return p;
321 }
322 return NULL;
323 }
324
325
326 /* activate a plugin instance */
327 void
activate_Reverb(LADSPA_Handle Instance)328 activate_Reverb(LADSPA_Handle Instance) {
329
330 Reverb * ptr = (Reverb *)Instance;
331 unsigned long i,j;
332
333 for (i = 0; i < 2 * MAX_COMBS; i++) {
334 for (j = 0; j < (unsigned long)MAX_COMB_DELAY * ptr->sample_rate / 1000; j++)
335 ((COMB_FILTER *)(ptr->combs + i))->ringbuffer[j] = 0.0f;
336 *(((COMB_FILTER *)(ptr->combs + i))->buffer_pos) = 0;
337 ((COMB_FILTER *)(ptr->combs + i))->last_out = 0;
338 biquad_init(((COMB_FILTER *)(ptr->combs + i))->filter);
339 }
340
341 for (i = 0; i < 2 * MAX_ALLPS; i++) {
342 for (j = 0; j < (unsigned long)MAX_ALLP_DELAY * ptr->sample_rate / 1000; j++)
343 ((ALLP_FILTER *)(ptr->allps + i))->ringbuffer[j] = 0.0f;
344 *(((ALLP_FILTER *)(ptr->allps + i))->buffer_pos) = 0;
345 ((ALLP_FILTER *)(ptr->allps + i))->last_out = 0;
346 }
347
348 biquad_init(ptr->low_pass);
349 biquad_init((biquad *)(ptr->low_pass + 1));
350 biquad_init(ptr->high_pass);
351 biquad_init((biquad *)(ptr->high_pass + 1));
352
353 ptr->old_decay = -10.0f;
354 ptr->old_stereo_enh = -10.0f;
355 ptr->old_mode = -10.0f;
356 }
357
358
359
360 /* Connect a port to a data location. */
361 void
connect_port_Reverb(LADSPA_Handle Instance,unsigned long Port,LADSPA_Data * DataLocation)362 connect_port_Reverb(LADSPA_Handle Instance,
363 unsigned long Port,
364 LADSPA_Data * DataLocation) {
365
366 Reverb * ptr = (Reverb *)Instance;
367
368 switch (Port) {
369 case DECAY:
370 ptr->decay = DataLocation;
371 break;
372 case DRYLEVEL:
373 ptr->drylevel = DataLocation;
374 break;
375 case WETLEVEL:
376 ptr->wetlevel = DataLocation;
377 break;
378 case COMBS_EN:
379 ptr->combs_en = DataLocation;
380 break;
381 case ALLPS_EN:
382 ptr->allps_en = DataLocation;
383 break;
384 case BANDPASS_EN:
385 ptr->bandpass_en = DataLocation;
386 break;
387 case STEREO_ENH:
388 ptr->stereo_enh = DataLocation;
389 break;
390 case MODE:
391 ptr->mode = DataLocation;
392 break;
393 case INPUT_L:
394 ptr->input_L = DataLocation;
395 break;
396 case OUTPUT_L:
397 ptr->output_L = DataLocation;
398 break;
399 case INPUT_R:
400 ptr->input_R = DataLocation;
401 break;
402 case OUTPUT_R:
403 ptr->output_R = DataLocation;
404 break;
405 }
406 }
407
408
409
410 void
run_Reverb(LADSPA_Handle Instance,unsigned long SampleCount)411 run_Reverb(LADSPA_Handle Instance,
412 unsigned long SampleCount) {
413
414 Reverb * ptr = (Reverb *)Instance;
415
416 unsigned long sample_index;
417 int i;
418
419 LADSPA_Data decay = LIMIT(*(ptr->decay),0.0f,10000.0f);
420 LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-70.0f,10.0f));
421 LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-70.0f,10.0f));
422 LADSPA_Data combs_en = LIMIT(*(ptr->combs_en),-2.0f,2.0f);
423 LADSPA_Data allps_en = LIMIT(*(ptr->allps_en),-2.0f,2.0f);
424 LADSPA_Data bandpass_en = LIMIT(*(ptr->bandpass_en),-2.0f,2.0f);
425 LADSPA_Data stereo_enh = LIMIT(*(ptr->stereo_enh),-2.0f,2.0f);
426 LADSPA_Data mode = LIMIT(*(ptr->mode),0,NUM_MODES-1);
427
428 LADSPA_Data * input_L = ptr->input_L;
429 LADSPA_Data * output_L = ptr->output_L;
430 LADSPA_Data * input_R = ptr->input_R;
431 LADSPA_Data * output_R = ptr->output_R;
432
433 rev_t out_L = 0;
434 rev_t out_R = 0;
435 rev_t in_L = 0;
436 rev_t in_R = 0;
437 rev_t combs_out_L = 0;
438 rev_t combs_out_R = 0;
439
440
441 /* see if the user changed any control since last run */
442 if ((ptr->old_decay != decay) ||
443 (ptr->old_stereo_enh != stereo_enh) ||
444 (ptr->old_mode != mode)) {
445
446 /* re-compute reverberator coefficients */
447 comp_coeffs(Instance);
448
449 /* save new values */
450 ptr->old_decay = decay;
451 ptr->old_stereo_enh = stereo_enh;
452 ptr->old_mode = mode;
453 }
454
455 for (sample_index = 0; sample_index < SampleCount; sample_index++) {
456
457 #ifdef REVERB_CALC_FLOAT
458 in_L = *(input_L++);
459 in_R = *(input_R++);
460 #else
461 in_L = (sample)((float)F2S * *(input_L++));
462 in_R = (sample)((float)F2S * *(input_R++));
463 #endif
464
465 combs_out_L = in_L;
466 combs_out_R = in_R;
467
468 /* process comb filters */
469 if (combs_en > 0.0f) {
470 for (i = 0; i < ptr->num_combs / 2; i++) {
471 combs_out_L +=
472 comb_run(in_L, ((COMB_FILTER *)(ptr->combs + 2*i)));
473 combs_out_R +=
474 comb_run(in_R, ((COMB_FILTER *)(ptr->combs + 2*i+1)));
475 }
476 }
477
478 /* process allpass filters */
479 if (allps_en > 0.0f) {
480 for (i = 0; i < ptr->num_allps / 2; i++) {
481 combs_out_L += allp_run(combs_out_L,
482 ((ALLP_FILTER *)(ptr->allps + 2*i)));
483 combs_out_R += allp_run(combs_out_R,
484 ((ALLP_FILTER *)(ptr->allps + 2*i+1)));
485 }
486 }
487
488 /* process bandpass filters */
489 if (bandpass_en > 0.0f) {
490 combs_out_L =
491 biquad_run(((biquad *)(ptr->low_pass)), combs_out_L);
492 combs_out_L =
493 biquad_run(((biquad *)(ptr->high_pass)), combs_out_L);
494 combs_out_R =
495 biquad_run(((biquad *)(ptr->low_pass + 1)), combs_out_R);
496 combs_out_R =
497 biquad_run(((biquad *)(ptr->high_pass + 1)), combs_out_R);
498 }
499
500 #ifdef REVERB_CALC_FLOAT
501 out_L = in_L * drylevel + combs_out_L * wetlevel;
502 out_R = in_R * drylevel + combs_out_R * wetlevel;
503 *(output_L++) = out_L;
504 *(output_R++) = out_R;
505 #else
506 out_L = (sample)((float)in_L * drylevel + (float)combs_out_L * wetlevel);
507 out_R = (sample)((float)in_R * drylevel + (float)combs_out_R * wetlevel);
508 *(output_L++) = (float)out_L / (float)F2S;
509 *(output_R++) = (float)out_R / (float)F2S;
510 #endif
511 }
512 }
513
514
515
516
517
518 void
set_run_adding_gain(LADSPA_Handle Instance,LADSPA_Data gain)519 set_run_adding_gain(LADSPA_Handle Instance, LADSPA_Data gain){
520
521 Reverb * ptr;
522
523 ptr = (Reverb *)Instance;
524
525 ptr->run_adding_gain = gain;
526 }
527
528
529 void
run_adding_gain_Reverb(LADSPA_Handle Instance,unsigned long SampleCount)530 run_adding_gain_Reverb(LADSPA_Handle Instance,
531 unsigned long SampleCount) {
532
533 Reverb * ptr = (Reverb *)Instance;
534
535 unsigned long sample_index;
536 int i;
537
538 LADSPA_Data decay = LIMIT(*(ptr->decay),0.0f,10000.0f);
539 LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-70.0f,10.0f));
540 LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-70.0f,10.0f));
541 LADSPA_Data combs_en = LIMIT(*(ptr->combs_en),-2.0f,2.0f);
542 LADSPA_Data allps_en = LIMIT(*(ptr->allps_en),-2.0f,2.0f);
543 LADSPA_Data bandpass_en = LIMIT(*(ptr->bandpass_en),-2.0f,2.0f);
544 LADSPA_Data stereo_enh = LIMIT(*(ptr->stereo_enh),-2.0f,2.0f);
545 LADSPA_Data mode = LIMIT(*(ptr->mode),0,NUM_MODES-1);
546
547 LADSPA_Data * input_L = ptr->input_L;
548 LADSPA_Data * output_L = ptr->output_L;
549 LADSPA_Data * input_R = ptr->input_R;
550 LADSPA_Data * output_R = ptr->output_R;
551
552 rev_t out_L = 0;
553 rev_t out_R = 0;
554 rev_t in_L = 0;
555 rev_t in_R = 0;
556 rev_t combs_out_L = 0;
557 rev_t combs_out_R = 0;
558
559
560 /* see if the user changed any control since last run */
561 if ((ptr->old_decay != decay) ||
562 (ptr->old_stereo_enh != stereo_enh) ||
563 (ptr->old_mode != mode)) {
564
565 /* re-compute reverberator coefficients */
566 comp_coeffs(Instance);
567
568 /* save new values */
569 ptr->old_decay = decay;
570 ptr->old_stereo_enh = stereo_enh;
571 ptr->old_mode = mode;
572 }
573
574 for (sample_index = 0; sample_index < SampleCount; sample_index++) {
575
576 #ifdef REVERB_CALC_FLOAT
577 in_L = *(input_L++);
578 in_R = *(input_R++);
579 #else
580 in_L = (sample)((float)F2S * *(input_L++));
581 in_R = (sample)((float)F2S * *(input_R++));
582 #endif
583
584 combs_out_L = in_L;
585 combs_out_R = in_R;
586
587 /* process comb filters */
588 if (combs_en > 0.0f) {
589 for (i = 0; i < ptr->num_combs / 2; i++) {
590 combs_out_L +=
591 comb_run(in_L, ((COMB_FILTER *)(ptr->combs + 2*i)));
592 combs_out_R +=
593 comb_run(in_R, ((COMB_FILTER *)(ptr->combs + 2*i+1)));
594 }
595 }
596
597 /* process allpass filters */
598 if (allps_en > 0.0f) {
599 for (i = 0; i < ptr->num_allps / 2; i++) {
600 combs_out_L += allp_run(combs_out_L,
601 ((ALLP_FILTER *)(ptr->allps + 2*i)));
602 combs_out_R += allp_run(combs_out_R,
603 ((ALLP_FILTER *)(ptr->allps + 2*i+1)));
604 }
605 }
606
607 /* process bandpass filters */
608 if (bandpass_en > 0.0f) {
609 combs_out_L =
610 biquad_run(((biquad *)(ptr->low_pass)), combs_out_L);
611 combs_out_L =
612 biquad_run(((biquad *)(ptr->high_pass)), combs_out_L);
613 combs_out_R =
614 biquad_run(((biquad *)(ptr->low_pass + 1)), combs_out_R);
615 combs_out_R =
616 biquad_run(((biquad *)(ptr->high_pass + 1)), combs_out_R);
617 }
618
619 #ifdef REVERB_CALC_FLOAT
620 out_L = in_L * drylevel + combs_out_L * wetlevel;
621 out_R = in_R * drylevel + combs_out_R * wetlevel;
622 *(output_L++) += out_L * ptr->run_adding_gain;
623 *(output_R++) += out_R * ptr->run_adding_gain;
624 #else
625 out_L = (sample)((float)in_L * drylevel + (float)combs_out_L * wetlevel);
626 out_R = (sample)((float)in_R * drylevel + (float)combs_out_R * wetlevel);
627 *(output_L++) += (float)out_L * ptr->run_adding_gain / (float)F2S;
628 *(output_R++) += (float)out_R * ptr->run_adding_gain / (float)F2S;
629 #endif
630 }
631 }
632
633
634
635 /* Throw away a Reverb effect instance. */
636 void
cleanup_Reverb(LADSPA_Handle Instance)637 cleanup_Reverb(LADSPA_Handle Instance) {
638
639 int i;
640 Reverb * ptr = (Reverb *)Instance;
641
642 /* free memory allocated for comb/allpass filters & co. in instantiate_Reverb() */
643 for (i = 0; i < 2 * MAX_COMBS; i++) {
644 free(((COMB_FILTER *)(ptr->combs + i))->ringbuffer);
645 free(((COMB_FILTER *)(ptr->combs + i))->buffer_pos);
646 free(((COMB_FILTER *)(ptr->combs + i))->filter);
647 }
648 for (i = 0; i < 2 * MAX_ALLPS; i++) {
649 free(((ALLP_FILTER *)(ptr->allps + i))->ringbuffer);
650 free(((ALLP_FILTER *)(ptr->allps + i))->buffer_pos);
651 }
652
653 free(ptr->combs);
654 free(ptr->allps);
655 free(ptr->low_pass);
656 free(ptr->high_pass);
657
658 free(Instance);
659
660 }
661
662
663
664 LADSPA_Descriptor * stereo_descriptor = NULL;
665
666
667
668 /* _init() is called automatically when the plugin library is first
669 loaded. */
670 void
_init()671 _init() {
672
673 char ** port_names;
674 LADSPA_PortDescriptor * port_descriptors;
675 LADSPA_PortRangeHint * port_range_hints;
676
677
678 if ((stereo_descriptor =
679 (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
680 exit(1);
681
682
683 /* init the stereo Reverb */
684
685 stereo_descriptor->UniqueID = ID_STEREO;
686 stereo_descriptor->Label = strdup("tap_reverb");
687 stereo_descriptor->Properties = 0;
688 stereo_descriptor->Name = strdup("TAP Reverberator");
689 stereo_descriptor->Maker = strdup("Tom Szilagyi");
690 stereo_descriptor->Copyright = strdup("GPL");
691 stereo_descriptor->PortCount = PORTCOUNT_STEREO;
692
693 if ((port_descriptors =
694 (LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
695 exit(1);
696
697 stereo_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
698 port_descriptors[DECAY] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
699 port_descriptors[DRYLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
700 port_descriptors[WETLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
701 port_descriptors[COMBS_EN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
702 port_descriptors[ALLPS_EN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
703 port_descriptors[BANDPASS_EN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
704 port_descriptors[STEREO_ENH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
705 port_descriptors[MODE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
706
707 port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
708 port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
709 port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
710 port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
711
712 if ((port_names =
713 (char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
714 exit(1);
715
716 stereo_descriptor->PortNames = (const char **)port_names;
717
718 port_names[DECAY] = strdup("Decay [ms]");
719 port_names[DRYLEVEL] = strdup("Dry Level [dB]");
720 port_names[WETLEVEL] = strdup("Wet Level [dB]");
721 port_names[COMBS_EN] = strdup("Comb Filters");
722 port_names[ALLPS_EN] = strdup("Allpass Filters");
723 port_names[BANDPASS_EN] = strdup("Bandpass Filter");
724 port_names[STEREO_ENH] = strdup("Enhanced Stereo");
725 port_names[MODE] = strdup("Reverb Type");
726 port_names[INPUT_L] = strdup("Input Left");
727 port_names[OUTPUT_L] = strdup("Output Left");
728 port_names[INPUT_R] = strdup("Input Right");
729 port_names[OUTPUT_R] = strdup("Output Right");
730
731 if ((port_range_hints =
732 ((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
733 exit(1);
734
735 stereo_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
736
737 port_range_hints[DECAY].HintDescriptor =
738 (LADSPA_HINT_BOUNDED_BELOW |
739 LADSPA_HINT_BOUNDED_ABOVE |
740 LADSPA_HINT_DEFAULT_LOW);
741 port_range_hints[DECAY].LowerBound = 0;
742 port_range_hints[DECAY].UpperBound = MAX_DECAY;
743
744 port_range_hints[DRYLEVEL].HintDescriptor =
745 (LADSPA_HINT_BOUNDED_BELOW |
746 LADSPA_HINT_BOUNDED_ABOVE |
747 LADSPA_HINT_DEFAULT_0);
748 port_range_hints[DRYLEVEL].LowerBound = -70.0f;
749 port_range_hints[DRYLEVEL].UpperBound = +10.0f;
750
751 port_range_hints[WETLEVEL].HintDescriptor =
752 (LADSPA_HINT_BOUNDED_BELOW |
753 LADSPA_HINT_BOUNDED_ABOVE |
754 LADSPA_HINT_DEFAULT_0);
755 port_range_hints[WETLEVEL].LowerBound = -70.0f;
756 port_range_hints[WETLEVEL].UpperBound = +10.0f;
757
758 port_range_hints[COMBS_EN].HintDescriptor =
759 (LADSPA_HINT_TOGGLED |
760 LADSPA_HINT_DEFAULT_1);
761
762 port_range_hints[ALLPS_EN].HintDescriptor =
763 (LADSPA_HINT_TOGGLED |
764 LADSPA_HINT_DEFAULT_1);
765
766 port_range_hints[BANDPASS_EN].HintDescriptor =
767 (LADSPA_HINT_TOGGLED |
768 LADSPA_HINT_DEFAULT_1);
769
770 port_range_hints[STEREO_ENH].HintDescriptor =
771 (LADSPA_HINT_TOGGLED |
772 LADSPA_HINT_DEFAULT_1);
773
774 port_range_hints[MODE].HintDescriptor =
775 (LADSPA_HINT_BOUNDED_BELOW |
776 LADSPA_HINT_BOUNDED_ABOVE |
777 LADSPA_HINT_INTEGER |
778 LADSPA_HINT_DEFAULT_0);
779 port_range_hints[MODE].LowerBound = 0;
780 port_range_hints[MODE].UpperBound = NUM_MODES - 0.9f;
781
782 port_range_hints[INPUT_L].HintDescriptor = 0;
783 port_range_hints[OUTPUT_L].HintDescriptor = 0;
784 port_range_hints[INPUT_R].HintDescriptor = 0;
785 port_range_hints[OUTPUT_R].HintDescriptor = 0;
786
787
788 stereo_descriptor->instantiate = instantiate_Reverb;
789 stereo_descriptor->connect_port = connect_port_Reverb;
790 stereo_descriptor->activate = activate_Reverb;
791 stereo_descriptor->run = run_Reverb;
792 stereo_descriptor->run_adding = run_adding_gain_Reverb;
793 stereo_descriptor->set_run_adding_gain = set_run_adding_gain;
794 stereo_descriptor->deactivate = NULL;
795 stereo_descriptor->cleanup = cleanup_Reverb;
796
797 }
798
799
800 void
delete_descriptor(LADSPA_Descriptor * descriptor)801 delete_descriptor(LADSPA_Descriptor * descriptor) {
802 unsigned long index;
803 if (descriptor) {
804 free((char *)descriptor->Label);
805 free((char *)descriptor->Name);
806 free((char *)descriptor->Maker);
807 free((char *)descriptor->Copyright);
808 free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
809 for (index = 0; index < descriptor->PortCount; index++)
810 free((char *)(descriptor->PortNames[index]));
811 free((char **)descriptor->PortNames);
812 free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
813 free(descriptor);
814 }
815 }
816
817
818 /* _fini() is called automatically when the library is unloaded. */
819 void
_fini()820 _fini() {
821 delete_descriptor(stereo_descriptor);
822 }
823
824
825 /* Return a descriptor of the requested plugin type. */
826 const LADSPA_Descriptor *
ladspa_descriptor(unsigned long Index)827 ladspa_descriptor(unsigned long Index) {
828
829 switch (Index) {
830 case 0:
831 return stereo_descriptor;
832 default:
833 return NULL;
834 }
835 }
836