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