1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include <stdlib.h>
7 #include "cras_dsp_module.h"
8 #include "drc.h"
9 #include "dsp_util.h"
10 #include "dcblock.h"
11 #include "eq.h"
12 #include "eq2.h"
13
14 /*
15 * empty module functions (for source and sink)
16 */
empty_instantiate(struct dsp_module * module,unsigned long sample_rate)17 static int empty_instantiate(struct dsp_module *module,
18 unsigned long sample_rate)
19 {
20 return 0;
21 }
22
empty_connect_port(struct dsp_module * module,unsigned long port,float * data_location)23 static void empty_connect_port(struct dsp_module *module, unsigned long port,
24 float *data_location)
25 {
26 }
27
empty_get_delay(struct dsp_module * module)28 static int empty_get_delay(struct dsp_module *module)
29 {
30 return 0;
31 }
32
empty_run(struct dsp_module * module,unsigned long sample_count)33 static void empty_run(struct dsp_module *module, unsigned long sample_count)
34 {
35 }
36
empty_deinstantiate(struct dsp_module * module)37 static void empty_deinstantiate(struct dsp_module *module)
38 {
39 }
40
empty_free_module(struct dsp_module * module)41 static void empty_free_module(struct dsp_module *module)
42 {
43 free(module);
44 }
45
empty_get_properties(struct dsp_module * module)46 static int empty_get_properties(struct dsp_module *module)
47 {
48 return 0;
49 }
50
empty_dump(struct dsp_module * module,struct dumper * d)51 static void empty_dump(struct dsp_module *module, struct dumper *d)
52 {
53 dumpf(d, "built-in module\n");
54 }
55
empty_init_module(struct dsp_module * module)56 static void empty_init_module(struct dsp_module *module)
57 {
58 module->instantiate = &empty_instantiate;
59 module->connect_port = &empty_connect_port;
60 module->get_delay = &empty_get_delay;
61 module->run = &empty_run;
62 module->deinstantiate = &empty_deinstantiate;
63 module->free_module = &empty_free_module;
64 module->get_properties = &empty_get_properties;
65 module->dump = &empty_dump;
66 }
67
68 /*
69 * swap_lr module functions
70 */
swap_lr_instantiate(struct dsp_module * module,unsigned long sample_rate)71 static int swap_lr_instantiate(struct dsp_module *module,
72 unsigned long sample_rate)
73 {
74 module->data = calloc(4, sizeof(float *));
75 return 0;
76 }
77
swap_lr_connect_port(struct dsp_module * module,unsigned long port,float * data_location)78 static void swap_lr_connect_port(struct dsp_module *module, unsigned long port,
79 float *data_location)
80 {
81 float **ports;
82 ports = (float **)module->data;
83 ports[port] = data_location;
84 }
85
swap_lr_run(struct dsp_module * module,unsigned long sample_count)86 static void swap_lr_run(struct dsp_module *module, unsigned long sample_count)
87 {
88 size_t i;
89 float **ports = (float **)module->data;
90
91 /* This module runs dsp in-place, so ports[0] == ports[2],
92 * ports[1] == ports[3]. Here we swap data on two channels.
93 */
94 for (i = 0; i < sample_count; i++) {
95 float temp = ports[0][i];
96 ports[2][i] = ports[1][i];
97 ports[3][i] = temp;
98 }
99 }
100
swap_lr_deinstantiate(struct dsp_module * module)101 static void swap_lr_deinstantiate(struct dsp_module *module)
102 {
103 free(module->data);
104 }
105
swap_lr_init_module(struct dsp_module * module)106 static void swap_lr_init_module(struct dsp_module *module)
107 {
108 module->instantiate = &swap_lr_instantiate;
109 module->connect_port = &swap_lr_connect_port;
110 module->get_delay = &empty_get_delay;
111 module->run = &swap_lr_run;
112 module->deinstantiate = &swap_lr_deinstantiate;
113 module->free_module = &empty_free_module;
114 module->get_properties = &empty_get_properties;
115 }
116
117 /*
118 * invert_lr module functions
119 */
invert_lr_instantiate(struct dsp_module * module,unsigned long sample_rate)120 static int invert_lr_instantiate(struct dsp_module *module,
121 unsigned long sample_rate)
122 {
123 module->data = calloc(4, sizeof(float *));
124 return 0;
125 }
126
invert_lr_connect_port(struct dsp_module * module,unsigned long port,float * data_location)127 static void invert_lr_connect_port(struct dsp_module *module,
128 unsigned long port, float *data_location)
129 {
130 float **ports;
131 ports = (float **)module->data;
132 ports[port] = data_location;
133 }
134
invert_lr_run(struct dsp_module * module,unsigned long sample_count)135 static void invert_lr_run(struct dsp_module *module, unsigned long sample_count)
136 {
137 size_t i;
138 float **ports = (float **)module->data;
139
140 for (i = 0; i < sample_count; i++) {
141 ports[2][i] = -ports[0][i];
142 ports[3][i] = ports[1][i];
143 }
144 }
145
invert_lr_deinstantiate(struct dsp_module * module)146 static void invert_lr_deinstantiate(struct dsp_module *module)
147 {
148 free(module->data);
149 }
150
invert_lr_init_module(struct dsp_module * module)151 static void invert_lr_init_module(struct dsp_module *module)
152 {
153 module->instantiate = &invert_lr_instantiate;
154 module->connect_port = &invert_lr_connect_port;
155 module->get_delay = &empty_get_delay;
156 module->run = &invert_lr_run;
157 module->deinstantiate = &invert_lr_deinstantiate;
158 module->free_module = &empty_free_module;
159 module->get_properties = &empty_get_properties;
160 }
161
162 /*
163 * mix_stereo module functions
164 */
mix_stereo_instantiate(struct dsp_module * module,unsigned long sample_rate)165 static int mix_stereo_instantiate(struct dsp_module *module,
166 unsigned long sample_rate)
167 {
168 module->data = calloc(4, sizeof(float *));
169 return 0;
170 }
171
mix_stereo_connect_port(struct dsp_module * module,unsigned long port,float * data_location)172 static void mix_stereo_connect_port(struct dsp_module *module,
173 unsigned long port, float *data_location)
174 {
175 float **ports;
176 ports = (float **)module->data;
177 ports[port] = data_location;
178 }
179
mix_stereo_run(struct dsp_module * module,unsigned long sample_count)180 static void mix_stereo_run(struct dsp_module *module,
181 unsigned long sample_count)
182 {
183 size_t i;
184 float tmp;
185 float **ports = (float **)module->data;
186
187 for (i = 0; i < sample_count; i++) {
188 tmp = ports[0][i] + ports[1][i];
189 ports[2][i] = tmp;
190 ports[3][i] = tmp;
191 }
192 }
193
mix_stereo_deinstantiate(struct dsp_module * module)194 static void mix_stereo_deinstantiate(struct dsp_module *module)
195 {
196 free(module->data);
197 }
198
mix_stereo_init_module(struct dsp_module * module)199 static void mix_stereo_init_module(struct dsp_module *module)
200 {
201 module->instantiate = &mix_stereo_instantiate;
202 module->connect_port = &mix_stereo_connect_port;
203 module->get_delay = &empty_get_delay;
204 module->run = &mix_stereo_run;
205 module->deinstantiate = &mix_stereo_deinstantiate;
206 module->free_module = &empty_free_module;
207 module->get_properties = &empty_get_properties;
208 module->dump = &empty_dump;
209 }
210
211 /*
212 * dcblock module functions
213 */
214 struct dcblock_data {
215 struct dcblock *dcblockl;
216 struct dcblock *dcblockr;
217 unsigned long sample_rate;
218
219 /* One port for input, one for output, and 1 parameter */
220 float *ports[5];
221 };
222
dcblock_instantiate(struct dsp_module * module,unsigned long sample_rate)223 static int dcblock_instantiate(struct dsp_module *module,
224 unsigned long sample_rate)
225 {
226 struct dcblock_data *data;
227
228 module->data = calloc(1, sizeof(struct dcblock_data));
229 data = (struct dcblock_data *)module->data;
230 data->sample_rate = sample_rate;
231
232 return 0;
233 }
234
dcblock_connect_port(struct dsp_module * module,unsigned long port,float * data_location)235 static void dcblock_connect_port(struct dsp_module *module, unsigned long port,
236 float *data_location)
237 {
238 struct dcblock_data *data = (struct dcblock_data *)module->data;
239 data->ports[port] = data_location;
240 }
241
dcblock_run(struct dsp_module * module,unsigned long sample_count)242 static void dcblock_run(struct dsp_module *module, unsigned long sample_count)
243 {
244 struct dcblock_data *data = (struct dcblock_data *)module->data;
245 if (!data->dcblockl)
246 data->dcblockl =
247 dcblock_new(*data->ports[4], data->sample_rate);
248 if (!data->dcblockr)
249 data->dcblockr =
250 dcblock_new(*data->ports[4], data->sample_rate);
251 if (data->ports[0] != data->ports[2])
252 memcpy(data->ports[2], data->ports[0],
253 sizeof(float) * sample_count);
254 if (data->ports[1] != data->ports[3])
255 memcpy(data->ports[3], data->ports[1],
256 sizeof(float) * sample_count);
257
258 dcblock_process(data->dcblockl, data->ports[2], (int)sample_count);
259 dcblock_process(data->dcblockr, data->ports[3], (int)sample_count);
260 }
261
dcblock_deinstantiate(struct dsp_module * module)262 static void dcblock_deinstantiate(struct dsp_module *module)
263 {
264 struct dcblock_data *data = (struct dcblock_data *)module->data;
265 if (data->dcblockl)
266 dcblock_free(data->dcblockl);
267 if (data->dcblockr)
268 dcblock_free(data->dcblockr);
269 free(data);
270 }
271
dcblock_init_module(struct dsp_module * module)272 static void dcblock_init_module(struct dsp_module *module)
273 {
274 module->instantiate = &dcblock_instantiate;
275 module->connect_port = &dcblock_connect_port;
276 module->get_delay = &empty_get_delay;
277 module->run = &dcblock_run;
278 module->deinstantiate = &dcblock_deinstantiate;
279 module->free_module = &empty_free_module;
280 module->get_properties = &empty_get_properties;
281 module->dump = &empty_dump;
282 }
283
284 /*
285 * eq module functions
286 */
287 struct eq_data {
288 int sample_rate;
289 struct eq *eq; /* Initialized in the first call of eq_run() */
290
291 /* One port for input, one for output, and 4 parameters per eq */
292 float *ports[2 + MAX_BIQUADS_PER_EQ * 4];
293 };
294
eq_instantiate(struct dsp_module * module,unsigned long sample_rate)295 static int eq_instantiate(struct dsp_module *module, unsigned long sample_rate)
296 {
297 struct eq_data *data;
298
299 module->data = calloc(1, sizeof(struct eq_data));
300 data = (struct eq_data *)module->data;
301 data->sample_rate = (int)sample_rate;
302 return 0;
303 }
304
eq_connect_port(struct dsp_module * module,unsigned long port,float * data_location)305 static void eq_connect_port(struct dsp_module *module, unsigned long port,
306 float *data_location)
307 {
308 struct eq_data *data = (struct eq_data *)module->data;
309 data->ports[port] = data_location;
310 }
311
eq_run(struct dsp_module * module,unsigned long sample_count)312 static void eq_run(struct dsp_module *module, unsigned long sample_count)
313 {
314 struct eq_data *data = (struct eq_data *)module->data;
315 if (!data->eq) {
316 float nyquist = data->sample_rate / 2;
317 int i;
318
319 data->eq = eq_new();
320 for (i = 2; i < 2 + MAX_BIQUADS_PER_EQ * 4; i += 4) {
321 if (!data->ports[i])
322 break;
323 int type = (int)*data->ports[i];
324 float freq = *data->ports[i + 1];
325 float Q = *data->ports[i + 2];
326 float gain = *data->ports[i + 3];
327 eq_append_biquad(data->eq, type, freq / nyquist, Q,
328 gain);
329 }
330 }
331 if (data->ports[0] != data->ports[1])
332 memcpy(data->ports[1], data->ports[0],
333 sizeof(float) * sample_count);
334 eq_process(data->eq, data->ports[1], (int)sample_count);
335 }
336
eq_deinstantiate(struct dsp_module * module)337 static void eq_deinstantiate(struct dsp_module *module)
338 {
339 struct eq_data *data = (struct eq_data *)module->data;
340 if (data->eq)
341 eq_free(data->eq);
342 free(data);
343 }
344
eq_init_module(struct dsp_module * module)345 static void eq_init_module(struct dsp_module *module)
346 {
347 module->instantiate = &eq_instantiate;
348 module->connect_port = &eq_connect_port;
349 module->get_delay = &empty_get_delay;
350 module->run = &eq_run;
351 module->deinstantiate = &eq_deinstantiate;
352 module->free_module = &empty_free_module;
353 module->get_properties = &empty_get_properties;
354 module->dump = &empty_dump;
355 }
356
357 /*
358 * eq2 module functions
359 */
360 struct eq2_data {
361 int sample_rate;
362 struct eq2 *eq2; /* Initialized in the first call of eq2_run() */
363
364 /* Two ports for input, two for output, and 8 parameters per eq pair */
365 float *ports[4 + MAX_BIQUADS_PER_EQ2 * 8];
366 };
367
eq2_instantiate(struct dsp_module * module,unsigned long sample_rate)368 static int eq2_instantiate(struct dsp_module *module, unsigned long sample_rate)
369 {
370 struct eq2_data *data;
371
372 module->data = calloc(1, sizeof(struct eq2_data));
373 data = (struct eq2_data *)module->data;
374 data->sample_rate = (int)sample_rate;
375 return 0;
376 }
377
eq2_connect_port(struct dsp_module * module,unsigned long port,float * data_location)378 static void eq2_connect_port(struct dsp_module *module, unsigned long port,
379 float *data_location)
380 {
381 struct eq2_data *data = (struct eq2_data *)module->data;
382 data->ports[port] = data_location;
383 }
384
eq2_run(struct dsp_module * module,unsigned long sample_count)385 static void eq2_run(struct dsp_module *module, unsigned long sample_count)
386 {
387 struct eq2_data *data = (struct eq2_data *)module->data;
388 if (!data->eq2) {
389 float nyquist = data->sample_rate / 2;
390 int i, channel;
391
392 data->eq2 = eq2_new();
393 for (i = 4; i < 4 + MAX_BIQUADS_PER_EQ2 * 8; i += 8) {
394 if (!data->ports[i])
395 break;
396 for (channel = 0; channel < 2; channel++) {
397 int k = i + channel * 4;
398 int type = (int)*data->ports[k];
399 float freq = *data->ports[k + 1];
400 float Q = *data->ports[k + 2];
401 float gain = *data->ports[k + 3];
402 eq2_append_biquad(data->eq2, channel, type,
403 freq / nyquist, Q, gain);
404 }
405 }
406 }
407
408 if (data->ports[0] != data->ports[2])
409 memcpy(data->ports[2], data->ports[0],
410 sizeof(float) * sample_count);
411 if (data->ports[3] != data->ports[1])
412 memcpy(data->ports[3], data->ports[1],
413 sizeof(float) * sample_count);
414
415 eq2_process(data->eq2, data->ports[2], data->ports[3],
416 (int)sample_count);
417 }
418
eq2_deinstantiate(struct dsp_module * module)419 static void eq2_deinstantiate(struct dsp_module *module)
420 {
421 struct eq2_data *data = (struct eq2_data *)module->data;
422 if (data->eq2)
423 eq2_free(data->eq2);
424 free(data);
425 }
426
eq2_init_module(struct dsp_module * module)427 static void eq2_init_module(struct dsp_module *module)
428 {
429 module->instantiate = &eq2_instantiate;
430 module->connect_port = &eq2_connect_port;
431 module->get_delay = &empty_get_delay;
432 module->run = &eq2_run;
433 module->deinstantiate = &eq2_deinstantiate;
434 module->free_module = &empty_free_module;
435 module->get_properties = &empty_get_properties;
436 module->dump = &empty_dump;
437 }
438
439 /*
440 * drc module functions
441 */
442 struct drc_data {
443 int sample_rate;
444 struct drc *drc; /* Initialized in the first call of drc_run() */
445
446 /* Two ports for input, two for output, one for disable_emphasis,
447 * and 8 parameters each band */
448 float *ports[4 + 1 + 8 * 3];
449 };
450
drc_instantiate(struct dsp_module * module,unsigned long sample_rate)451 static int drc_instantiate(struct dsp_module *module, unsigned long sample_rate)
452 {
453 struct drc_data *data;
454
455 module->data = calloc(1, sizeof(struct drc_data));
456 data = (struct drc_data *)module->data;
457 data->sample_rate = (int)sample_rate;
458 return 0;
459 }
460
drc_connect_port(struct dsp_module * module,unsigned long port,float * data_location)461 static void drc_connect_port(struct dsp_module *module, unsigned long port,
462 float *data_location)
463 {
464 struct drc_data *data = (struct drc_data *)module->data;
465 data->ports[port] = data_location;
466 }
467
drc_get_delay(struct dsp_module * module)468 static int drc_get_delay(struct dsp_module *module)
469 {
470 struct drc_data *data = (struct drc_data *)module->data;
471 return DRC_DEFAULT_PRE_DELAY * data->sample_rate;
472 }
473
drc_run(struct dsp_module * module,unsigned long sample_count)474 static void drc_run(struct dsp_module *module, unsigned long sample_count)
475 {
476 struct drc_data *data = (struct drc_data *)module->data;
477 if (!data->drc) {
478 int i;
479 float nyquist = data->sample_rate / 2;
480 struct drc *drc = drc_new(data->sample_rate);
481
482 data->drc = drc;
483 drc->emphasis_disabled = (int)*data->ports[4];
484 for (i = 0; i < 3; i++) {
485 int k = 5 + i * 8;
486 float f = *data->ports[k];
487 float enable = *data->ports[k + 1];
488 float threshold = *data->ports[k + 2];
489 float knee = *data->ports[k + 3];
490 float ratio = *data->ports[k + 4];
491 float attack = *data->ports[k + 5];
492 float release = *data->ports[k + 6];
493 float boost = *data->ports[k + 7];
494 drc_set_param(drc, i, PARAM_CROSSOVER_LOWER_FREQ,
495 f / nyquist);
496 drc_set_param(drc, i, PARAM_ENABLED, enable);
497 drc_set_param(drc, i, PARAM_THRESHOLD, threshold);
498 drc_set_param(drc, i, PARAM_KNEE, knee);
499 drc_set_param(drc, i, PARAM_RATIO, ratio);
500 drc_set_param(drc, i, PARAM_ATTACK, attack);
501 drc_set_param(drc, i, PARAM_RELEASE, release);
502 drc_set_param(drc, i, PARAM_POST_GAIN, boost);
503 }
504 drc_init(drc);
505 }
506 if (data->ports[0] != data->ports[2])
507 memcpy(data->ports[2], data->ports[0],
508 sizeof(float) * sample_count);
509 if (data->ports[1] != data->ports[3])
510 memcpy(data->ports[3], data->ports[1],
511 sizeof(float) * sample_count);
512
513 drc_process(data->drc, &data->ports[2], (int)sample_count);
514 }
515
drc_deinstantiate(struct dsp_module * module)516 static void drc_deinstantiate(struct dsp_module *module)
517 {
518 struct drc_data *data = (struct drc_data *)module->data;
519 if (data->drc)
520 drc_free(data->drc);
521 free(data);
522 }
523
drc_init_module(struct dsp_module * module)524 static void drc_init_module(struct dsp_module *module)
525 {
526 module->instantiate = &drc_instantiate;
527 module->connect_port = &drc_connect_port;
528 module->get_delay = &drc_get_delay;
529 module->run = &drc_run;
530 module->deinstantiate = &drc_deinstantiate;
531 module->free_module = &empty_free_module;
532 module->get_properties = &empty_get_properties;
533 module->dump = &empty_dump;
534 }
535
536 /*
537 * sink module functions
538 */
539 struct sink_data {
540 struct ext_dsp_module *ext_module;
541 float *ports[MAX_EXT_DSP_PORTS];
542 };
543
sink_instantiate(struct dsp_module * module,unsigned long sample_rate)544 static int sink_instantiate(struct dsp_module *module,
545 unsigned long sample_rate)
546 {
547 module->data = (struct sink_data *)calloc(1, sizeof(struct sink_data));
548 return 0;
549 }
550
sink_deinstantiate(struct dsp_module * module)551 static void sink_deinstantiate(struct dsp_module *module)
552 {
553 struct sink_data *data = (struct sink_data *)module->data;
554 free(data);
555 }
556
sink_connect_port(struct dsp_module * module,unsigned long port,float * data_location)557 static void sink_connect_port(struct dsp_module *module, unsigned long port,
558 float *data_location)
559 {
560 struct sink_data *data = (struct sink_data *)module->data;
561 data->ports[port] = data_location;
562 }
563
sink_run(struct dsp_module * module,unsigned long sample_count)564 static void sink_run(struct dsp_module *module, unsigned long sample_count)
565 {
566 struct sink_data *data = (struct sink_data *)module->data;
567
568 if (!data->ext_module)
569 return;
570 data->ext_module->run(data->ext_module, sample_count);
571 }
572
sink_init_module(struct dsp_module * module)573 static void sink_init_module(struct dsp_module *module)
574 {
575 module->instantiate = &sink_instantiate;
576 module->connect_port = &sink_connect_port;
577 module->get_delay = &empty_get_delay;
578 module->run = &sink_run;
579 module->deinstantiate = &sink_deinstantiate;
580 module->free_module = &empty_free_module;
581 module->get_properties = &empty_get_properties;
582 module->dump = &empty_dump;
583 }
584
cras_dsp_module_set_sink_ext_module(struct dsp_module * module,struct ext_dsp_module * ext_module)585 void cras_dsp_module_set_sink_ext_module(struct dsp_module *module,
586 struct ext_dsp_module *ext_module)
587 {
588 struct sink_data *data = (struct sink_data *)module->data;
589 int i;
590 data->ext_module = ext_module;
591
592 if (data->ext_module == NULL)
593 return;
594
595 for (i = 0; i < MAX_EXT_DSP_PORTS; i++)
596 ext_module->ports[i] = data->ports[i];
597 }
598
599 /*
600 * builtin module dispatcher
601 */
cras_dsp_module_load_builtin(struct plugin * plugin)602 struct dsp_module *cras_dsp_module_load_builtin(struct plugin *plugin)
603 {
604 struct dsp_module *module;
605 if (strcmp(plugin->library, "builtin") != 0)
606 return NULL;
607
608 module = calloc(1, sizeof(struct dsp_module));
609
610 if (strcmp(plugin->label, "mix_stereo") == 0) {
611 mix_stereo_init_module(module);
612 } else if (strcmp(plugin->label, "invert_lr") == 0) {
613 invert_lr_init_module(module);
614 } else if (strcmp(plugin->label, "dcblock") == 0) {
615 dcblock_init_module(module);
616 } else if (strcmp(plugin->label, "eq") == 0) {
617 eq_init_module(module);
618 } else if (strcmp(plugin->label, "eq2") == 0) {
619 eq2_init_module(module);
620 } else if (strcmp(plugin->label, "drc") == 0) {
621 drc_init_module(module);
622 } else if (strcmp(plugin->label, "swap_lr") == 0) {
623 swap_lr_init_module(module);
624 } else if (strcmp(plugin->label, "sink") == 0) {
625 sink_init_module(module);
626 } else {
627 empty_init_module(module);
628 }
629
630 return module;
631 }
632