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 "gverb_1216.xml"
29
30 /*
31
32 GVerb algorithm designed and implemented by Juhana Sadeharju.
33 LADSPA implementation and GVerb speeds ups by Steve Harris.
34
35 Comments and suggestions should be mailed to Juhana Sadeharju
36 (kouhia at nic funet fi).
37
38 */
39
40 #include "ladspa-util.h"
41 #include "gverb/gverbdsp.h"
42 #include "gverb/gverb.h"
43
44 #define GVERB_ROOMSIZE 0
45 #define GVERB_REVTIME 1
46 #define GVERB_DAMPING 2
47 #define GVERB_INPUTBANDWIDTH 3
48 #define GVERB_DRYLEVEL 4
49 #define GVERB_EARLYLEVEL 5
50 #define GVERB_TAILLEVEL 6
51 #define GVERB_INPUT 7
52 #define GVERB_OUTL 8
53 #define GVERB_OUTR 9
54
55 static LADSPA_Descriptor *gverbDescriptor = NULL;
56
57 typedef struct {
58 LADSPA_Data *roomsize;
59 LADSPA_Data *revtime;
60 LADSPA_Data *damping;
61 LADSPA_Data *inputbandwidth;
62 LADSPA_Data *drylevel;
63 LADSPA_Data *earlylevel;
64 LADSPA_Data *taillevel;
65 LADSPA_Data *input;
66 LADSPA_Data *outl;
67 LADSPA_Data *outr;
68 ty_gverb * verb;
69 LADSPA_Data run_adding_gain;
70 } Gverb;
71
72 _WINDOWS_DLL_EXPORT_
ladspa_descriptor(unsigned long index)73 const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) {
74
75 #ifdef WIN32
76 if (bIsFirstTime) {
77 swh_init();
78 bIsFirstTime = 0;
79 }
80 #endif
81 switch (index) {
82 case 0:
83 return gverbDescriptor;
84 default:
85 return NULL;
86 }
87 }
88
activateGverb(LADSPA_Handle instance)89 static void activateGverb(LADSPA_Handle instance) {
90 Gverb *plugin_data = (Gverb *)instance;
91 ty_gverb *verb = plugin_data->verb;
92 #line 54 "gverb_1216.xml"
93 gverb_flush(plugin_data->verb);
94 plugin_data->verb = verb;
95
96 }
97
cleanupGverb(LADSPA_Handle instance)98 static void cleanupGverb(LADSPA_Handle instance) {
99 #line 58 "gverb_1216.xml"
100 Gverb *plugin_data = (Gverb *)instance;
101 gverb_free(plugin_data->verb);
102 free(instance);
103 }
104
connectPortGverb(LADSPA_Handle instance,unsigned long port,LADSPA_Data * data)105 static void connectPortGverb(
106 LADSPA_Handle instance,
107 unsigned long port,
108 LADSPA_Data *data) {
109 Gverb *plugin;
110
111 plugin = (Gverb *)instance;
112 switch (port) {
113 case GVERB_ROOMSIZE:
114 plugin->roomsize = data;
115 break;
116 case GVERB_REVTIME:
117 plugin->revtime = data;
118 break;
119 case GVERB_DAMPING:
120 plugin->damping = data;
121 break;
122 case GVERB_INPUTBANDWIDTH:
123 plugin->inputbandwidth = data;
124 break;
125 case GVERB_DRYLEVEL:
126 plugin->drylevel = data;
127 break;
128 case GVERB_EARLYLEVEL:
129 plugin->earlylevel = data;
130 break;
131 case GVERB_TAILLEVEL:
132 plugin->taillevel = data;
133 break;
134 case GVERB_INPUT:
135 plugin->input = data;
136 break;
137 case GVERB_OUTL:
138 plugin->outl = data;
139 break;
140 case GVERB_OUTR:
141 plugin->outr = data;
142 break;
143 }
144 }
145
instantiateGverb(const LADSPA_Descriptor * descriptor,unsigned long s_rate)146 static LADSPA_Handle instantiateGverb(
147 const LADSPA_Descriptor *descriptor,
148 unsigned long s_rate) {
149 Gverb *plugin_data = (Gverb *)calloc(1, sizeof(Gverb));
150 ty_gverb *verb = NULL;
151
152 #line 50 "gverb_1216.xml"
153 verb = gverb_new(s_rate, 300.0f, 50.0f, 7.0f, 0.5f, 15.0f, 0.5f, 0.5f, 0.5f);
154
155 plugin_data->verb = verb;
156
157 return (LADSPA_Handle)plugin_data;
158 }
159
160 #undef buffer_write
161 #undef RUN_ADDING
162 #undef RUN_REPLACING
163
164 #define buffer_write(b, v) (b = v)
165 #define RUN_ADDING 0
166 #define RUN_REPLACING 1
167
runGverb(LADSPA_Handle instance,unsigned long sample_count)168 static void runGverb(LADSPA_Handle instance, unsigned long sample_count) {
169 Gverb *plugin_data = (Gverb *)instance;
170
171 /* Roomsize (m) (float value) */
172 const LADSPA_Data roomsize = *(plugin_data->roomsize);
173
174 /* Reverb time (s) (float value) */
175 const LADSPA_Data revtime = *(plugin_data->revtime);
176
177 /* Damping (float value) */
178 const LADSPA_Data damping = *(plugin_data->damping);
179
180 /* Input bandwidth (float value) */
181 const LADSPA_Data inputbandwidth = *(plugin_data->inputbandwidth);
182
183 /* Dry signal level (dB) (float value) */
184 const LADSPA_Data drylevel = *(plugin_data->drylevel);
185
186 /* Early reflection level (dB) (float value) */
187 const LADSPA_Data earlylevel = *(plugin_data->earlylevel);
188
189 /* Tail level (dB) (float value) */
190 const LADSPA_Data taillevel = *(plugin_data->taillevel);
191
192 /* Input (array of floats of length sample_count) */
193 const LADSPA_Data * const input = plugin_data->input;
194
195 /* Left output (array of floats of length sample_count) */
196 LADSPA_Data * const outl = plugin_data->outl;
197
198 /* Right output (array of floats of length sample_count) */
199 LADSPA_Data * const outr = plugin_data->outr;
200 ty_gverb * verb = plugin_data->verb;
201
202 #line 62 "gverb_1216.xml"
203 unsigned long pos;
204 float l, r;
205 float dryc = DB_CO(drylevel);
206
207 gverb_set_roomsize(verb, roomsize);
208 gverb_set_revtime(verb, revtime);
209 gverb_set_damping(verb, damping);
210 gverb_set_inputbandwidth(verb, inputbandwidth);
211 gverb_set_earlylevel(verb, DB_CO(earlylevel));
212 gverb_set_taillevel(verb, DB_CO(taillevel));
213
214 for (pos = 0; pos < sample_count; pos++) {
215 gverb_do(verb, input[pos], &l, &r);
216 buffer_write(outl[pos], l + input[pos] * dryc);
217 buffer_write(outr[pos], r + input[pos] * dryc);
218 }
219 }
220 #undef buffer_write
221 #undef RUN_ADDING
222 #undef RUN_REPLACING
223
224 #define buffer_write(b, v) (b += (v) * run_adding_gain)
225 #define RUN_ADDING 1
226 #define RUN_REPLACING 0
227
setRunAddingGainGverb(LADSPA_Handle instance,LADSPA_Data gain)228 static void setRunAddingGainGverb(LADSPA_Handle instance, LADSPA_Data gain) {
229 ((Gverb *)instance)->run_adding_gain = gain;
230 }
231
runAddingGverb(LADSPA_Handle instance,unsigned long sample_count)232 static void runAddingGverb(LADSPA_Handle instance, unsigned long sample_count) {
233 Gverb *plugin_data = (Gverb *)instance;
234 LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;
235
236 /* Roomsize (m) (float value) */
237 const LADSPA_Data roomsize = *(plugin_data->roomsize);
238
239 /* Reverb time (s) (float value) */
240 const LADSPA_Data revtime = *(plugin_data->revtime);
241
242 /* Damping (float value) */
243 const LADSPA_Data damping = *(plugin_data->damping);
244
245 /* Input bandwidth (float value) */
246 const LADSPA_Data inputbandwidth = *(plugin_data->inputbandwidth);
247
248 /* Dry signal level (dB) (float value) */
249 const LADSPA_Data drylevel = *(plugin_data->drylevel);
250
251 /* Early reflection level (dB) (float value) */
252 const LADSPA_Data earlylevel = *(plugin_data->earlylevel);
253
254 /* Tail level (dB) (float value) */
255 const LADSPA_Data taillevel = *(plugin_data->taillevel);
256
257 /* Input (array of floats of length sample_count) */
258 const LADSPA_Data * const input = plugin_data->input;
259
260 /* Left output (array of floats of length sample_count) */
261 LADSPA_Data * const outl = plugin_data->outl;
262
263 /* Right output (array of floats of length sample_count) */
264 LADSPA_Data * const outr = plugin_data->outr;
265 ty_gverb * verb = plugin_data->verb;
266
267 #line 62 "gverb_1216.xml"
268 unsigned long pos;
269 float l, r;
270 float dryc = DB_CO(drylevel);
271
272 gverb_set_roomsize(verb, roomsize);
273 gverb_set_revtime(verb, revtime);
274 gverb_set_damping(verb, damping);
275 gverb_set_inputbandwidth(verb, inputbandwidth);
276 gverb_set_earlylevel(verb, DB_CO(earlylevel));
277 gverb_set_taillevel(verb, DB_CO(taillevel));
278
279 for (pos = 0; pos < sample_count; pos++) {
280 gverb_do(verb, input[pos], &l, &r);
281 buffer_write(outl[pos], l + input[pos] * dryc);
282 buffer_write(outr[pos], r + input[pos] * dryc);
283 }
284 }
285
swh_init()286 static void __attribute__((constructor)) swh_init() {
287 char **port_names;
288 LADSPA_PortDescriptor *port_descriptors;
289 LADSPA_PortRangeHint *port_range_hints;
290
291 #ifdef ENABLE_NLS
292 #define D_(s) dgettext(PACKAGE, s)
293 bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR);
294 #else
295 #define D_(s) (s)
296 #endif
297
298
299 gverbDescriptor =
300 (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
301
302 if (gverbDescriptor) {
303 gverbDescriptor->UniqueID = 1216;
304 gverbDescriptor->Label = "gverb";
305 gverbDescriptor->Properties =
306 LADSPA_PROPERTY_HARD_RT_CAPABLE;
307 gverbDescriptor->Name =
308 D_("GVerb");
309 gverbDescriptor->Maker =
310 "Juhana Sadeharju <kouhia at nic.funet.fi>, LADSPAification by Steve Harris <steve@plugin.org.uk>";
311 gverbDescriptor->Copyright =
312 "GPL";
313 gverbDescriptor->PortCount = 10;
314
315 port_descriptors = (LADSPA_PortDescriptor *)calloc(10,
316 sizeof(LADSPA_PortDescriptor));
317 gverbDescriptor->PortDescriptors =
318 (const LADSPA_PortDescriptor *)port_descriptors;
319
320 port_range_hints = (LADSPA_PortRangeHint *)calloc(10,
321 sizeof(LADSPA_PortRangeHint));
322 gverbDescriptor->PortRangeHints =
323 (const LADSPA_PortRangeHint *)port_range_hints;
324
325 port_names = (char **)calloc(10, sizeof(char*));
326 gverbDescriptor->PortNames =
327 (const char **)port_names;
328
329 /* Parameters for Roomsize (m) */
330 port_descriptors[GVERB_ROOMSIZE] =
331 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
332 port_names[GVERB_ROOMSIZE] =
333 D_("Roomsize (m)");
334 port_range_hints[GVERB_ROOMSIZE].HintDescriptor =
335 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW;
336 port_range_hints[GVERB_ROOMSIZE].LowerBound = 1;
337 port_range_hints[GVERB_ROOMSIZE].UpperBound = 300;
338
339 /* Parameters for Reverb time (s) */
340 port_descriptors[GVERB_REVTIME] =
341 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
342 port_names[GVERB_REVTIME] =
343 D_("Reverb time (s)");
344 port_range_hints[GVERB_REVTIME].HintDescriptor =
345 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW;
346 port_range_hints[GVERB_REVTIME].LowerBound = 0.1;
347 port_range_hints[GVERB_REVTIME].UpperBound = 30;
348
349 /* Parameters for Damping */
350 port_descriptors[GVERB_DAMPING] =
351 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
352 port_names[GVERB_DAMPING] =
353 D_("Damping");
354 port_range_hints[GVERB_DAMPING].HintDescriptor =
355 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE;
356 port_range_hints[GVERB_DAMPING].LowerBound = 0;
357 port_range_hints[GVERB_DAMPING].UpperBound = 1;
358
359 /* Parameters for Input bandwidth */
360 port_descriptors[GVERB_INPUTBANDWIDTH] =
361 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
362 port_names[GVERB_INPUTBANDWIDTH] =
363 D_("Input bandwidth");
364 port_range_hints[GVERB_INPUTBANDWIDTH].HintDescriptor =
365 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_HIGH;
366 port_range_hints[GVERB_INPUTBANDWIDTH].LowerBound = 0;
367 port_range_hints[GVERB_INPUTBANDWIDTH].UpperBound = 1;
368
369 /* Parameters for Dry signal level (dB) */
370 port_descriptors[GVERB_DRYLEVEL] =
371 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
372 port_names[GVERB_DRYLEVEL] =
373 D_("Dry signal level (dB)");
374 port_range_hints[GVERB_DRYLEVEL].HintDescriptor =
375 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MINIMUM;
376 port_range_hints[GVERB_DRYLEVEL].LowerBound = -70;
377 port_range_hints[GVERB_DRYLEVEL].UpperBound = 0;
378
379 /* Parameters for Early reflection level (dB) */
380 port_descriptors[GVERB_EARLYLEVEL] =
381 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
382 port_names[GVERB_EARLYLEVEL] =
383 D_("Early reflection level (dB)");
384 port_range_hints[GVERB_EARLYLEVEL].HintDescriptor =
385 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
386 port_range_hints[GVERB_EARLYLEVEL].LowerBound = -70;
387 port_range_hints[GVERB_EARLYLEVEL].UpperBound = 0;
388
389 /* Parameters for Tail level (dB) */
390 port_descriptors[GVERB_TAILLEVEL] =
391 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
392 port_names[GVERB_TAILLEVEL] =
393 D_("Tail level (dB)");
394 port_range_hints[GVERB_TAILLEVEL].HintDescriptor =
395 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_HIGH;
396 port_range_hints[GVERB_TAILLEVEL].LowerBound = -70;
397 port_range_hints[GVERB_TAILLEVEL].UpperBound = 0;
398
399 /* Parameters for Input */
400 port_descriptors[GVERB_INPUT] =
401 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
402 port_names[GVERB_INPUT] =
403 D_("Input");
404 port_range_hints[GVERB_INPUT].HintDescriptor = 0;
405
406 /* Parameters for Left output */
407 port_descriptors[GVERB_OUTL] =
408 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
409 port_names[GVERB_OUTL] =
410 D_("Left output");
411 port_range_hints[GVERB_OUTL].HintDescriptor = 0;
412
413 /* Parameters for Right output */
414 port_descriptors[GVERB_OUTR] =
415 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
416 port_names[GVERB_OUTR] =
417 D_("Right output");
418 port_range_hints[GVERB_OUTR].HintDescriptor = 0;
419
420 gverbDescriptor->activate = activateGverb;
421 gverbDescriptor->cleanup = cleanupGverb;
422 gverbDescriptor->connect_port = connectPortGverb;
423 gverbDescriptor->deactivate = NULL;
424 gverbDescriptor->instantiate = instantiateGverb;
425 gverbDescriptor->run = runGverb;
426 gverbDescriptor->run_adding = runAddingGverb;
427 gverbDescriptor->set_run_adding_gain = setRunAddingGainGverb;
428 }
429 }
430
swh_fini()431 static void __attribute__((destructor)) swh_fini() {
432 if (gverbDescriptor) {
433 free((LADSPA_PortDescriptor *)gverbDescriptor->PortDescriptors);
434 free((char **)gverbDescriptor->PortNames);
435 free((LADSPA_PortRangeHint *)gverbDescriptor->PortRangeHints);
436 free(gverbDescriptor);
437 }
438 gverbDescriptor = NULL;
439
440 }
441