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 9 "gsm_1215.xml"
29 
30 #include <stdlib.h>
31 #include "ladspa-util.h"
32 #include "gsm/gsm.h"
33 #include "util/biquad.h"
34 
35 #define SCALE 32768.0f
36 #define SCALE_R 0.0000305175f
37 
38 int bits[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
39 
40 #define GSM_DRYWET                     0
41 #define GSM_PASSES                     1
42 #define GSM_ERROR                      2
43 #define GSM_INPUT                      3
44 #define GSM_OUTPUT                     4
45 #define GSM_LATENCY                    5
46 
47 static LADSPA_Descriptor *gsmDescriptor = NULL;
48 
49 typedef struct {
50 	LADSPA_Data *drywet;
51 	LADSPA_Data *passes;
52 	LADSPA_Data *error;
53 	LADSPA_Data *input;
54 	LADSPA_Data *output;
55 	LADSPA_Data *latency;
56 	biquad *     blf;
57 	int          count;
58 	LADSPA_Data *dry;
59 	gsm_signal * dst;
60 	float        fs;
61 	gsm          handle;
62 	int          resamp;
63 	float        rsf;
64 	gsm_signal * src;
65 	LADSPA_Data run_adding_gain;
66 } Gsm;
67 
68 _WINDOWS_DLL_EXPORT_
ladspa_descriptor(unsigned long index)69 const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) {
70 
71 #ifdef WIN32
72 	if (bIsFirstTime) {
73 		swh_init();
74 		bIsFirstTime = 0;
75 	}
76 #endif
77 	switch (index) {
78 	case 0:
79 		return gsmDescriptor;
80 	default:
81 		return NULL;
82 	}
83 }
84 
activateGsm(LADSPA_Handle instance)85 static void activateGsm(LADSPA_Handle instance) {
86 	Gsm *plugin_data = (Gsm *)instance;
87 	biquad *blf = plugin_data->blf;
88 	int count = plugin_data->count;
89 	LADSPA_Data *dry = plugin_data->dry;
90 	gsm_signal *dst = plugin_data->dst;
91 	float fs = plugin_data->fs;
92 	gsm handle = plugin_data->handle;
93 	int resamp = plugin_data->resamp;
94 	float rsf = plugin_data->rsf;
95 	gsm_signal *src = plugin_data->src;
96 #line 41 "gsm_1215.xml"
97 	count = 0;
98 	memset(src, 0, sizeof(gsm_signal) * 160);
99 	memset(dst, 0, sizeof(gsm_signal) * 163);
100 	memset(dry, 0, sizeof(LADSPA_Data) * 160 * resamp);
101 	handle = gsm_create();
102 	biquad_init(blf);
103 	hs_set_params(blf, 3500.0f, -50.0f, 0.7f, fs);
104 	plugin_data->blf = blf;
105 	plugin_data->count = count;
106 	plugin_data->dry = dry;
107 	plugin_data->dst = dst;
108 	plugin_data->fs = fs;
109 	plugin_data->handle = handle;
110 	plugin_data->resamp = resamp;
111 	plugin_data->rsf = rsf;
112 	plugin_data->src = src;
113 
114 }
115 
cleanupGsm(LADSPA_Handle instance)116 static void cleanupGsm(LADSPA_Handle instance) {
117 #line 51 "gsm_1215.xml"
118 	Gsm *plugin_data = (Gsm *)instance;
119 	free(plugin_data->src);
120 	free(plugin_data->dst);
121 	free(plugin_data->dry);
122 	free(plugin_data->blf);
123 	if (plugin_data->handle) {
124 	  gsm_destroy(plugin_data->handle);
125 	}
126 	free(instance);
127 }
128 
connectPortGsm(LADSPA_Handle instance,unsigned long port,LADSPA_Data * data)129 static void connectPortGsm(
130  LADSPA_Handle instance,
131  unsigned long port,
132  LADSPA_Data *data) {
133 	Gsm *plugin;
134 
135 	plugin = (Gsm *)instance;
136 	switch (port) {
137 	case GSM_DRYWET:
138 		plugin->drywet = data;
139 		break;
140 	case GSM_PASSES:
141 		plugin->passes = data;
142 		break;
143 	case GSM_ERROR:
144 		plugin->error = data;
145 		break;
146 	case GSM_INPUT:
147 		plugin->input = data;
148 		break;
149 	case GSM_OUTPUT:
150 		plugin->output = data;
151 		break;
152 	case GSM_LATENCY:
153 		plugin->latency = data;
154 		break;
155 	}
156 }
157 
instantiateGsm(const LADSPA_Descriptor * descriptor,unsigned long s_rate)158 static LADSPA_Handle instantiateGsm(
159  const LADSPA_Descriptor *descriptor,
160  unsigned long s_rate) {
161 	Gsm *plugin_data = (Gsm *)calloc(1, sizeof(Gsm));
162 	biquad *blf = NULL;
163 	int count;
164 	LADSPA_Data *dry = NULL;
165 	gsm_signal *dst = NULL;
166 	float fs;
167 	gsm handle;
168 	int resamp;
169 	float rsf;
170 	gsm_signal *src = NULL;
171 
172 #line 27 "gsm_1215.xml"
173 	count = 0;
174 	resamp = s_rate / 8000;
175 	fs = s_rate;
176 	rsf = SCALE / (float)resamp;
177 	src = malloc(sizeof(gsm_signal) * 160);
178 	dst = malloc(sizeof(gsm_signal) * 163);
179 	dry = malloc(sizeof(LADSPA_Data) * 160 * resamp);
180 	handle = NULL;
181 
182 	blf = malloc(sizeof(biquad));
183 	biquad_init(blf);
184 
185 	plugin_data->blf = blf;
186 	plugin_data->count = count;
187 	plugin_data->dry = dry;
188 	plugin_data->dst = dst;
189 	plugin_data->fs = fs;
190 	plugin_data->handle = handle;
191 	plugin_data->resamp = resamp;
192 	plugin_data->rsf = rsf;
193 	plugin_data->src = src;
194 
195 	return (LADSPA_Handle)plugin_data;
196 }
197 
198 #undef buffer_write
199 #undef RUN_ADDING
200 #undef RUN_REPLACING
201 
202 #define buffer_write(b, v) (b = v)
203 #define RUN_ADDING    0
204 #define RUN_REPLACING 1
205 
runGsm(LADSPA_Handle instance,unsigned long sample_count)206 static void runGsm(LADSPA_Handle instance, unsigned long sample_count) {
207 	Gsm *plugin_data = (Gsm *)instance;
208 
209 	/* Dry/wet mix (float value) */
210 	const LADSPA_Data drywet = *(plugin_data->drywet);
211 
212 	/* Number of passes (float value) */
213 	const LADSPA_Data passes = *(plugin_data->passes);
214 
215 	/* Error rate (bits/block) (float value) */
216 	const LADSPA_Data error = *(plugin_data->error);
217 
218 	/* Input (array of floats of length sample_count) */
219 	const LADSPA_Data * const input = plugin_data->input;
220 
221 	/* Output (array of floats of length sample_count) */
222 	LADSPA_Data * const output = plugin_data->output;
223 	biquad * blf = plugin_data->blf;
224 	int count = plugin_data->count;
225 	LADSPA_Data * dry = plugin_data->dry;
226 	gsm_signal * dst = plugin_data->dst;
227 	float fs = plugin_data->fs;
228 	gsm handle = plugin_data->handle;
229 	int resamp = plugin_data->resamp;
230 	float rsf = plugin_data->rsf;
231 	gsm_signal * src = plugin_data->src;
232 
233 #line 61 "gsm_1215.xml"
234 	unsigned long pos;
235 	gsm_frame frame;
236 	int samp;
237 	float part;
238 	int error_rate = f_round(error);
239 	int num_passes = f_round(passes);
240 
241 	fs = fs; // So gcc doesn't think it's unused
242 
243 	for (pos = 0; pos < sample_count; pos++) {
244 
245 	  // oversample into buffer down to aprox 8kHz, 13bit
246 	  src[count / resamp] += f_round(biquad_run(blf, input[pos]) * rsf);
247 
248 	  // interpolate output, so it doesn't sound totaly awful
249 	  samp = count / resamp;
250 	  part = (float)count / (float)resamp - (float)samp;
251 	  buffer_write(output[pos], cube_interp(part, dst[samp], dst[samp+1], dst[samp+2], dst[samp+3]) * SCALE_R * drywet + dry[count] * (1.0f - drywet));
252 
253 	  // Maintain delayed, dry buffer.
254 	  dry[count] = input[pos];
255 
256 	  count++;
257 
258 	  // If we have a full, downsampled buffer then run the encode +
259 	  // decode process.
260 	  if (count >= 160 * resamp) {
261 	          int i, j;
262 	          gsm_signal *in;
263 
264 	          count = 0;
265 	          dst[0] = dst[160];
266 	          dst[1] = dst[161];
267 	          dst[2] = dst[162];
268 
269 	          in = src;
270 	          for (j=0; j<num_passes; j++) {
271 	                  gsm_encode(handle, in, frame);
272 	                  for (i=0; i < error_rate; i++) {
273 	                          frame[1 + (rand() % 32)] ^= bits[rand() % 8];
274 	                  }
275 	                  gsm_decode(handle, frame, dst+3);
276 	                  in = dst+3;
277 	          }
278 	          if (num_passes == 0) {
279 	                  for (j=0; j < 160; j++) {
280 	                          dst[j + 3] = src[j];
281 	                  }
282 	          }
283 	          memset(src, 0, sizeof(gsm_signal) * 160);
284 	  }
285 	}
286 
287 	plugin_data->count = count;
288 
289 	*(plugin_data->latency) = 160 * resamp;
290 }
291 #undef buffer_write
292 #undef RUN_ADDING
293 #undef RUN_REPLACING
294 
295 #define buffer_write(b, v) (b += (v) * run_adding_gain)
296 #define RUN_ADDING    1
297 #define RUN_REPLACING 0
298 
setRunAddingGainGsm(LADSPA_Handle instance,LADSPA_Data gain)299 static void setRunAddingGainGsm(LADSPA_Handle instance, LADSPA_Data gain) {
300 	((Gsm *)instance)->run_adding_gain = gain;
301 }
302 
runAddingGsm(LADSPA_Handle instance,unsigned long sample_count)303 static void runAddingGsm(LADSPA_Handle instance, unsigned long sample_count) {
304 	Gsm *plugin_data = (Gsm *)instance;
305 	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;
306 
307 	/* Dry/wet mix (float value) */
308 	const LADSPA_Data drywet = *(plugin_data->drywet);
309 
310 	/* Number of passes (float value) */
311 	const LADSPA_Data passes = *(plugin_data->passes);
312 
313 	/* Error rate (bits/block) (float value) */
314 	const LADSPA_Data error = *(plugin_data->error);
315 
316 	/* Input (array of floats of length sample_count) */
317 	const LADSPA_Data * const input = plugin_data->input;
318 
319 	/* Output (array of floats of length sample_count) */
320 	LADSPA_Data * const output = plugin_data->output;
321 	biquad * blf = plugin_data->blf;
322 	int count = plugin_data->count;
323 	LADSPA_Data * dry = plugin_data->dry;
324 	gsm_signal * dst = plugin_data->dst;
325 	float fs = plugin_data->fs;
326 	gsm handle = plugin_data->handle;
327 	int resamp = plugin_data->resamp;
328 	float rsf = plugin_data->rsf;
329 	gsm_signal * src = plugin_data->src;
330 
331 #line 61 "gsm_1215.xml"
332 	unsigned long pos;
333 	gsm_frame frame;
334 	int samp;
335 	float part;
336 	int error_rate = f_round(error);
337 	int num_passes = f_round(passes);
338 
339 	fs = fs; // So gcc doesn't think it's unused
340 
341 	for (pos = 0; pos < sample_count; pos++) {
342 
343 	  // oversample into buffer down to aprox 8kHz, 13bit
344 	  src[count / resamp] += f_round(biquad_run(blf, input[pos]) * rsf);
345 
346 	  // interpolate output, so it doesn't sound totaly awful
347 	  samp = count / resamp;
348 	  part = (float)count / (float)resamp - (float)samp;
349 	  buffer_write(output[pos], cube_interp(part, dst[samp], dst[samp+1], dst[samp+2], dst[samp+3]) * SCALE_R * drywet + dry[count] * (1.0f - drywet));
350 
351 	  // Maintain delayed, dry buffer.
352 	  dry[count] = input[pos];
353 
354 	  count++;
355 
356 	  // If we have a full, downsampled buffer then run the encode +
357 	  // decode process.
358 	  if (count >= 160 * resamp) {
359 	          int i, j;
360 	          gsm_signal *in;
361 
362 	          count = 0;
363 	          dst[0] = dst[160];
364 	          dst[1] = dst[161];
365 	          dst[2] = dst[162];
366 
367 	          in = src;
368 	          for (j=0; j<num_passes; j++) {
369 	                  gsm_encode(handle, in, frame);
370 	                  for (i=0; i < error_rate; i++) {
371 	                          frame[1 + (rand() % 32)] ^= bits[rand() % 8];
372 	                  }
373 	                  gsm_decode(handle, frame, dst+3);
374 	                  in = dst+3;
375 	          }
376 	          if (num_passes == 0) {
377 	                  for (j=0; j < 160; j++) {
378 	                          dst[j + 3] = src[j];
379 	                  }
380 	          }
381 	          memset(src, 0, sizeof(gsm_signal) * 160);
382 	  }
383 	}
384 
385 	plugin_data->count = count;
386 
387 	*(plugin_data->latency) = 160 * resamp;
388 }
389 
swh_init()390 static void __attribute__((constructor)) swh_init() {
391 	char **port_names;
392 	LADSPA_PortDescriptor *port_descriptors;
393 	LADSPA_PortRangeHint *port_range_hints;
394 
395 #ifdef ENABLE_NLS
396 #define D_(s) dgettext(PACKAGE, s)
397 	bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR);
398 #else
399 #define D_(s) (s)
400 #endif
401 
402 
403 	gsmDescriptor =
404 	 (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
405 
406 	if (gsmDescriptor) {
407 		gsmDescriptor->UniqueID = 1215;
408 		gsmDescriptor->Label = "gsm";
409 		gsmDescriptor->Properties =
410 		 0;
411 		gsmDescriptor->Name =
412 		 D_("GSM simulator");
413 		gsmDescriptor->Maker =
414 		 "Steve Harris <steve@plugin.org.uk>";
415 		gsmDescriptor->Copyright =
416 		 "GPL";
417 		gsmDescriptor->PortCount = 6;
418 
419 		port_descriptors = (LADSPA_PortDescriptor *)calloc(6,
420 		 sizeof(LADSPA_PortDescriptor));
421 		gsmDescriptor->PortDescriptors =
422 		 (const LADSPA_PortDescriptor *)port_descriptors;
423 
424 		port_range_hints = (LADSPA_PortRangeHint *)calloc(6,
425 		 sizeof(LADSPA_PortRangeHint));
426 		gsmDescriptor->PortRangeHints =
427 		 (const LADSPA_PortRangeHint *)port_range_hints;
428 
429 		port_names = (char **)calloc(6, sizeof(char*));
430 		gsmDescriptor->PortNames =
431 		 (const char **)port_names;
432 
433 		/* Parameters for Dry/wet mix */
434 		port_descriptors[GSM_DRYWET] =
435 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
436 		port_names[GSM_DRYWET] =
437 		 D_("Dry/wet mix");
438 		port_range_hints[GSM_DRYWET].HintDescriptor =
439 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_1;
440 		port_range_hints[GSM_DRYWET].LowerBound = 0;
441 		port_range_hints[GSM_DRYWET].UpperBound = 1;
442 
443 		/* Parameters for Number of passes */
444 		port_descriptors[GSM_PASSES] =
445 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
446 		port_names[GSM_PASSES] =
447 		 D_("Number of passes");
448 		port_range_hints[GSM_PASSES].HintDescriptor =
449 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_INTEGER | LADSPA_HINT_DEFAULT_1;
450 		port_range_hints[GSM_PASSES].LowerBound = 0;
451 		port_range_hints[GSM_PASSES].UpperBound = 10;
452 
453 		/* Parameters for Error rate (bits/block) */
454 		port_descriptors[GSM_ERROR] =
455 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
456 		port_names[GSM_ERROR] =
457 		 D_("Error rate (bits/block)");
458 		port_range_hints[GSM_ERROR].HintDescriptor =
459 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
460 		port_range_hints[GSM_ERROR].LowerBound = 0;
461 		port_range_hints[GSM_ERROR].UpperBound = 30;
462 
463 		/* Parameters for Input */
464 		port_descriptors[GSM_INPUT] =
465 		 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
466 		port_names[GSM_INPUT] =
467 		 D_("Input");
468 		port_range_hints[GSM_INPUT].HintDescriptor = 0;
469 
470 		/* Parameters for Output */
471 		port_descriptors[GSM_OUTPUT] =
472 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
473 		port_names[GSM_OUTPUT] =
474 		 D_("Output");
475 		port_range_hints[GSM_OUTPUT].HintDescriptor = 0;
476 
477 		/* Parameters for latency */
478 		port_descriptors[GSM_LATENCY] =
479 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
480 		port_names[GSM_LATENCY] =
481 		 D_("latency");
482 		port_range_hints[GSM_LATENCY].HintDescriptor = 0;
483 
484 		gsmDescriptor->activate = activateGsm;
485 		gsmDescriptor->cleanup = cleanupGsm;
486 		gsmDescriptor->connect_port = connectPortGsm;
487 		gsmDescriptor->deactivate = NULL;
488 		gsmDescriptor->instantiate = instantiateGsm;
489 		gsmDescriptor->run = runGsm;
490 		gsmDescriptor->run_adding = runAddingGsm;
491 		gsmDescriptor->set_run_adding_gain = setRunAddingGainGsm;
492 	}
493 }
494 
swh_fini()495 static void __attribute__((destructor)) swh_fini() {
496 	if (gsmDescriptor) {
497 		free((LADSPA_PortDescriptor *)gsmDescriptor->PortDescriptors);
498 		free((char **)gsmDescriptor->PortNames);
499 		free((LADSPA_PortRangeHint *)gsmDescriptor->PortRangeHints);
500 		free(gsmDescriptor);
501 	}
502 	gsmDescriptor = NULL;
503 
504 }
505