1 #include <stdlib.h>
2 #include <string.h>
3 #ifndef WIN32
4 #include "config.h"
5 #endif
6 
7 #ifdef ENABLE_NLS
8 #include <libintl.h>
9 #endif
10 
11 #define         _ISOC9X_SOURCE  1
12 #define         _ISOC99_SOURCE  1
13 #define         __USE_ISOC99    1
14 #define         __USE_ISOC9X    1
15 
16 #include <math.h>
17 
18 #include "ladspa.h"
19 
20 #ifdef WIN32
21 #define _WINDOWS_DLL_EXPORT_ __declspec(dllexport)
22 int bIsFirstTime = 1;
23 static void __attribute__((constructor)) swh_init(); // forward declaration
24 #else
25 #define _WINDOWS_DLL_EXPORT_
26 #endif
27 
28 #line 10 "lcr_delay_1436.xml"
29 
30 #include "ladspa-util.h"
31 #include "util/biquad.h"
32 
33 #define LCRDELAY_LDEL                  0
34 #define LCRDELAY_LLEV                  1
35 #define LCRDELAY_CDEL                  2
36 #define LCRDELAY_CLEV                  3
37 #define LCRDELAY_RDEL                  4
38 #define LCRDELAY_RLEV                  5
39 #define LCRDELAY_FEEDBACK              6
40 #define LCRDELAY_HIGH_D                7
41 #define LCRDELAY_LOW_D                 8
42 #define LCRDELAY_SPREAD                9
43 #define LCRDELAY_WET                   10
44 #define LCRDELAY_IN_L                  11
45 #define LCRDELAY_IN_R                  12
46 #define LCRDELAY_OUT_L                 13
47 #define LCRDELAY_OUT_R                 14
48 
49 static LADSPA_Descriptor *lcrDelayDescriptor = NULL;
50 
51 typedef struct {
52 	LADSPA_Data *ldel;
53 	LADSPA_Data *llev;
54 	LADSPA_Data *cdel;
55 	LADSPA_Data *clev;
56 	LADSPA_Data *rdel;
57 	LADSPA_Data *rlev;
58 	LADSPA_Data *feedback;
59 	LADSPA_Data *high_d;
60 	LADSPA_Data *low_d;
61 	LADSPA_Data *spread;
62 	LADSPA_Data *wet;
63 	LADSPA_Data *in_l;
64 	LADSPA_Data *in_r;
65 	LADSPA_Data *out_l;
66 	LADSPA_Data *out_r;
67 	LADSPA_Data *buffer;
68 	unsigned int buffer_mask;
69 	unsigned int buffer_pos;
70 	biquad *     filters;
71 	float        fs;
72 	float        last_cd;
73 	float        last_cl;
74 	float        last_ld;
75 	float        last_ll;
76 	float        last_rd;
77 	float        last_rl;
78 	LADSPA_Data run_adding_gain;
79 } LcrDelay;
80 
81 _WINDOWS_DLL_EXPORT_
ladspa_descriptor(unsigned long index)82 const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) {
83 
84 #ifdef WIN32
85 	if (bIsFirstTime) {
86 		swh_init();
87 		bIsFirstTime = 0;
88 	}
89 #endif
90 	switch (index) {
91 	case 0:
92 		return lcrDelayDescriptor;
93 	default:
94 		return NULL;
95 	}
96 }
97 
activateLcrDelay(LADSPA_Handle instance)98 static void activateLcrDelay(LADSPA_Handle instance) {
99 	LcrDelay *plugin_data = (LcrDelay *)instance;
100 	LADSPA_Data *buffer = plugin_data->buffer;
101 	unsigned int buffer_mask = plugin_data->buffer_mask;
102 	unsigned int buffer_pos = plugin_data->buffer_pos;
103 	biquad *filters = plugin_data->filters;
104 	float fs = plugin_data->fs;
105 	float last_cd = plugin_data->last_cd;
106 	float last_cl = plugin_data->last_cl;
107 	float last_ld = plugin_data->last_ld;
108 	float last_ll = plugin_data->last_ll;
109 	float last_rd = plugin_data->last_rd;
110 	float last_rl = plugin_data->last_rl;
111 #line 41 "lcr_delay_1436.xml"
112 	memset(buffer, 0, (buffer_mask + 1) * sizeof(LADSPA_Data));
113 	last_ll = 0.0f;
114 	last_cl = 0.0f;
115 	last_rl = 0.0f;
116 	last_ld = 0.0f;
117 	last_cd = 0.0f;
118 	last_rd = 0.0f;
119 	biquad_init(filters);
120 	biquad_init(filters + 1);
121 	plugin_data->buffer = buffer;
122 	plugin_data->buffer_mask = buffer_mask;
123 	plugin_data->buffer_pos = buffer_pos;
124 	plugin_data->filters = filters;
125 	plugin_data->fs = fs;
126 	plugin_data->last_cd = last_cd;
127 	plugin_data->last_cl = last_cl;
128 	plugin_data->last_ld = last_ld;
129 	plugin_data->last_ll = last_ll;
130 	plugin_data->last_rd = last_rd;
131 	plugin_data->last_rl = last_rl;
132 
133 }
134 
cleanupLcrDelay(LADSPA_Handle instance)135 static void cleanupLcrDelay(LADSPA_Handle instance) {
136 #line 53 "lcr_delay_1436.xml"
137 	LcrDelay *plugin_data = (LcrDelay *)instance;
138 	free(plugin_data->filters);
139 	free(plugin_data->buffer);
140 	free(instance);
141 }
142 
connectPortLcrDelay(LADSPA_Handle instance,unsigned long port,LADSPA_Data * data)143 static void connectPortLcrDelay(
144  LADSPA_Handle instance,
145  unsigned long port,
146  LADSPA_Data *data) {
147 	LcrDelay *plugin;
148 
149 	plugin = (LcrDelay *)instance;
150 	switch (port) {
151 	case LCRDELAY_LDEL:
152 		plugin->ldel = data;
153 		break;
154 	case LCRDELAY_LLEV:
155 		plugin->llev = data;
156 		break;
157 	case LCRDELAY_CDEL:
158 		plugin->cdel = data;
159 		break;
160 	case LCRDELAY_CLEV:
161 		plugin->clev = data;
162 		break;
163 	case LCRDELAY_RDEL:
164 		plugin->rdel = data;
165 		break;
166 	case LCRDELAY_RLEV:
167 		plugin->rlev = data;
168 		break;
169 	case LCRDELAY_FEEDBACK:
170 		plugin->feedback = data;
171 		break;
172 	case LCRDELAY_HIGH_D:
173 		plugin->high_d = data;
174 		break;
175 	case LCRDELAY_LOW_D:
176 		plugin->low_d = data;
177 		break;
178 	case LCRDELAY_SPREAD:
179 		plugin->spread = data;
180 		break;
181 	case LCRDELAY_WET:
182 		plugin->wet = data;
183 		break;
184 	case LCRDELAY_IN_L:
185 		plugin->in_l = data;
186 		break;
187 	case LCRDELAY_IN_R:
188 		plugin->in_r = data;
189 		break;
190 	case LCRDELAY_OUT_L:
191 		plugin->out_l = data;
192 		break;
193 	case LCRDELAY_OUT_R:
194 		plugin->out_r = data;
195 		break;
196 	}
197 }
198 
instantiateLcrDelay(const LADSPA_Descriptor * descriptor,unsigned long s_rate)199 static LADSPA_Handle instantiateLcrDelay(
200  const LADSPA_Descriptor *descriptor,
201  unsigned long s_rate) {
202 	LcrDelay *plugin_data = (LcrDelay *)calloc(1, sizeof(LcrDelay));
203 	LADSPA_Data *buffer = NULL;
204 	unsigned int buffer_mask;
205 	unsigned int buffer_pos;
206 	biquad *filters = NULL;
207 	float fs;
208 	float last_cd;
209 	float last_cl;
210 	float last_ld;
211 	float last_ll;
212 	float last_rd;
213 	float last_rl;
214 
215 #line 21 "lcr_delay_1436.xml"
216 	int buffer_size = 32768;
217 
218 	fs = s_rate;
219 	while (buffer_size < fs * 2.7f) {
220 	  buffer_size *= 2;
221 	}
222 	buffer = calloc(buffer_size, sizeof(LADSPA_Data));
223 	buffer_mask = buffer_size - 1;
224 	buffer_pos = 0;
225 	last_ll = 0.0f;
226 	last_cl = 0.0f;
227 	last_rl = 0.0f;
228 	last_ld = 0.0f;
229 	last_cd = 0.0f;
230 	last_rd = 0.0f;
231 
232 	filters = malloc(2 * sizeof(biquad));
233 
234 	plugin_data->buffer = buffer;
235 	plugin_data->buffer_mask = buffer_mask;
236 	plugin_data->buffer_pos = buffer_pos;
237 	plugin_data->filters = filters;
238 	plugin_data->fs = fs;
239 	plugin_data->last_cd = last_cd;
240 	plugin_data->last_cl = last_cl;
241 	plugin_data->last_ld = last_ld;
242 	plugin_data->last_ll = last_ll;
243 	plugin_data->last_rd = last_rd;
244 	plugin_data->last_rl = last_rl;
245 
246 	return (LADSPA_Handle)plugin_data;
247 }
248 
249 #undef buffer_write
250 #undef RUN_ADDING
251 #undef RUN_REPLACING
252 
253 #define buffer_write(b, v) (b = v)
254 #define RUN_ADDING    0
255 #define RUN_REPLACING 1
256 
runLcrDelay(LADSPA_Handle instance,unsigned long sample_count)257 static void runLcrDelay(LADSPA_Handle instance, unsigned long sample_count) {
258 	LcrDelay *plugin_data = (LcrDelay *)instance;
259 
260 	/* L delay (ms) (float value) */
261 	const LADSPA_Data ldel = *(plugin_data->ldel);
262 
263 	/* L level (float value) */
264 	const LADSPA_Data llev = *(plugin_data->llev);
265 
266 	/* C delay (ms) (float value) */
267 	const LADSPA_Data cdel = *(plugin_data->cdel);
268 
269 	/* C level (float value) */
270 	const LADSPA_Data clev = *(plugin_data->clev);
271 
272 	/* R delay (ms) (float value) */
273 	const LADSPA_Data rdel = *(plugin_data->rdel);
274 
275 	/* R level (float value) */
276 	const LADSPA_Data rlev = *(plugin_data->rlev);
277 
278 	/* Feedback (float value) */
279 	const LADSPA_Data feedback = *(plugin_data->feedback);
280 
281 	/* High damp (%) (float value) */
282 	const LADSPA_Data high_d = *(plugin_data->high_d);
283 
284 	/* Low damp (%) (float value) */
285 	const LADSPA_Data low_d = *(plugin_data->low_d);
286 
287 	/* Spread (float value) */
288 	const LADSPA_Data spread = *(plugin_data->spread);
289 
290 	/* Dry/Wet level (float value) */
291 	const LADSPA_Data wet = *(plugin_data->wet);
292 
293 	/* L input (array of floats of length sample_count) */
294 	const LADSPA_Data * const in_l = plugin_data->in_l;
295 
296 	/* R input (array of floats of length sample_count) */
297 	const LADSPA_Data * const in_r = plugin_data->in_r;
298 
299 	/* L output (array of floats of length sample_count) */
300 	LADSPA_Data * const out_l = plugin_data->out_l;
301 
302 	/* R output (array of floats of length sample_count) */
303 	LADSPA_Data * const out_r = plugin_data->out_r;
304 	LADSPA_Data * buffer = plugin_data->buffer;
305 	unsigned int buffer_mask = plugin_data->buffer_mask;
306 	unsigned int buffer_pos = plugin_data->buffer_pos;
307 	biquad * filters = plugin_data->filters;
308 	float fs = plugin_data->fs;
309 	float last_cd = plugin_data->last_cd;
310 	float last_cl = plugin_data->last_cl;
311 	float last_ld = plugin_data->last_ld;
312 	float last_ll = plugin_data->last_ll;
313 	float last_rd = plugin_data->last_rd;
314 	float last_rl = plugin_data->last_rl;
315 
316 #line 58 "lcr_delay_1436.xml"
317 	unsigned long pos;
318 	const float sc_r = 1.0f / (float)sample_count;
319 	const float spr_t = 0.5f + spread * 0.01f;
320 	const float spr_o = 0.5f - spread * 0.01f;
321 	float fb = feedback * 0.01f;
322 	float ll, cl, rl, ld, cd, rd;
323 	float ll_d, cl_d, rl_d, ld_d, cd_d, rd_d;
324 	float left, right;
325 	float fbs; /* Feedback signal */
326 
327 	if (fb < -0.99f) {
328 	  fb = -0.99f;
329 	} else if (fb > 0.99f) {
330 	  fb = 0.99f;
331 	}
332 
333 	ls_set_params(filters, fs * 0.0001f * powf(2.0f, low_d * 0.12f),
334 	              -0.5f * low_d, 0.5f, fs);
335 	hs_set_params(filters + 1, fs * (0.41f - 0.0001f *
336 	              powf(2.0f, high_d * 0.12f)), -70.0f, 0.9f, fs);
337 
338 	ll = last_ll;                                /* Start value of Left Level */
339 	ll_d = (llev * 0.01f - last_ll) * sc_r;         /* Delta for Left Level */
340 	cl = last_cl;
341 	cl_d = (clev * 0.01f - last_cl) * sc_r;
342 	rl = last_rl;
343 	rl_d = (rlev * 0.01f - last_rl) * sc_r;
344 
345 	ld = last_ld;
346 	ld_d = (ldel * fs * 0.001f - last_ld) * sc_r;
347 	cd = last_cd;
348 	cd_d = (cdel * fs * 0.001f - last_cd) * sc_r;
349 	rd = last_rd;
350 	rd_d = (rdel * fs * 0.001f - last_rd) * sc_r;
351 
352 	for (pos = 0; pos < sample_count; pos++) {
353 	  /* Increment linear interpolators */
354 	  ll += ll_d;
355 	  rl += rl_d;
356 	  cl += cl_d;
357 	  ld += ld_d;
358 	  rd += rd_d;
359 	  cd += cd_d;
360 
361 	  /* Write input into delay line */
362 	  buffer[buffer_pos] = in_l[pos] + in_r[pos];
363 	  /* Add feedback, must be done afterwards for case where C delay = 0 */
364 	  fbs = buffer[(buffer_pos - f_round(cd)) & buffer_mask] * fb;
365 	  fbs = flush_to_zero(fbs);
366 	  fbs = biquad_run(filters, fbs);
367 	  fbs = biquad_run(filters + 1, fbs);
368 	  buffer[buffer_pos] += fbs;
369 
370 	  /* Outputs from left and right delay beffers + centre mix */
371 	  left  = buffer[(buffer_pos - f_round(ld)) & buffer_mask] * ll +
372 	          buffer[(buffer_pos - f_round(cd)) & buffer_mask] * cl;
373 	  right = buffer[(buffer_pos - f_round(rd)) & buffer_mask] * rl +
374 	          buffer[(buffer_pos - f_round(cd)) & buffer_mask] * cl;
375 
376 	  /* Left and right channel outs */
377 	  buffer_write(out_l[pos], in_l[pos] * (1.0f - wet) +
378 	                  (left * spr_t + right * spr_o) * wet);
379 	  buffer_write(out_r[pos], in_r[pos] * (1.0f - wet) +
380 	                  (left * spr_o + right * spr_t) * wet);
381 
382 	  buffer_pos = (buffer_pos + 1) & buffer_mask;
383 	}
384 
385 	plugin_data->last_ll = ll;
386 	plugin_data->last_cl = cl;
387 	plugin_data->last_rl = rl;
388 	plugin_data->last_ld = ld;
389 	plugin_data->last_cd = cd;
390 	plugin_data->last_rd = rd;
391 	plugin_data->buffer_pos = buffer_pos;
392 }
393 #undef buffer_write
394 #undef RUN_ADDING
395 #undef RUN_REPLACING
396 
397 #define buffer_write(b, v) (b += (v) * run_adding_gain)
398 #define RUN_ADDING    1
399 #define RUN_REPLACING 0
400 
setRunAddingGainLcrDelay(LADSPA_Handle instance,LADSPA_Data gain)401 static void setRunAddingGainLcrDelay(LADSPA_Handle instance, LADSPA_Data gain) {
402 	((LcrDelay *)instance)->run_adding_gain = gain;
403 }
404 
runAddingLcrDelay(LADSPA_Handle instance,unsigned long sample_count)405 static void runAddingLcrDelay(LADSPA_Handle instance, unsigned long sample_count) {
406 	LcrDelay *plugin_data = (LcrDelay *)instance;
407 	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;
408 
409 	/* L delay (ms) (float value) */
410 	const LADSPA_Data ldel = *(plugin_data->ldel);
411 
412 	/* L level (float value) */
413 	const LADSPA_Data llev = *(plugin_data->llev);
414 
415 	/* C delay (ms) (float value) */
416 	const LADSPA_Data cdel = *(plugin_data->cdel);
417 
418 	/* C level (float value) */
419 	const LADSPA_Data clev = *(plugin_data->clev);
420 
421 	/* R delay (ms) (float value) */
422 	const LADSPA_Data rdel = *(plugin_data->rdel);
423 
424 	/* R level (float value) */
425 	const LADSPA_Data rlev = *(plugin_data->rlev);
426 
427 	/* Feedback (float value) */
428 	const LADSPA_Data feedback = *(plugin_data->feedback);
429 
430 	/* High damp (%) (float value) */
431 	const LADSPA_Data high_d = *(plugin_data->high_d);
432 
433 	/* Low damp (%) (float value) */
434 	const LADSPA_Data low_d = *(plugin_data->low_d);
435 
436 	/* Spread (float value) */
437 	const LADSPA_Data spread = *(plugin_data->spread);
438 
439 	/* Dry/Wet level (float value) */
440 	const LADSPA_Data wet = *(plugin_data->wet);
441 
442 	/* L input (array of floats of length sample_count) */
443 	const LADSPA_Data * const in_l = plugin_data->in_l;
444 
445 	/* R input (array of floats of length sample_count) */
446 	const LADSPA_Data * const in_r = plugin_data->in_r;
447 
448 	/* L output (array of floats of length sample_count) */
449 	LADSPA_Data * const out_l = plugin_data->out_l;
450 
451 	/* R output (array of floats of length sample_count) */
452 	LADSPA_Data * const out_r = plugin_data->out_r;
453 	LADSPA_Data * buffer = plugin_data->buffer;
454 	unsigned int buffer_mask = plugin_data->buffer_mask;
455 	unsigned int buffer_pos = plugin_data->buffer_pos;
456 	biquad * filters = plugin_data->filters;
457 	float fs = plugin_data->fs;
458 	float last_cd = plugin_data->last_cd;
459 	float last_cl = plugin_data->last_cl;
460 	float last_ld = plugin_data->last_ld;
461 	float last_ll = plugin_data->last_ll;
462 	float last_rd = plugin_data->last_rd;
463 	float last_rl = plugin_data->last_rl;
464 
465 #line 58 "lcr_delay_1436.xml"
466 	unsigned long pos;
467 	const float sc_r = 1.0f / (float)sample_count;
468 	const float spr_t = 0.5f + spread * 0.01f;
469 	const float spr_o = 0.5f - spread * 0.01f;
470 	float fb = feedback * 0.01f;
471 	float ll, cl, rl, ld, cd, rd;
472 	float ll_d, cl_d, rl_d, ld_d, cd_d, rd_d;
473 	float left, right;
474 	float fbs; /* Feedback signal */
475 
476 	if (fb < -0.99f) {
477 	  fb = -0.99f;
478 	} else if (fb > 0.99f) {
479 	  fb = 0.99f;
480 	}
481 
482 	ls_set_params(filters, fs * 0.0001f * powf(2.0f, low_d * 0.12f),
483 	              -0.5f * low_d, 0.5f, fs);
484 	hs_set_params(filters + 1, fs * (0.41f - 0.0001f *
485 	              powf(2.0f, high_d * 0.12f)), -70.0f, 0.9f, fs);
486 
487 	ll = last_ll;                                /* Start value of Left Level */
488 	ll_d = (llev * 0.01f - last_ll) * sc_r;         /* Delta for Left Level */
489 	cl = last_cl;
490 	cl_d = (clev * 0.01f - last_cl) * sc_r;
491 	rl = last_rl;
492 	rl_d = (rlev * 0.01f - last_rl) * sc_r;
493 
494 	ld = last_ld;
495 	ld_d = (ldel * fs * 0.001f - last_ld) * sc_r;
496 	cd = last_cd;
497 	cd_d = (cdel * fs * 0.001f - last_cd) * sc_r;
498 	rd = last_rd;
499 	rd_d = (rdel * fs * 0.001f - last_rd) * sc_r;
500 
501 	for (pos = 0; pos < sample_count; pos++) {
502 	  /* Increment linear interpolators */
503 	  ll += ll_d;
504 	  rl += rl_d;
505 	  cl += cl_d;
506 	  ld += ld_d;
507 	  rd += rd_d;
508 	  cd += cd_d;
509 
510 	  /* Write input into delay line */
511 	  buffer[buffer_pos] = in_l[pos] + in_r[pos];
512 	  /* Add feedback, must be done afterwards for case where C delay = 0 */
513 	  fbs = buffer[(buffer_pos - f_round(cd)) & buffer_mask] * fb;
514 	  fbs = flush_to_zero(fbs);
515 	  fbs = biquad_run(filters, fbs);
516 	  fbs = biquad_run(filters + 1, fbs);
517 	  buffer[buffer_pos] += fbs;
518 
519 	  /* Outputs from left and right delay beffers + centre mix */
520 	  left  = buffer[(buffer_pos - f_round(ld)) & buffer_mask] * ll +
521 	          buffer[(buffer_pos - f_round(cd)) & buffer_mask] * cl;
522 	  right = buffer[(buffer_pos - f_round(rd)) & buffer_mask] * rl +
523 	          buffer[(buffer_pos - f_round(cd)) & buffer_mask] * cl;
524 
525 	  /* Left and right channel outs */
526 	  buffer_write(out_l[pos], in_l[pos] * (1.0f - wet) +
527 	                  (left * spr_t + right * spr_o) * wet);
528 	  buffer_write(out_r[pos], in_r[pos] * (1.0f - wet) +
529 	                  (left * spr_o + right * spr_t) * wet);
530 
531 	  buffer_pos = (buffer_pos + 1) & buffer_mask;
532 	}
533 
534 	plugin_data->last_ll = ll;
535 	plugin_data->last_cl = cl;
536 	plugin_data->last_rl = rl;
537 	plugin_data->last_ld = ld;
538 	plugin_data->last_cd = cd;
539 	plugin_data->last_rd = rd;
540 	plugin_data->buffer_pos = buffer_pos;
541 }
542 
swh_init()543 static void __attribute__((constructor)) swh_init() {
544 	char **port_names;
545 	LADSPA_PortDescriptor *port_descriptors;
546 	LADSPA_PortRangeHint *port_range_hints;
547 
548 #ifdef ENABLE_NLS
549 #define D_(s) dgettext(PACKAGE, s)
550 	bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR);
551 #else
552 #define D_(s) (s)
553 #endif
554 
555 
556 	lcrDelayDescriptor =
557 	 (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
558 
559 	if (lcrDelayDescriptor) {
560 		lcrDelayDescriptor->UniqueID = 1436;
561 		lcrDelayDescriptor->Label = "lcrDelay";
562 		lcrDelayDescriptor->Properties =
563 		 LADSPA_PROPERTY_HARD_RT_CAPABLE;
564 		lcrDelayDescriptor->Name =
565 		 D_("L/C/R Delay");
566 		lcrDelayDescriptor->Maker =
567 		 "Steve Harris <steve@plugin.org.uk>";
568 		lcrDelayDescriptor->Copyright =
569 		 "GPL";
570 		lcrDelayDescriptor->PortCount = 15;
571 
572 		port_descriptors = (LADSPA_PortDescriptor *)calloc(15,
573 		 sizeof(LADSPA_PortDescriptor));
574 		lcrDelayDescriptor->PortDescriptors =
575 		 (const LADSPA_PortDescriptor *)port_descriptors;
576 
577 		port_range_hints = (LADSPA_PortRangeHint *)calloc(15,
578 		 sizeof(LADSPA_PortRangeHint));
579 		lcrDelayDescriptor->PortRangeHints =
580 		 (const LADSPA_PortRangeHint *)port_range_hints;
581 
582 		port_names = (char **)calloc(15, sizeof(char*));
583 		lcrDelayDescriptor->PortNames =
584 		 (const char **)port_names;
585 
586 		/* Parameters for L delay (ms) */
587 		port_descriptors[LCRDELAY_LDEL] =
588 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
589 		port_names[LCRDELAY_LDEL] =
590 		 D_("L delay (ms)");
591 		port_range_hints[LCRDELAY_LDEL].HintDescriptor =
592 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW;
593 		port_range_hints[LCRDELAY_LDEL].LowerBound = 0;
594 		port_range_hints[LCRDELAY_LDEL].UpperBound = 2700;
595 
596 		/* Parameters for L level */
597 		port_descriptors[LCRDELAY_LLEV] =
598 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
599 		port_names[LCRDELAY_LLEV] =
600 		 D_("L level");
601 		port_range_hints[LCRDELAY_LLEV].HintDescriptor =
602 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE;
603 		port_range_hints[LCRDELAY_LLEV].LowerBound = 0;
604 		port_range_hints[LCRDELAY_LLEV].UpperBound = 50;
605 
606 		/* Parameters for C delay (ms) */
607 		port_descriptors[LCRDELAY_CDEL] =
608 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
609 		port_names[LCRDELAY_CDEL] =
610 		 D_("C delay (ms)");
611 		port_range_hints[LCRDELAY_CDEL].HintDescriptor =
612 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW;
613 		port_range_hints[LCRDELAY_CDEL].LowerBound = 0;
614 		port_range_hints[LCRDELAY_CDEL].UpperBound = 2700;
615 
616 		/* Parameters for C level */
617 		port_descriptors[LCRDELAY_CLEV] =
618 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
619 		port_names[LCRDELAY_CLEV] =
620 		 D_("C level");
621 		port_range_hints[LCRDELAY_CLEV].HintDescriptor =
622 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE;
623 		port_range_hints[LCRDELAY_CLEV].LowerBound = 0;
624 		port_range_hints[LCRDELAY_CLEV].UpperBound = 50;
625 
626 		/* Parameters for R delay (ms) */
627 		port_descriptors[LCRDELAY_RDEL] =
628 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
629 		port_names[LCRDELAY_RDEL] =
630 		 D_("R delay (ms)");
631 		port_range_hints[LCRDELAY_RDEL].HintDescriptor =
632 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW;
633 		port_range_hints[LCRDELAY_RDEL].LowerBound = 0;
634 		port_range_hints[LCRDELAY_RDEL].UpperBound = 2700;
635 
636 		/* Parameters for R level */
637 		port_descriptors[LCRDELAY_RLEV] =
638 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
639 		port_names[LCRDELAY_RLEV] =
640 		 D_("R level");
641 		port_range_hints[LCRDELAY_RLEV].HintDescriptor =
642 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE;
643 		port_range_hints[LCRDELAY_RLEV].LowerBound = 0;
644 		port_range_hints[LCRDELAY_RLEV].UpperBound = 50;
645 
646 		/* Parameters for Feedback */
647 		port_descriptors[LCRDELAY_FEEDBACK] =
648 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
649 		port_names[LCRDELAY_FEEDBACK] =
650 		 D_("Feedback");
651 		port_range_hints[LCRDELAY_FEEDBACK].HintDescriptor =
652 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
653 		port_range_hints[LCRDELAY_FEEDBACK].LowerBound = -100;
654 		port_range_hints[LCRDELAY_FEEDBACK].UpperBound = 100;
655 
656 		/* Parameters for High damp (%) */
657 		port_descriptors[LCRDELAY_HIGH_D] =
658 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
659 		port_names[LCRDELAY_HIGH_D] =
660 		 D_("High damp (%)");
661 		port_range_hints[LCRDELAY_HIGH_D].HintDescriptor =
662 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE;
663 		port_range_hints[LCRDELAY_HIGH_D].LowerBound = 0;
664 		port_range_hints[LCRDELAY_HIGH_D].UpperBound = 100;
665 
666 		/* Parameters for Low damp (%) */
667 		port_descriptors[LCRDELAY_LOW_D] =
668 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
669 		port_names[LCRDELAY_LOW_D] =
670 		 D_("Low damp (%)");
671 		port_range_hints[LCRDELAY_LOW_D].HintDescriptor =
672 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE;
673 		port_range_hints[LCRDELAY_LOW_D].LowerBound = 0;
674 		port_range_hints[LCRDELAY_LOW_D].UpperBound = 100;
675 
676 		/* Parameters for Spread */
677 		port_descriptors[LCRDELAY_SPREAD] =
678 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
679 		port_names[LCRDELAY_SPREAD] =
680 		 D_("Spread");
681 		port_range_hints[LCRDELAY_SPREAD].HintDescriptor =
682 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE;
683 		port_range_hints[LCRDELAY_SPREAD].LowerBound = 0;
684 		port_range_hints[LCRDELAY_SPREAD].UpperBound = 50;
685 
686 		/* Parameters for Dry/Wet level */
687 		port_descriptors[LCRDELAY_WET] =
688 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
689 		port_names[LCRDELAY_WET] =
690 		 D_("Dry/Wet level");
691 		port_range_hints[LCRDELAY_WET].HintDescriptor =
692 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
693 		port_range_hints[LCRDELAY_WET].LowerBound = 0;
694 		port_range_hints[LCRDELAY_WET].UpperBound = 1;
695 
696 		/* Parameters for L input */
697 		port_descriptors[LCRDELAY_IN_L] =
698 		 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
699 		port_names[LCRDELAY_IN_L] =
700 		 D_("L input");
701 		port_range_hints[LCRDELAY_IN_L].HintDescriptor = 0;
702 
703 		/* Parameters for R input */
704 		port_descriptors[LCRDELAY_IN_R] =
705 		 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
706 		port_names[LCRDELAY_IN_R] =
707 		 D_("R input");
708 		port_range_hints[LCRDELAY_IN_R].HintDescriptor = 0;
709 
710 		/* Parameters for L output */
711 		port_descriptors[LCRDELAY_OUT_L] =
712 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
713 		port_names[LCRDELAY_OUT_L] =
714 		 D_("L output");
715 		port_range_hints[LCRDELAY_OUT_L].HintDescriptor = 0;
716 
717 		/* Parameters for R output */
718 		port_descriptors[LCRDELAY_OUT_R] =
719 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
720 		port_names[LCRDELAY_OUT_R] =
721 		 D_("R output");
722 		port_range_hints[LCRDELAY_OUT_R].HintDescriptor = 0;
723 
724 		lcrDelayDescriptor->activate = activateLcrDelay;
725 		lcrDelayDescriptor->cleanup = cleanupLcrDelay;
726 		lcrDelayDescriptor->connect_port = connectPortLcrDelay;
727 		lcrDelayDescriptor->deactivate = NULL;
728 		lcrDelayDescriptor->instantiate = instantiateLcrDelay;
729 		lcrDelayDescriptor->run = runLcrDelay;
730 		lcrDelayDescriptor->run_adding = runAddingLcrDelay;
731 		lcrDelayDescriptor->set_run_adding_gain = setRunAddingGainLcrDelay;
732 	}
733 }
734 
swh_fini()735 static void __attribute__((destructor)) swh_fini() {
736 	if (lcrDelayDescriptor) {
737 		free((LADSPA_PortDescriptor *)lcrDelayDescriptor->PortDescriptors);
738 		free((char **)lcrDelayDescriptor->PortNames);
739 		free((LADSPA_PortRangeHint *)lcrDelayDescriptor->PortRangeHints);
740 		free(lcrDelayDescriptor);
741 	}
742 	lcrDelayDescriptor = NULL;
743 
744 }
745