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