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