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