11
#define _ISOC9X_SOURCE 1
12
#define _ISOC99_SOURCE 1
13
#define __USE_ISOC99 1
14
#define __USE_ISOC9X 1
21
#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport)
23
void _init(); // forward declaration
25
#define _WINDOWS_DLL_EXPORT_
28
#line 10 "harmonic_gen_1220.xml"
32
/* Calculate Chebychev coefficents from partial magnitudes, adapted from
33
* example in Num. Rec. */
34
void chebpc(float c[], float d[])
37
float sv, dd[HARMONICS];
39
for (j = 0; j < HARMONICS; j++) {
43
d[0] = c[HARMONICS - 1];
45
for (j = HARMONICS - 2; j >= 1; j--) {
46
for (k = HARMONICS - j; k >= 1; k--) {
48
d[k] = 2.0 * d[k - 1] - dd[k];
56
for (j = HARMONICS - 1; j >= 1; j--) {
57
d[j] = d[j - 1] - dd[j];
59
d[0] = -dd[0] + 0.5 * c[0];
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
75
static LADSPA_Descriptor *harmonicGenDescriptor = NULL;
92
LADSPA_Data run_adding_gain;
96
const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) {
106
return harmonicGenDescriptor;
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"
119
plugin_data->itm1 = itm1;
120
plugin_data->otm1 = otm1;
124
static void cleanupHarmonicGen(LADSPA_Handle instance) {
128
static void connectPortHarmonicGen(
129
LADSPA_Handle instance,
134
plugin = (HarmonicGen *)instance;
136
case HARMONICGEN_MAG_1:
137
plugin->mag_1 = data;
139
case HARMONICGEN_MAG_2:
140
plugin->mag_2 = data;
142
case HARMONICGEN_MAG_3:
143
plugin->mag_3 = data;
145
case HARMONICGEN_MAG_4:
146
plugin->mag_4 = data;
148
case HARMONICGEN_MAG_5:
149
plugin->mag_5 = data;
151
case HARMONICGEN_MAG_6:
152
plugin->mag_6 = data;
154
case HARMONICGEN_MAG_7:
155
plugin->mag_7 = data;
157
case HARMONICGEN_MAG_8:
158
plugin->mag_8 = data;
160
case HARMONICGEN_MAG_9:
161
plugin->mag_9 = data;
163
case HARMONICGEN_MAG_10:
164
plugin->mag_10 = data;
166
case HARMONICGEN_INPUT:
167
plugin->input = data;
169
case HARMONICGEN_OUTPUT:
170
plugin->output = data;
175
static LADSPA_Handle instantiateHarmonicGen(
176
const LADSPA_Descriptor *descriptor,
177
unsigned long s_rate) {
178
HarmonicGen *plugin_data = (HarmonicGen *)malloc(sizeof(HarmonicGen));
179
plugin_data->run_adding_gain = 1.0f;
181
return (LADSPA_Handle)plugin_data;
188
#define buffer_write(b, v) (b = v)
190
#define RUN_REPLACING 1
192
static void runHarmonicGen(LADSPA_Handle instance, unsigned long sample_count) {
193
HarmonicGen *plugin_data = (HarmonicGen *)instance;
195
/* Fundamental magnitude (float value) */
196
const LADSPA_Data mag_1 = *(plugin_data->mag_1);
198
/* 2nd harmonic magnitude (float value) */
199
const LADSPA_Data mag_2 = *(plugin_data->mag_2);
201
/* 3rd harmonic magnitude (float value) */
202
const LADSPA_Data mag_3 = *(plugin_data->mag_3);
204
/* 4th harmonic magnitude (float value) */
205
const LADSPA_Data mag_4 = *(plugin_data->mag_4);
207
/* 5th harmonic magnitude (float value) */
208
const LADSPA_Data mag_5 = *(plugin_data->mag_5);
210
/* 6th harmonic magnitude (float value) */
211
const LADSPA_Data mag_6 = *(plugin_data->mag_6);
213
/* 7th harmonic magnitude (float value) */
214
const LADSPA_Data mag_7 = *(plugin_data->mag_7);
216
/* 8th harmonic magnitude (float value) */
217
const LADSPA_Data mag_8 = *(plugin_data->mag_8);
219
/* 9th harmonic magnitude (float value) */
220
const LADSPA_Data mag_9 = *(plugin_data->mag_9);
222
/* 10th harmonic magnitude (float value) */
223
const LADSPA_Data mag_10 = *(plugin_data->mag_10);
225
/* Input (array of floats of length sample_count) */
226
const LADSPA_Data * const input = plugin_data->input;
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;
233
#line 61 "harmonic_gen_1220.xml"
234
unsigned long pos, i;
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};
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) {
247
mag_fix = 1.0f / mag_fix;
249
for (i=0; i<HARMONICS; i++) {
253
// Calculate polynomial coefficients, using Chebychev aproximation
256
for (pos = 0; pos < sample_count; pos++) {
257
float x = input[pos], y;
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) *
264
// DC offset remove (odd harmonics cause DC offset)
265
otm1 = 0.999f * otm1 + y - itm1;
268
buffer_write(output[pos], otm1);
271
plugin_data->itm1 = itm1;
272
plugin_data->otm1 = otm1;
278
#define buffer_write(b, v) (b += (v) * run_adding_gain)
280
#define RUN_REPLACING 0
282
static void setRunAddingGainHarmonicGen(LADSPA_Handle instance, LADSPA_Data gain) {
283
((HarmonicGen *)instance)->run_adding_gain = gain;
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;
290
/* Fundamental magnitude (float value) */
291
const LADSPA_Data mag_1 = *(plugin_data->mag_1);
293
/* 2nd harmonic magnitude (float value) */
294
const LADSPA_Data mag_2 = *(plugin_data->mag_2);
296
/* 3rd harmonic magnitude (float value) */
297
const LADSPA_Data mag_3 = *(plugin_data->mag_3);
299
/* 4th harmonic magnitude (float value) */
300
const LADSPA_Data mag_4 = *(plugin_data->mag_4);
302
/* 5th harmonic magnitude (float value) */
303
const LADSPA_Data mag_5 = *(plugin_data->mag_5);
305
/* 6th harmonic magnitude (float value) */
306
const LADSPA_Data mag_6 = *(plugin_data->mag_6);
308
/* 7th harmonic magnitude (float value) */
309
const LADSPA_Data mag_7 = *(plugin_data->mag_7);
311
/* 8th harmonic magnitude (float value) */
312
const LADSPA_Data mag_8 = *(plugin_data->mag_8);
314
/* 9th harmonic magnitude (float value) */
315
const LADSPA_Data mag_9 = *(plugin_data->mag_9);
317
/* 10th harmonic magnitude (float value) */
318
const LADSPA_Data mag_10 = *(plugin_data->mag_10);
320
/* Input (array of floats of length sample_count) */
321
const LADSPA_Data * const input = plugin_data->input;
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;
328
#line 61 "harmonic_gen_1220.xml"
329
unsigned long pos, i;
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};
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) {
342
mag_fix = 1.0f / mag_fix;
344
for (i=0; i<HARMONICS; i++) {
348
// Calculate polynomial coefficients, using Chebychev aproximation
351
for (pos = 0; pos < sample_count; pos++) {
352
float x = input[pos], y;
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) *
359
// DC offset remove (odd harmonics cause DC offset)
360
otm1 = 0.999f * otm1 + y - itm1;
363
buffer_write(output[pos], otm1);
366
plugin_data->itm1 = itm1;
367
plugin_data->otm1 = otm1;
372
LADSPA_PortDescriptor *port_descriptors;
373
LADSPA_PortRangeHint *port_range_hints;
376
#define D_(s) dgettext(PACKAGE, s)
377
setlocale(LC_ALL, "");
378
bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR);
384
harmonicGenDescriptor =
385
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
387
if (harmonicGenDescriptor) {
388
harmonicGenDescriptor->UniqueID = 1220;
389
harmonicGenDescriptor->Label = "harmonicGen";
390
harmonicGenDescriptor->Properties =
391
LADSPA_PROPERTY_HARD_RT_CAPABLE;
392
harmonicGenDescriptor->Name =
393
D_("Harmonic generator");
394
harmonicGenDescriptor->Maker =
395
"Steve Harris <steve@plugin.org.uk>";
396
harmonicGenDescriptor->Copyright =
398
harmonicGenDescriptor->PortCount = 12;
400
port_descriptors = (LADSPA_PortDescriptor *)calloc(12,
401
sizeof(LADSPA_PortDescriptor));
402
harmonicGenDescriptor->PortDescriptors =
403
(const LADSPA_PortDescriptor *)port_descriptors;
405
port_range_hints = (LADSPA_PortRangeHint *)calloc(12,
406
sizeof(LADSPA_PortRangeHint));
407
harmonicGenDescriptor->PortRangeHints =
408
(const LADSPA_PortRangeHint *)port_range_hints;
410
port_names = (char **)calloc(12, sizeof(char*));
411
harmonicGenDescriptor->PortNames =
412
(const char **)port_names;
414
/* Parameters for Fundamental magnitude */
415
port_descriptors[HARMONICGEN_MAG_1] =
416
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
417
port_names[HARMONICGEN_MAG_1] =
418
D_("Fundamental magnitude");
419
port_range_hints[HARMONICGEN_MAG_1].HintDescriptor =
420
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_1;
421
port_range_hints[HARMONICGEN_MAG_1].LowerBound = -1;
422
port_range_hints[HARMONICGEN_MAG_1].UpperBound = +1;
424
/* Parameters for 2nd harmonic magnitude */
425
port_descriptors[HARMONICGEN_MAG_2] =
426
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
427
port_names[HARMONICGEN_MAG_2] =
428
D_("2nd harmonic magnitude");
429
port_range_hints[HARMONICGEN_MAG_2].HintDescriptor =
430
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
431
port_range_hints[HARMONICGEN_MAG_2].LowerBound = -1;
432
port_range_hints[HARMONICGEN_MAG_2].UpperBound = +1;
434
/* Parameters for 3rd harmonic magnitude */
435
port_descriptors[HARMONICGEN_MAG_3] =
436
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
437
port_names[HARMONICGEN_MAG_3] =
438
D_("3rd harmonic magnitude");
439
port_range_hints[HARMONICGEN_MAG_3].HintDescriptor =
440
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
441
port_range_hints[HARMONICGEN_MAG_3].LowerBound = -1;
442
port_range_hints[HARMONICGEN_MAG_3].UpperBound = +1;
444
/* Parameters for 4th harmonic magnitude */
445
port_descriptors[HARMONICGEN_MAG_4] =
446
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
447
port_names[HARMONICGEN_MAG_4] =
448
D_("4th harmonic magnitude");
449
port_range_hints[HARMONICGEN_MAG_4].HintDescriptor =
450
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
451
port_range_hints[HARMONICGEN_MAG_4].LowerBound = -1;
452
port_range_hints[HARMONICGEN_MAG_4].UpperBound = +1;
454
/* Parameters for 5th harmonic magnitude */
455
port_descriptors[HARMONICGEN_MAG_5] =
456
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
457
port_names[HARMONICGEN_MAG_5] =
458
D_("5th harmonic magnitude");
459
port_range_hints[HARMONICGEN_MAG_5].HintDescriptor =
460
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
461
port_range_hints[HARMONICGEN_MAG_5].LowerBound = -1;
462
port_range_hints[HARMONICGEN_MAG_5].UpperBound = +1;
464
/* Parameters for 6th harmonic magnitude */
465
port_descriptors[HARMONICGEN_MAG_6] =
466
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
467
port_names[HARMONICGEN_MAG_6] =
468
D_("6th harmonic magnitude");
469
port_range_hints[HARMONICGEN_MAG_6].HintDescriptor =
470
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
471
port_range_hints[HARMONICGEN_MAG_6].LowerBound = -1;
472
port_range_hints[HARMONICGEN_MAG_6].UpperBound = +1;
474
/* Parameters for 7th harmonic magnitude */
475
port_descriptors[HARMONICGEN_MAG_7] =
476
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
477
port_names[HARMONICGEN_MAG_7] =
478
D_("7th harmonic magnitude");
479
port_range_hints[HARMONICGEN_MAG_7].HintDescriptor =
480
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
481
port_range_hints[HARMONICGEN_MAG_7].LowerBound = -1;
482
port_range_hints[HARMONICGEN_MAG_7].UpperBound = +1;
484
/* Parameters for 8th harmonic magnitude */
485
port_descriptors[HARMONICGEN_MAG_8] =
486
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
487
port_names[HARMONICGEN_MAG_8] =
488
D_("8th harmonic magnitude");
489
port_range_hints[HARMONICGEN_MAG_8].HintDescriptor =
490
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
491
port_range_hints[HARMONICGEN_MAG_8].LowerBound = -1;
492
port_range_hints[HARMONICGEN_MAG_8].UpperBound = +1;
494
/* Parameters for 9th harmonic magnitude */
495
port_descriptors[HARMONICGEN_MAG_9] =
496
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
497
port_names[HARMONICGEN_MAG_9] =
498
D_("9th harmonic magnitude");
499
port_range_hints[HARMONICGEN_MAG_9].HintDescriptor =
500
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
501
port_range_hints[HARMONICGEN_MAG_9].LowerBound = -1;
502
port_range_hints[HARMONICGEN_MAG_9].UpperBound = +1;
504
/* Parameters for 10th harmonic magnitude */
505
port_descriptors[HARMONICGEN_MAG_10] =
506
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
507
port_names[HARMONICGEN_MAG_10] =
508
D_("10th harmonic magnitude");
509
port_range_hints[HARMONICGEN_MAG_10].HintDescriptor =
510
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
511
port_range_hints[HARMONICGEN_MAG_10].LowerBound = -1;
512
port_range_hints[HARMONICGEN_MAG_10].UpperBound = +1;
514
/* Parameters for Input */
515
port_descriptors[HARMONICGEN_INPUT] =
516
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
517
port_names[HARMONICGEN_INPUT] =
519
port_range_hints[HARMONICGEN_INPUT].HintDescriptor =
520
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
521
port_range_hints[HARMONICGEN_INPUT].LowerBound = -1;
522
port_range_hints[HARMONICGEN_INPUT].UpperBound = +1;
524
/* Parameters for Output */
525
port_descriptors[HARMONICGEN_OUTPUT] =
526
LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
527
port_names[HARMONICGEN_OUTPUT] =
529
port_range_hints[HARMONICGEN_OUTPUT].HintDescriptor =
530
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
531
port_range_hints[HARMONICGEN_OUTPUT].LowerBound = -1;
532
port_range_hints[HARMONICGEN_OUTPUT].UpperBound = +1;
534
harmonicGenDescriptor->activate = activateHarmonicGen;
535
harmonicGenDescriptor->cleanup = cleanupHarmonicGen;
536
harmonicGenDescriptor->connect_port = connectPortHarmonicGen;
537
harmonicGenDescriptor->deactivate = NULL;
538
harmonicGenDescriptor->instantiate = instantiateHarmonicGen;
539
harmonicGenDescriptor->run = runHarmonicGen;
540
harmonicGenDescriptor->run_adding = runAddingHarmonicGen;
541
harmonicGenDescriptor->set_run_adding_gain = setRunAddingGainHarmonicGen;
546
if (harmonicGenDescriptor) {
547
free((LADSPA_PortDescriptor *)harmonicGenDescriptor->PortDescriptors);
548
free((char **)harmonicGenDescriptor->PortNames);
549
free((LADSPA_PortRangeHint *)harmonicGenDescriptor->PortRangeHints);
550
free(harmonicGenDescriptor);