2
Copyright (C) 2004 Tom Szilagyi
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.
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.
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.
18
$Id: tap_vibrato.c,v 1.3 2004/02/21 17:33:36 tszilagyi Exp $
28
#include "tap_utils.h"
31
/* The Unique ID of the plugin: */
35
/* The port numbers for the plugin: */
45
/* Total number of ports */
48
#define PORTCOUNT_MONO 7
52
* This has to be bigger than 0.2f * sample_rate / (2*PI) for any sample rate.
53
* At 192 kHz 6238 is needed so this should be enough.
61
#define COS_TABLE_SIZE 1024
62
LADSPA_Data cos_table[COS_TABLE_SIZE];
65
/* The structure used to hold port connection information and state */
70
LADSPA_Data * drylevel;
71
LADSPA_Data * wetlevel;
72
LADSPA_Data * latency;
76
LADSPA_Data * ringbuffer;
81
unsigned long sample_rate;
82
LADSPA_Data run_adding_gain;
87
/* Construct a new plugin instance. */
89
instantiate_Vibrato(const LADSPA_Descriptor * Descriptor,
90
unsigned long sample_rate) {
94
if ((ptr = malloc(sizeof(Vibrato))) != NULL) {
95
((Vibrato *)ptr)->sample_rate = sample_rate;
96
((Vibrato *)ptr)->run_adding_gain = 1.0f;
98
if ((((Vibrato *)ptr)->ringbuffer =
99
calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
104
((Vibrato *)ptr)->buflen = ceil(0.2f * sample_rate / M_PI);
105
((Vibrato *)ptr)->pos = 0;
114
activate_Vibrato(LADSPA_Handle Instance) {
116
Vibrato * ptr = (Vibrato *)Instance;
119
for (i = 0; i < 2 * PM_DEPTH; i++)
120
ptr->ringbuffer[i] = 0.0f;
129
/* Connect a port to a data location. */
131
connect_port_Vibrato(LADSPA_Handle Instance,
133
LADSPA_Data * DataLocation) {
135
Vibrato * ptr = (Vibrato *)Instance;
139
ptr->depth = DataLocation;
142
ptr->freq = DataLocation;
145
ptr->drylevel = DataLocation;
148
ptr->wetlevel = DataLocation;
151
ptr->latency = DataLocation;
152
*(ptr->latency) = ptr->buflen / 2; /* IS THIS LEGAL? */
155
ptr->input = DataLocation;
158
ptr->output = DataLocation;
166
run_Vibrato(LADSPA_Handle Instance,
167
unsigned long SampleCount) {
169
Vibrato * ptr = (Vibrato *)Instance;
171
LADSPA_Data freq = LIMIT(*(ptr->freq),0.0f,PM_FREQ);
173
LIMIT(LIMIT(*(ptr->depth),0.0f,20.0f) * ptr->sample_rate / 200.0f / M_PI / freq,
175
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
176
LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
177
LADSPA_Data * input = ptr->input;
178
LADSPA_Data * output = ptr->output;
180
unsigned long sample_index;
181
unsigned long sample_count = SampleCount;
183
LADSPA_Data in = 0.0f;
184
LADSPA_Data phase = 0.0f;
185
LADSPA_Data fpos = 0.0f;
186
LADSPA_Data n = 0.0f;
187
LADSPA_Data rem = 0.0f;
188
LADSPA_Data s_a, s_b;
194
for (sample_index = 0; sample_index < sample_count; sample_index++) {
198
phase = COS_TABLE_SIZE * freq * sample_index / ptr->sample_rate + ptr->phase;
199
while (phase >= COS_TABLE_SIZE)
200
phase -= COS_TABLE_SIZE;
202
push_buffer(in, ptr->ringbuffer, ptr->buflen, &(ptr->pos));
204
fpos = depth * (1.0f - cos_table[(unsigned long) phase]);
208
s_a = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n);
209
s_b = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n + 1);
211
*(output++) = wetlevel * ((1 - rem) * s_a + rem * s_b) +
212
drylevel * read_buffer(ptr->ringbuffer, ptr->buflen,
213
ptr->pos, ptr->buflen / 2);
217
ptr->phase += COS_TABLE_SIZE * freq * sample_index / ptr->sample_rate;
218
while (ptr->phase >= COS_TABLE_SIZE)
219
ptr->phase -= COS_TABLE_SIZE;
221
*(ptr->latency) = ptr->buflen / 2;
226
set_run_adding_gain_Vibrato(LADSPA_Handle Instance, LADSPA_Data gain) {
228
Vibrato * ptr = (Vibrato *)Instance;
230
ptr->run_adding_gain = gain;
236
run_adding_Vibrato(LADSPA_Handle Instance,
237
unsigned long SampleCount) {
239
Vibrato * ptr = (Vibrato *)Instance;
241
LADSPA_Data freq = LIMIT(*(ptr->freq),0.0f,PM_FREQ);
243
LIMIT(LIMIT(*(ptr->depth),0.0f,20.0f) * ptr->sample_rate / 200.0f / M_PI / freq,
245
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
246
LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
247
LADSPA_Data * input = ptr->input;
248
LADSPA_Data * output = ptr->output;
250
unsigned long sample_index;
251
unsigned long sample_count = SampleCount;
253
LADSPA_Data in = 0.0f;
254
LADSPA_Data phase = 0.0f;
255
LADSPA_Data fpos = 0.0f;
256
LADSPA_Data n = 0.0f;
257
LADSPA_Data rem = 0.0f;
258
LADSPA_Data s_a, s_b;
264
for (sample_index = 0; sample_index < sample_count; sample_index++) {
268
phase = COS_TABLE_SIZE * freq * sample_index / ptr->sample_rate + ptr->phase;
269
while (phase >= COS_TABLE_SIZE)
270
phase -= COS_TABLE_SIZE;
272
push_buffer(in, ptr->ringbuffer, ptr->buflen, &(ptr->pos));
274
fpos = depth * (1.0f - cos_table[(unsigned long) phase]);
278
s_a = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n);
279
s_b = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n + 1);
281
*(output++) += ptr->run_adding_gain * wetlevel * ((1 - rem) * s_a + rem * s_b) +
282
drylevel * read_buffer(ptr->ringbuffer, ptr->buflen,
283
ptr->pos, ptr->buflen / 2);
287
ptr->phase += COS_TABLE_SIZE * freq * sample_index / ptr->sample_rate;
288
while (ptr->phase >= COS_TABLE_SIZE)
289
ptr->phase -= COS_TABLE_SIZE;
291
*(ptr->latency) = ptr->buflen / 2;
296
/* Throw away a Vibrato effect instance. */
298
cleanup_Vibrato(LADSPA_Handle Instance) {
300
Vibrato * ptr = (Vibrato *)Instance;
301
free(ptr->ringbuffer);
307
LADSPA_Descriptor * mono_descriptor = NULL;
311
/* __attribute__((constructor)) _init() is called automatically when the plugin library is first
314
__attribute__((constructor)) _init() {
318
LADSPA_PortDescriptor * port_descriptors;
319
LADSPA_PortRangeHint * port_range_hints;
321
if ((mono_descriptor =
322
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
325
for (i = 0; i < COS_TABLE_SIZE; i++)
326
cos_table[i] = cosf(i * 2.0f * M_PI / COS_TABLE_SIZE);
328
mono_descriptor->UniqueID = ID_MONO;
329
mono_descriptor->Label = strdup("tap_vibrato");
330
mono_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
331
mono_descriptor->Name = strdup("TAP Vibrato");
332
mono_descriptor->Maker = strdup("Tom Szilagyi");
333
mono_descriptor->Copyright = strdup("GPL");
334
mono_descriptor->PortCount = PORTCOUNT_MONO;
336
if ((port_descriptors =
337
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
340
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
341
port_descriptors[DEPTH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
342
port_descriptors[FREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
343
port_descriptors[DRYLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
344
port_descriptors[WETLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
345
port_descriptors[LATENCY] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
346
port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
347
port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
350
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
353
mono_descriptor->PortNames = (const char **)port_names;
354
port_names[FREQ] = strdup("Frequency [Hz]");
355
port_names[DEPTH] = strdup("Depth [%]");
356
port_names[DRYLEVEL] = strdup("Dry Level [dB]");
357
port_names[WETLEVEL] = strdup("Wet Level [dB]");
358
port_names[LATENCY] = strdup("latency");
359
port_names[INPUT] = strdup("Input");
360
port_names[OUTPUT] = strdup("Output");
362
if ((port_range_hints =
363
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
366
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
367
port_range_hints[DEPTH].HintDescriptor =
368
(LADSPA_HINT_BOUNDED_BELOW |
369
LADSPA_HINT_BOUNDED_ABOVE |
370
LADSPA_HINT_DEFAULT_0);
371
port_range_hints[FREQ].HintDescriptor =
372
(LADSPA_HINT_BOUNDED_BELOW |
373
LADSPA_HINT_BOUNDED_ABOVE |
374
LADSPA_HINT_DEFAULT_0);
375
port_range_hints[DRYLEVEL].HintDescriptor =
376
(LADSPA_HINT_BOUNDED_BELOW |
377
LADSPA_HINT_BOUNDED_ABOVE |
378
LADSPA_HINT_DEFAULT_MINIMUM);
379
port_range_hints[WETLEVEL].HintDescriptor =
380
(LADSPA_HINT_BOUNDED_BELOW |
381
LADSPA_HINT_BOUNDED_ABOVE |
382
LADSPA_HINT_DEFAULT_0);
383
port_range_hints[LATENCY].HintDescriptor =
384
(LADSPA_HINT_BOUNDED_BELOW |
385
LADSPA_HINT_BOUNDED_ABOVE |
386
LADSPA_HINT_DEFAULT_MAXIMUM);
387
port_range_hints[DEPTH].LowerBound = 0;
388
port_range_hints[DEPTH].UpperBound = 20.0f;
389
port_range_hints[FREQ].LowerBound = 0;
390
port_range_hints[FREQ].UpperBound = PM_FREQ;
391
port_range_hints[DRYLEVEL].LowerBound = -90.0f;
392
port_range_hints[DRYLEVEL].UpperBound = +20.0f;
393
port_range_hints[WETLEVEL].LowerBound = -90.0f;
394
port_range_hints[WETLEVEL].UpperBound = +20.0f;
395
port_range_hints[LATENCY].LowerBound = 0;
396
port_range_hints[LATENCY].UpperBound = PM_DEPTH;
397
port_range_hints[INPUT].HintDescriptor = 0;
398
port_range_hints[OUTPUT].HintDescriptor = 0;
399
mono_descriptor->instantiate = instantiate_Vibrato;
400
mono_descriptor->connect_port = connect_port_Vibrato;
401
mono_descriptor->activate = activate_Vibrato;
402
mono_descriptor->run = run_Vibrato;
403
mono_descriptor->run_adding = run_adding_Vibrato;
404
mono_descriptor->set_run_adding_gain = set_run_adding_gain_Vibrato;
405
mono_descriptor->deactivate = NULL;
406
mono_descriptor->cleanup = cleanup_Vibrato;
411
delete_descriptor(LADSPA_Descriptor * descriptor) {
414
free((char *)descriptor->Label);
415
free((char *)descriptor->Name);
416
free((char *)descriptor->Maker);
417
free((char *)descriptor->Copyright);
418
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
419
for (index = 0; index < descriptor->PortCount; index++)
420
free((char *)(descriptor->PortNames[index]));
421
free((char **)descriptor->PortNames);
422
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
428
/* __attribute__((destructor)) _fini() is called automatically when the library is unloaded. */
430
__attribute__((destructor)) _fini() {
431
delete_descriptor(mono_descriptor);
435
/* Return a descriptor of the requested plugin type. */
436
const LADSPA_Descriptor *
437
ladspa_descriptor(unsigned long Index) {
441
return mono_descriptor;