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