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 "harmonic_gen_1220.xml"
29 
30 #define HARMONICS 11
31 
32 /* Calculate Chebychev coefficents from partial magnitudes, adapted from
33  * example in Num. Rec. */
chebpc(float c[],float d[])34 void chebpc(float c[], float d[])
35 {
36     int k, j;
37     float sv, dd[HARMONICS];
38 
39     for (j = 0; j < HARMONICS; j++) {
40         d[j] = dd[j] = 0.0;
41     }
42 
43     d[0] = c[HARMONICS - 1];
44 
45     for (j = HARMONICS - 2; j >= 1; j--) {
46         for (k = HARMONICS - j; k >= 1; k--) {
47             sv = d[k];
48             d[k] = 2.0 * d[k - 1] - dd[k];
49             dd[k] = sv;
50         }
51         sv = d[0];
52         d[0] = -dd[0] + c[j];
53         dd[0] = sv;
54     }
55 
56     for (j = HARMONICS - 1; j >= 1; j--) {
57         d[j] = d[j - 1] - dd[j];
58     }
59     d[0] = -dd[0] + 0.5 * c[0];
60 }
61 
62 #define HARMONICGEN_MAG_1              0
63 #define HARMONICGEN_MAG_2              1
64 #define HARMONICGEN_MAG_3              2
65 #define HARMONICGEN_MAG_4              3
66 #define HARMONICGEN_MAG_5              4
67 #define HARMONICGEN_MAG_6              5
68 #define HARMONICGEN_MAG_7              6
69 #define HARMONICGEN_MAG_8              7
70 #define HARMONICGEN_MAG_9              8
71 #define HARMONICGEN_MAG_10             9
72 #define HARMONICGEN_INPUT              10
73 #define HARMONICGEN_OUTPUT             11
74 
75 static LADSPA_Descriptor *harmonicGenDescriptor = NULL;
76 
77 typedef struct {
78 	LADSPA_Data *mag_1;
79 	LADSPA_Data *mag_2;
80 	LADSPA_Data *mag_3;
81 	LADSPA_Data *mag_4;
82 	LADSPA_Data *mag_5;
83 	LADSPA_Data *mag_6;
84 	LADSPA_Data *mag_7;
85 	LADSPA_Data *mag_8;
86 	LADSPA_Data *mag_9;
87 	LADSPA_Data *mag_10;
88 	LADSPA_Data *input;
89 	LADSPA_Data *output;
90 	float        itm1;
91 	float        otm1;
92 	LADSPA_Data run_adding_gain;
93 } HarmonicGen;
94 
95 _WINDOWS_DLL_EXPORT_
ladspa_descriptor(unsigned long index)96 const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) {
97 
98 #ifdef WIN32
99 	if (bIsFirstTime) {
100 		swh_init();
101 		bIsFirstTime = 0;
102 	}
103 #endif
104 	switch (index) {
105 	case 0:
106 		return harmonicGenDescriptor;
107 	default:
108 		return NULL;
109 	}
110 }
111 
activateHarmonicGen(LADSPA_Handle instance)112 static void activateHarmonicGen(LADSPA_Handle instance) {
113 	HarmonicGen *plugin_data = (HarmonicGen *)instance;
114 	float itm1 = plugin_data->itm1;
115 	float otm1 = plugin_data->otm1;
116 #line 56 "harmonic_gen_1220.xml"
117 	itm1 = 0.0f;
118 	otm1 = 0.0f;
119 	plugin_data->itm1 = itm1;
120 	plugin_data->otm1 = otm1;
121 
122 }
123 
cleanupHarmonicGen(LADSPA_Handle instance)124 static void cleanupHarmonicGen(LADSPA_Handle instance) {
125 	free(instance);
126 }
127 
connectPortHarmonicGen(LADSPA_Handle instance,unsigned long port,LADSPA_Data * data)128 static void connectPortHarmonicGen(
129  LADSPA_Handle instance,
130  unsigned long port,
131  LADSPA_Data *data) {
132 	HarmonicGen *plugin;
133 
134 	plugin = (HarmonicGen *)instance;
135 	switch (port) {
136 	case HARMONICGEN_MAG_1:
137 		plugin->mag_1 = data;
138 		break;
139 	case HARMONICGEN_MAG_2:
140 		plugin->mag_2 = data;
141 		break;
142 	case HARMONICGEN_MAG_3:
143 		plugin->mag_3 = data;
144 		break;
145 	case HARMONICGEN_MAG_4:
146 		plugin->mag_4 = data;
147 		break;
148 	case HARMONICGEN_MAG_5:
149 		plugin->mag_5 = data;
150 		break;
151 	case HARMONICGEN_MAG_6:
152 		plugin->mag_6 = data;
153 		break;
154 	case HARMONICGEN_MAG_7:
155 		plugin->mag_7 = data;
156 		break;
157 	case HARMONICGEN_MAG_8:
158 		plugin->mag_8 = data;
159 		break;
160 	case HARMONICGEN_MAG_9:
161 		plugin->mag_9 = data;
162 		break;
163 	case HARMONICGEN_MAG_10:
164 		plugin->mag_10 = data;
165 		break;
166 	case HARMONICGEN_INPUT:
167 		plugin->input = data;
168 		break;
169 	case HARMONICGEN_OUTPUT:
170 		plugin->output = data;
171 		break;
172 	}
173 }
174 
instantiateHarmonicGen(const LADSPA_Descriptor * descriptor,unsigned long s_rate)175 static LADSPA_Handle instantiateHarmonicGen(
176  const LADSPA_Descriptor *descriptor,
177  unsigned long s_rate) {
178 	HarmonicGen *plugin_data = (HarmonicGen *)calloc(1, sizeof(HarmonicGen));
179 	plugin_data->run_adding_gain = 1.0f;
180 
181 	return (LADSPA_Handle)plugin_data;
182 }
183 
184 #undef buffer_write
185 #undef RUN_ADDING
186 #undef RUN_REPLACING
187 
188 #define buffer_write(b, v) (b = v)
189 #define RUN_ADDING    0
190 #define RUN_REPLACING 1
191 
runHarmonicGen(LADSPA_Handle instance,unsigned long sample_count)192 static void runHarmonicGen(LADSPA_Handle instance, unsigned long sample_count) {
193 	HarmonicGen *plugin_data = (HarmonicGen *)instance;
194 
195 	/* Fundamental magnitude (float value) */
196 	const LADSPA_Data mag_1 = *(plugin_data->mag_1);
197 
198 	/* 2nd harmonic magnitude (float value) */
199 	const LADSPA_Data mag_2 = *(plugin_data->mag_2);
200 
201 	/* 3rd harmonic magnitude (float value) */
202 	const LADSPA_Data mag_3 = *(plugin_data->mag_3);
203 
204 	/* 4th harmonic magnitude (float value) */
205 	const LADSPA_Data mag_4 = *(plugin_data->mag_4);
206 
207 	/* 5th harmonic magnitude (float value) */
208 	const LADSPA_Data mag_5 = *(plugin_data->mag_5);
209 
210 	/* 6th harmonic magnitude (float value) */
211 	const LADSPA_Data mag_6 = *(plugin_data->mag_6);
212 
213 	/* 7th harmonic magnitude (float value) */
214 	const LADSPA_Data mag_7 = *(plugin_data->mag_7);
215 
216 	/* 8th harmonic magnitude (float value) */
217 	const LADSPA_Data mag_8 = *(plugin_data->mag_8);
218 
219 	/* 9th harmonic magnitude (float value) */
220 	const LADSPA_Data mag_9 = *(plugin_data->mag_9);
221 
222 	/* 10th harmonic magnitude (float value) */
223 	const LADSPA_Data mag_10 = *(plugin_data->mag_10);
224 
225 	/* Input (array of floats of length sample_count) */
226 	const LADSPA_Data * const input = plugin_data->input;
227 
228 	/* Output (array of floats of length sample_count) */
229 	LADSPA_Data * const output = plugin_data->output;
230 	float itm1 = plugin_data->itm1;
231 	float otm1 = plugin_data->otm1;
232 
233 #line 61 "harmonic_gen_1220.xml"
234 	unsigned long pos, i;
235 	float mag_fix;
236 	float mag[HARMONICS] = {0.0f, mag_1, mag_2, mag_3, mag_4, mag_5, mag_6,
237 	                        mag_7, mag_8, mag_9, mag_10};
238 	float p[HARMONICS];
239 
240 	// Normalise magnitudes
241 	mag_fix = (fabs(mag_1) + fabs(mag_2) + fabs(mag_3) + fabs(mag_4) +
242 	           fabs(mag_5) + fabs(mag_6) + fabs(mag_7) + fabs(mag_8) +
243 	           fabs(mag_9) + fabs(mag_10));
244 	if (mag_fix < 1.0f) {
245 	  mag_fix = 1.0f;
246 	} else {
247 	  mag_fix = 1.0f / mag_fix;
248 	}
249 	for (i=0; i<HARMONICS; i++) {
250 	  mag[i] *= mag_fix;
251 	}
252 
253 	// Calculate polynomial coefficients, using Chebychev aproximation
254 	chebpc(mag, p);
255 
256 	for (pos = 0; pos < sample_count; pos++) {
257 	  float x = input[pos], y;
258 
259 	  // Calculate the polynomial using Horner's Rule
260 	  y = p[0] + (p[1] + (p[2] + (p[3] + (p[4] + (p[5] + (p[6] + (p[7] +
261 	      (p[8] + (p[9] + p[10] * x) * x) * x) * x) * x) * x) * x) * x) *
262 	      x) * x;
263 
264 	  // DC offset remove (odd harmonics cause DC offset)
265 	  otm1 = 0.999f * otm1 + y - itm1;
266 	  itm1 = y;
267 
268 	  buffer_write(output[pos], otm1);
269 	}
270 
271 	plugin_data->itm1 = itm1;
272 	plugin_data->otm1 = otm1;
273 }
274 #undef buffer_write
275 #undef RUN_ADDING
276 #undef RUN_REPLACING
277 
278 #define buffer_write(b, v) (b += (v) * run_adding_gain)
279 #define RUN_ADDING    1
280 #define RUN_REPLACING 0
281 
setRunAddingGainHarmonicGen(LADSPA_Handle instance,LADSPA_Data gain)282 static void setRunAddingGainHarmonicGen(LADSPA_Handle instance, LADSPA_Data gain) {
283 	((HarmonicGen *)instance)->run_adding_gain = gain;
284 }
285 
runAddingHarmonicGen(LADSPA_Handle instance,unsigned long sample_count)286 static void runAddingHarmonicGen(LADSPA_Handle instance, unsigned long sample_count) {
287 	HarmonicGen *plugin_data = (HarmonicGen *)instance;
288 	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;
289 
290 	/* Fundamental magnitude (float value) */
291 	const LADSPA_Data mag_1 = *(plugin_data->mag_1);
292 
293 	/* 2nd harmonic magnitude (float value) */
294 	const LADSPA_Data mag_2 = *(plugin_data->mag_2);
295 
296 	/* 3rd harmonic magnitude (float value) */
297 	const LADSPA_Data mag_3 = *(plugin_data->mag_3);
298 
299 	/* 4th harmonic magnitude (float value) */
300 	const LADSPA_Data mag_4 = *(plugin_data->mag_4);
301 
302 	/* 5th harmonic magnitude (float value) */
303 	const LADSPA_Data mag_5 = *(plugin_data->mag_5);
304 
305 	/* 6th harmonic magnitude (float value) */
306 	const LADSPA_Data mag_6 = *(plugin_data->mag_6);
307 
308 	/* 7th harmonic magnitude (float value) */
309 	const LADSPA_Data mag_7 = *(plugin_data->mag_7);
310 
311 	/* 8th harmonic magnitude (float value) */
312 	const LADSPA_Data mag_8 = *(plugin_data->mag_8);
313 
314 	/* 9th harmonic magnitude (float value) */
315 	const LADSPA_Data mag_9 = *(plugin_data->mag_9);
316 
317 	/* 10th harmonic magnitude (float value) */
318 	const LADSPA_Data mag_10 = *(plugin_data->mag_10);
319 
320 	/* Input (array of floats of length sample_count) */
321 	const LADSPA_Data * const input = plugin_data->input;
322 
323 	/* Output (array of floats of length sample_count) */
324 	LADSPA_Data * const output = plugin_data->output;
325 	float itm1 = plugin_data->itm1;
326 	float otm1 = plugin_data->otm1;
327 
328 #line 61 "harmonic_gen_1220.xml"
329 	unsigned long pos, i;
330 	float mag_fix;
331 	float mag[HARMONICS] = {0.0f, mag_1, mag_2, mag_3, mag_4, mag_5, mag_6,
332 	                        mag_7, mag_8, mag_9, mag_10};
333 	float p[HARMONICS];
334 
335 	// Normalise magnitudes
336 	mag_fix = (fabs(mag_1) + fabs(mag_2) + fabs(mag_3) + fabs(mag_4) +
337 	           fabs(mag_5) + fabs(mag_6) + fabs(mag_7) + fabs(mag_8) +
338 	           fabs(mag_9) + fabs(mag_10));
339 	if (mag_fix < 1.0f) {
340 	  mag_fix = 1.0f;
341 	} else {
342 	  mag_fix = 1.0f / mag_fix;
343 	}
344 	for (i=0; i<HARMONICS; i++) {
345 	  mag[i] *= mag_fix;
346 	}
347 
348 	// Calculate polynomial coefficients, using Chebychev aproximation
349 	chebpc(mag, p);
350 
351 	for (pos = 0; pos < sample_count; pos++) {
352 	  float x = input[pos], y;
353 
354 	  // Calculate the polynomial using Horner's Rule
355 	  y = p[0] + (p[1] + (p[2] + (p[3] + (p[4] + (p[5] + (p[6] + (p[7] +
356 	      (p[8] + (p[9] + p[10] * x) * x) * x) * x) * x) * x) * x) * x) *
357 	      x) * x;
358 
359 	  // DC offset remove (odd harmonics cause DC offset)
360 	  otm1 = 0.999f * otm1 + y - itm1;
361 	  itm1 = y;
362 
363 	  buffer_write(output[pos], otm1);
364 	}
365 
366 	plugin_data->itm1 = itm1;
367 	plugin_data->otm1 = otm1;
368 }
369 
swh_init()370 static void __attribute__((constructor)) swh_init() {
371 	char **port_names;
372 	LADSPA_PortDescriptor *port_descriptors;
373 	LADSPA_PortRangeHint *port_range_hints;
374 
375 #ifdef ENABLE_NLS
376 #define D_(s) dgettext(PACKAGE, s)
377 	bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR);
378 #else
379 #define D_(s) (s)
380 #endif
381 
382 
383 	harmonicGenDescriptor =
384 	 (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
385 
386 	if (harmonicGenDescriptor) {
387 		harmonicGenDescriptor->UniqueID = 1220;
388 		harmonicGenDescriptor->Label = "harmonicGen";
389 		harmonicGenDescriptor->Properties =
390 		 LADSPA_PROPERTY_HARD_RT_CAPABLE;
391 		harmonicGenDescriptor->Name =
392 		 D_("Harmonic generator");
393 		harmonicGenDescriptor->Maker =
394 		 "Steve Harris <steve@plugin.org.uk>";
395 		harmonicGenDescriptor->Copyright =
396 		 "GPL";
397 		harmonicGenDescriptor->PortCount = 12;
398 
399 		port_descriptors = (LADSPA_PortDescriptor *)calloc(12,
400 		 sizeof(LADSPA_PortDescriptor));
401 		harmonicGenDescriptor->PortDescriptors =
402 		 (const LADSPA_PortDescriptor *)port_descriptors;
403 
404 		port_range_hints = (LADSPA_PortRangeHint *)calloc(12,
405 		 sizeof(LADSPA_PortRangeHint));
406 		harmonicGenDescriptor->PortRangeHints =
407 		 (const LADSPA_PortRangeHint *)port_range_hints;
408 
409 		port_names = (char **)calloc(12, sizeof(char*));
410 		harmonicGenDescriptor->PortNames =
411 		 (const char **)port_names;
412 
413 		/* Parameters for Fundamental magnitude */
414 		port_descriptors[HARMONICGEN_MAG_1] =
415 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
416 		port_names[HARMONICGEN_MAG_1] =
417 		 D_("Fundamental magnitude");
418 		port_range_hints[HARMONICGEN_MAG_1].HintDescriptor =
419 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_1;
420 		port_range_hints[HARMONICGEN_MAG_1].LowerBound = -1;
421 		port_range_hints[HARMONICGEN_MAG_1].UpperBound = +1;
422 
423 		/* Parameters for 2nd harmonic magnitude */
424 		port_descriptors[HARMONICGEN_MAG_2] =
425 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
426 		port_names[HARMONICGEN_MAG_2] =
427 		 D_("2nd harmonic magnitude");
428 		port_range_hints[HARMONICGEN_MAG_2].HintDescriptor =
429 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
430 		port_range_hints[HARMONICGEN_MAG_2].LowerBound = -1;
431 		port_range_hints[HARMONICGEN_MAG_2].UpperBound = +1;
432 
433 		/* Parameters for 3rd harmonic magnitude */
434 		port_descriptors[HARMONICGEN_MAG_3] =
435 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
436 		port_names[HARMONICGEN_MAG_3] =
437 		 D_("3rd harmonic magnitude");
438 		port_range_hints[HARMONICGEN_MAG_3].HintDescriptor =
439 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
440 		port_range_hints[HARMONICGEN_MAG_3].LowerBound = -1;
441 		port_range_hints[HARMONICGEN_MAG_3].UpperBound = +1;
442 
443 		/* Parameters for 4th harmonic magnitude */
444 		port_descriptors[HARMONICGEN_MAG_4] =
445 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
446 		port_names[HARMONICGEN_MAG_4] =
447 		 D_("4th harmonic magnitude");
448 		port_range_hints[HARMONICGEN_MAG_4].HintDescriptor =
449 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
450 		port_range_hints[HARMONICGEN_MAG_4].LowerBound = -1;
451 		port_range_hints[HARMONICGEN_MAG_4].UpperBound = +1;
452 
453 		/* Parameters for 5th harmonic magnitude */
454 		port_descriptors[HARMONICGEN_MAG_5] =
455 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
456 		port_names[HARMONICGEN_MAG_5] =
457 		 D_("5th harmonic magnitude");
458 		port_range_hints[HARMONICGEN_MAG_5].HintDescriptor =
459 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
460 		port_range_hints[HARMONICGEN_MAG_5].LowerBound = -1;
461 		port_range_hints[HARMONICGEN_MAG_5].UpperBound = +1;
462 
463 		/* Parameters for 6th harmonic magnitude */
464 		port_descriptors[HARMONICGEN_MAG_6] =
465 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
466 		port_names[HARMONICGEN_MAG_6] =
467 		 D_("6th harmonic magnitude");
468 		port_range_hints[HARMONICGEN_MAG_6].HintDescriptor =
469 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
470 		port_range_hints[HARMONICGEN_MAG_6].LowerBound = -1;
471 		port_range_hints[HARMONICGEN_MAG_6].UpperBound = +1;
472 
473 		/* Parameters for 7th harmonic magnitude */
474 		port_descriptors[HARMONICGEN_MAG_7] =
475 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
476 		port_names[HARMONICGEN_MAG_7] =
477 		 D_("7th harmonic magnitude");
478 		port_range_hints[HARMONICGEN_MAG_7].HintDescriptor =
479 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
480 		port_range_hints[HARMONICGEN_MAG_7].LowerBound = -1;
481 		port_range_hints[HARMONICGEN_MAG_7].UpperBound = +1;
482 
483 		/* Parameters for 8th harmonic magnitude */
484 		port_descriptors[HARMONICGEN_MAG_8] =
485 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
486 		port_names[HARMONICGEN_MAG_8] =
487 		 D_("8th harmonic magnitude");
488 		port_range_hints[HARMONICGEN_MAG_8].HintDescriptor =
489 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
490 		port_range_hints[HARMONICGEN_MAG_8].LowerBound = -1;
491 		port_range_hints[HARMONICGEN_MAG_8].UpperBound = +1;
492 
493 		/* Parameters for 9th harmonic magnitude */
494 		port_descriptors[HARMONICGEN_MAG_9] =
495 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
496 		port_names[HARMONICGEN_MAG_9] =
497 		 D_("9th harmonic magnitude");
498 		port_range_hints[HARMONICGEN_MAG_9].HintDescriptor =
499 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
500 		port_range_hints[HARMONICGEN_MAG_9].LowerBound = -1;
501 		port_range_hints[HARMONICGEN_MAG_9].UpperBound = +1;
502 
503 		/* Parameters for 10th harmonic magnitude */
504 		port_descriptors[HARMONICGEN_MAG_10] =
505 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
506 		port_names[HARMONICGEN_MAG_10] =
507 		 D_("10th harmonic magnitude");
508 		port_range_hints[HARMONICGEN_MAG_10].HintDescriptor =
509 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
510 		port_range_hints[HARMONICGEN_MAG_10].LowerBound = -1;
511 		port_range_hints[HARMONICGEN_MAG_10].UpperBound = +1;
512 
513 		/* Parameters for Input */
514 		port_descriptors[HARMONICGEN_INPUT] =
515 		 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
516 		port_names[HARMONICGEN_INPUT] =
517 		 D_("Input");
518 		port_range_hints[HARMONICGEN_INPUT].HintDescriptor =
519 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
520 		port_range_hints[HARMONICGEN_INPUT].LowerBound = -1;
521 		port_range_hints[HARMONICGEN_INPUT].UpperBound = +1;
522 
523 		/* Parameters for Output */
524 		port_descriptors[HARMONICGEN_OUTPUT] =
525 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
526 		port_names[HARMONICGEN_OUTPUT] =
527 		 D_("Output");
528 		port_range_hints[HARMONICGEN_OUTPUT].HintDescriptor =
529 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
530 		port_range_hints[HARMONICGEN_OUTPUT].LowerBound = -1;
531 		port_range_hints[HARMONICGEN_OUTPUT].UpperBound = +1;
532 
533 		harmonicGenDescriptor->activate = activateHarmonicGen;
534 		harmonicGenDescriptor->cleanup = cleanupHarmonicGen;
535 		harmonicGenDescriptor->connect_port = connectPortHarmonicGen;
536 		harmonicGenDescriptor->deactivate = NULL;
537 		harmonicGenDescriptor->instantiate = instantiateHarmonicGen;
538 		harmonicGenDescriptor->run = runHarmonicGen;
539 		harmonicGenDescriptor->run_adding = runAddingHarmonicGen;
540 		harmonicGenDescriptor->set_run_adding_gain = setRunAddingGainHarmonicGen;
541 	}
542 }
543 
swh_fini()544 static void __attribute__((destructor)) swh_fini() {
545 	if (harmonicGenDescriptor) {
546 		free((LADSPA_PortDescriptor *)harmonicGenDescriptor->PortDescriptors);
547 		free((char **)harmonicGenDescriptor->PortNames);
548 		free((LADSPA_PortRangeHint *)harmonicGenDescriptor->PortRangeHints);
549 		free(harmonicGenDescriptor);
550 	}
551 	harmonicGenDescriptor = NULL;
552 
553 }
554