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_tremolo.c,v 1.6 2004/02/21 17:33:36 tszilagyi Exp $
28
#include "tap_utils.h"
30
/* The Unique ID of the plugin: */
34
/* The port numbers for the plugin: */
36
#define CONTROL_FREQ 0
37
#define CONTROL_DEPTH 1
38
#define CONTROL_GAIN 2
43
/* Total number of ports */
45
#define PORTCOUNT_MONO 5
48
/* cosine table for fast computations */
49
LADSPA_Data cos_table[1024];
52
/* The structure used to hold port connection information and state */
55
LADSPA_Data * Control_Freq;
56
LADSPA_Data * Control_Depth;
57
LADSPA_Data * Control_Gain;
58
LADSPA_Data * InputBuffer_1;
59
LADSPA_Data * OutputBuffer_1;
60
unsigned long SampleRate;
62
LADSPA_Data run_adding_gain;
67
/* Construct a new plugin instance. */
69
instantiate_Tremolo(const LADSPA_Descriptor * Descriptor,
70
unsigned long SampleRate) {
74
if ((ptr = malloc(sizeof(Tremolo))) != NULL) {
75
((Tremolo *)ptr)->SampleRate = SampleRate;
76
((Tremolo *)ptr)->run_adding_gain = 1.0;
84
activate_Tremolo(LADSPA_Handle Instance) {
88
ptr = (Tremolo *)Instance;
94
/* Connect a port to a data location. */
96
connect_port_Tremolo(LADSPA_Handle Instance,
98
LADSPA_Data * DataLocation) {
102
ptr = (Tremolo *)Instance;
105
ptr->Control_Freq = DataLocation;
108
ptr->Control_Depth = DataLocation;
111
ptr->Control_Gain = DataLocation;
114
ptr->InputBuffer_1 = DataLocation;
117
ptr->OutputBuffer_1 = DataLocation;
125
run_Tremolo(LADSPA_Handle Instance,
126
unsigned long SampleCount) {
129
LADSPA_Data * output;
134
unsigned long sample_index;
135
LADSPA_Data phase = 0.0f;
137
ptr = (Tremolo *)Instance;
139
input = ptr->InputBuffer_1;
140
output = ptr->OutputBuffer_1;
141
freq = LIMIT(*(ptr->Control_Freq),0.0f,20.0f);
142
depth = LIMIT(*(ptr->Control_Depth),0.0f,100.0f);
143
gain = db2lin(LIMIT(*(ptr->Control_Gain),-70.0f,20.0f));
145
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
146
phase = 1024.0f * freq * sample_index / ptr->SampleRate + ptr->Phase;
148
while (phase >= 1024.0f)
151
*(output++) = *(input++) * gain *
152
(1 - 0.5*depth/100 + 0.5 * depth/100 * cos_table[(unsigned long) phase]);
155
while (ptr->Phase >= 1024.0f)
156
ptr->Phase -= 1024.0f;
162
set_run_adding_gain_Tremolo(LADSPA_Handle Instance, LADSPA_Data gain) {
166
ptr = (Tremolo *)Instance;
168
ptr->run_adding_gain = gain;
174
run_adding_Tremolo(LADSPA_Handle Instance,
175
unsigned long SampleCount) {
178
LADSPA_Data * output;
183
unsigned long sample_index;
184
LADSPA_Data phase = 0.0f;
186
ptr = (Tremolo *)Instance;
188
input = ptr->InputBuffer_1;
189
output = ptr->OutputBuffer_1;
190
freq = LIMIT(*(ptr->Control_Freq),0.0f,20.0f);
191
depth = LIMIT(*(ptr->Control_Depth),0.0f,100.0f);
192
gain = db2lin(LIMIT(*(ptr->Control_Gain),-70.0f,20.0f));
194
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
195
phase = 1024.0f * freq * sample_index / ptr->SampleRate + ptr->Phase;
197
while (phase >= 1024.0f)
200
*(output++) += *(input++) * ptr->run_adding_gain * gain *
201
(1 - 0.5*depth/100 + 0.5 * depth/100 * cos_table[(unsigned long) phase]);
204
while (ptr->Phase >= 1024.0f)
205
ptr->Phase -= 1024.0f;
211
/* Throw away a Tremolo effect instance. */
213
cleanup_Tremolo(LADSPA_Handle Instance) {
219
LADSPA_Descriptor * mono_descriptor = NULL;
223
/* __attribute__((constructor)) _init() is called automatically when the plugin library is first
226
__attribute__((constructor)) _init() {
229
LADSPA_PortDescriptor * port_descriptors;
230
LADSPA_PortRangeHint * port_range_hints;
233
if ((mono_descriptor =
234
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
238
for (i = 0; i < 1024; i++)
239
cos_table[i] = cosf(i * M_PI / 512.0f);
242
mono_descriptor->UniqueID = ID_MONO;
243
mono_descriptor->Label = strdup("tap_tremolo");
244
mono_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
245
mono_descriptor->Name = strdup("TAP Tremolo");
246
mono_descriptor->Maker = strdup("Tom Szilagyi");
247
mono_descriptor->Copyright = strdup("GPL");
248
mono_descriptor->PortCount = PORTCOUNT_MONO;
250
if ((port_descriptors =
251
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
254
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
255
port_descriptors[CONTROL_FREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
256
port_descriptors[CONTROL_DEPTH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
257
port_descriptors[CONTROL_GAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
258
port_descriptors[INPUT_0] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
259
port_descriptors[OUTPUT_0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
262
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
265
mono_descriptor->PortNames = (const char **)port_names;
266
port_names[CONTROL_FREQ] = strdup("Frequency [Hz]");
267
port_names[CONTROL_DEPTH] = strdup("Depth [%]");
268
port_names[CONTROL_GAIN] = strdup("Gain [dB]");
269
port_names[INPUT_0] = strdup("Input_0");
270
port_names[OUTPUT_0] = strdup("Output_0");
272
if ((port_range_hints =
273
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
276
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
277
port_range_hints[CONTROL_FREQ].HintDescriptor =
278
(LADSPA_HINT_BOUNDED_BELOW |
279
LADSPA_HINT_BOUNDED_ABOVE |
280
LADSPA_HINT_DEFAULT_0);
281
port_range_hints[CONTROL_DEPTH].HintDescriptor =
282
(LADSPA_HINT_BOUNDED_BELOW |
283
LADSPA_HINT_BOUNDED_ABOVE |
284
LADSPA_HINT_DEFAULT_0);
285
port_range_hints[CONTROL_GAIN].HintDescriptor =
286
(LADSPA_HINT_BOUNDED_BELOW |
287
LADSPA_HINT_BOUNDED_ABOVE |
288
LADSPA_HINT_DEFAULT_0);
289
port_range_hints[CONTROL_FREQ].LowerBound = 0;
290
port_range_hints[CONTROL_FREQ].UpperBound = 20;
291
port_range_hints[CONTROL_DEPTH].LowerBound = 0;
292
port_range_hints[CONTROL_DEPTH].UpperBound = 100;
293
port_range_hints[CONTROL_GAIN].LowerBound = -70;
294
port_range_hints[CONTROL_GAIN].UpperBound = 20;
295
port_range_hints[INPUT_0].HintDescriptor = 0;
296
port_range_hints[OUTPUT_0].HintDescriptor = 0;
297
mono_descriptor->instantiate = instantiate_Tremolo;
298
mono_descriptor->connect_port = connect_port_Tremolo;
299
mono_descriptor->activate = activate_Tremolo;
300
mono_descriptor->run = run_Tremolo;
301
mono_descriptor->run_adding = run_adding_Tremolo;
302
mono_descriptor->set_run_adding_gain = set_run_adding_gain_Tremolo;
303
mono_descriptor->deactivate = NULL;
304
mono_descriptor->cleanup = cleanup_Tremolo;
309
delete_descriptor(LADSPA_Descriptor * descriptor) {
312
free((char *)descriptor->Label);
313
free((char *)descriptor->Name);
314
free((char *)descriptor->Maker);
315
free((char *)descriptor->Copyright);
316
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
317
for (index = 0; index < descriptor->PortCount; index++)
318
free((char *)(descriptor->PortNames[index]));
319
free((char **)descriptor->PortNames);
320
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
326
/* __attribute__((destructor)) _fini() is called automatically when the library is unloaded. */
328
__attribute__((destructor)) _fini() {
329
delete_descriptor(mono_descriptor);
333
/* Return a descriptor of the requested plugin type. */
334
const LADSPA_Descriptor *
335
ladspa_descriptor(unsigned long Index) {
339
return mono_descriptor;