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 "eq.h"
11 #include "eq2.h"
12 
13 /*
14  *  empty module functions (for source and sink)
15  */
empty_instantiate(struct dsp_module * module,unsigned long sample_rate)16 static int empty_instantiate(struct dsp_module *module,
17 			     unsigned long sample_rate)
18 {
19 	return 0;
20 }
21 
empty_connect_port(struct dsp_module * module,unsigned long port,float * data_location)22 static void empty_connect_port(struct dsp_module *module, unsigned long port,
23 			       float *data_location) {}
24 
empty_get_delay(struct dsp_module * module)25 static int empty_get_delay(struct dsp_module *module)
26 {
27 	return 0;
28 }
29 
empty_run(struct dsp_module * module,unsigned long sample_count)30 static void empty_run(struct dsp_module *module, unsigned long sample_count) {}
31 
empty_deinstantiate(struct dsp_module * module)32 static void empty_deinstantiate(struct dsp_module *module) {}
33 
empty_free_module(struct dsp_module * module)34 static void empty_free_module(struct dsp_module *module)
35 {
36 	free(module);
37 }
38 
empty_get_properties(struct dsp_module * module)39 static int empty_get_properties(struct dsp_module *module) { return 0; }
40 
empty_init_module(struct dsp_module * module)41 static void empty_init_module(struct dsp_module *module)
42 {
43 	module->instantiate = &empty_instantiate;
44 	module->connect_port = &empty_connect_port;
45 	module->get_delay = &empty_get_delay;
46 	module->run = &empty_run;
47 	module->deinstantiate = &empty_deinstantiate;
48 	module->free_module = &empty_free_module;
49 	module->get_properties = &empty_get_properties;
50 }
51 
52 /*
53  *  invert_lr module functions
54  */
invert_lr_instantiate(struct dsp_module * module,unsigned long sample_rate)55 static int invert_lr_instantiate(struct dsp_module *module,
56 				 unsigned long sample_rate)
57 {
58 	module->data = calloc(4, sizeof(float*));
59 	return 0;
60 }
61 
invert_lr_connect_port(struct dsp_module * module,unsigned long port,float * data_location)62 static void invert_lr_connect_port(struct dsp_module *module,
63 				   unsigned long port, float *data_location)
64 {
65 	float **ports;
66 	ports = (float **)module->data;
67 	ports[port] = data_location;
68 }
69 
invert_lr_run(struct dsp_module * module,unsigned long sample_count)70 static void invert_lr_run(struct dsp_module *module,
71 			  unsigned long sample_count)
72 {
73 	size_t i;
74 	float **ports = (float **)module->data;
75 
76 	for (i = 0; i < sample_count; i++) {
77 		ports[2][i] = -ports[0][i];
78 		ports[3][i] = ports[1][i];
79 	}
80 }
81 
invert_lr_deinstantiate(struct dsp_module * module)82 static void invert_lr_deinstantiate(struct dsp_module *module)
83 {
84 	free(module->data);
85 }
86 
invert_lr_init_module(struct dsp_module * module)87 static void invert_lr_init_module(struct dsp_module *module)
88 {
89 	module->instantiate = &invert_lr_instantiate;
90 	module->connect_port = &invert_lr_connect_port;
91 	module->get_delay = &empty_get_delay;
92 	module->run = &invert_lr_run;
93 	module->deinstantiate = &invert_lr_deinstantiate;
94 	module->free_module = &empty_free_module;
95 	module->get_properties = &empty_get_properties;
96 }
97 
98 /*
99  *  mix_stereo module functions
100  */
mix_stereo_instantiate(struct dsp_module * module,unsigned long sample_rate)101 static int mix_stereo_instantiate(struct dsp_module *module,
102 				  unsigned long sample_rate)
103 {
104 	module->data = calloc(4, sizeof(float*));
105 	return 0;
106 }
107 
mix_stereo_connect_port(struct dsp_module * module,unsigned long port,float * data_location)108 static void mix_stereo_connect_port(struct dsp_module *module,
109 				    unsigned long port, float *data_location)
110 {
111 	float **ports;
112 	ports = (float **)module->data;
113 	ports[port] = data_location;
114 }
115 
mix_stereo_run(struct dsp_module * module,unsigned long sample_count)116 static void mix_stereo_run(struct dsp_module *module,
117 			   unsigned long sample_count)
118 {
119 	size_t i;
120 	float tmp;
121 	float **ports = (float **)module->data;
122 
123 	for (i = 0; i < sample_count; i++) {
124 		tmp = ports[0][i] + ports[1][i];
125 		ports[2][i] = tmp;
126 		ports[3][i] = tmp;
127 	}
128 }
129 
mix_stereo_deinstantiate(struct dsp_module * module)130 static void mix_stereo_deinstantiate(struct dsp_module *module)
131 {
132 	free(module->data);
133 }
134 
mix_stereo_init_module(struct dsp_module * module)135 static void mix_stereo_init_module(struct dsp_module *module)
136 {
137 	module->instantiate = &mix_stereo_instantiate;
138 	module->connect_port = &mix_stereo_connect_port;
139 	module->get_delay = &empty_get_delay;
140 	module->run = &mix_stereo_run;
141 	module->deinstantiate = &mix_stereo_deinstantiate;
142 	module->free_module = &empty_free_module;
143 	module->get_properties = &empty_get_properties;
144 }
145 
146 /*
147  *  eq module functions
148  */
149 struct eq_data {
150 	int sample_rate;
151 	struct eq *eq;  /* Initialized in the first call of eq_run() */
152 
153 	/* One port for input, one for output, and 4 parameters per eq */
154 	float *ports[2 + MAX_BIQUADS_PER_EQ * 4];
155 };
156 
eq_instantiate(struct dsp_module * module,unsigned long sample_rate)157 static int eq_instantiate(struct dsp_module *module, unsigned long sample_rate)
158 {
159 	struct eq_data *data;
160 
161 	module->data = calloc(1, sizeof(struct eq_data));
162 	data = (struct eq_data *) module->data;
163 	data->sample_rate = (int) sample_rate;
164 	return 0;
165 }
166 
eq_connect_port(struct dsp_module * module,unsigned long port,float * data_location)167 static void eq_connect_port(struct dsp_module *module,
168 			    unsigned long port, float *data_location)
169 {
170 	struct eq_data *data = (struct eq_data *) module->data;
171 	data->ports[port] = data_location;
172 }
173 
eq_run(struct dsp_module * module,unsigned long sample_count)174 static void eq_run(struct dsp_module *module, unsigned long sample_count)
175 {
176 	struct eq_data *data = (struct eq_data *) module->data;
177 	if (!data->eq) {
178 		float nyquist = data->sample_rate / 2;
179 		int i;
180 
181 		data->eq = eq_new();
182 		for (i = 2; i < 2 + MAX_BIQUADS_PER_EQ * 4; i += 4) {
183 			if (!data->ports[i])
184 				break;
185 			int type = (int) *data->ports[i];
186 			float freq = *data->ports[i+1];
187 			float Q = *data->ports[i+2];
188 			float gain = *data->ports[i+3];
189 			eq_append_biquad(data->eq, type, freq / nyquist, Q,
190 					 gain);
191 		}
192 	}
193 	if (data->ports[0] != data->ports[1])
194 		memcpy(data->ports[1], data->ports[0],
195 		       sizeof(float) * sample_count);
196 	eq_process(data->eq, data->ports[1], (int) sample_count);
197 }
198 
eq_deinstantiate(struct dsp_module * module)199 static void eq_deinstantiate(struct dsp_module *module)
200 {
201 	struct eq_data *data = (struct eq_data *) module->data;
202 	if (data->eq)
203 		eq_free(data->eq);
204 	free(data);
205 }
206 
eq_init_module(struct dsp_module * module)207 static void eq_init_module(struct dsp_module *module)
208 {
209 	module->instantiate = &eq_instantiate;
210 	module->connect_port = &eq_connect_port;
211 	module->get_delay = &empty_get_delay;
212 	module->run = &eq_run;
213 	module->deinstantiate = &eq_deinstantiate;
214 	module->free_module = &empty_free_module;
215 	module->get_properties = &empty_get_properties;
216 }
217 
218 /*
219  *  eq2 module functions
220  */
221 struct eq2_data {
222 	int sample_rate;
223 	struct eq2 *eq2;  /* Initialized in the first call of eq2_run() */
224 
225 	/* Two ports for input, two for output, and 8 parameters per eq pair */
226 	float *ports[4 + MAX_BIQUADS_PER_EQ2 * 8];
227 };
228 
eq2_instantiate(struct dsp_module * module,unsigned long sample_rate)229 static int eq2_instantiate(struct dsp_module *module, unsigned long sample_rate)
230 {
231 	struct eq2_data *data;
232 
233 	module->data = calloc(1, sizeof(struct eq2_data));
234 	data = (struct eq2_data *) module->data;
235 	data->sample_rate = (int) sample_rate;
236 	return 0;
237 }
238 
eq2_connect_port(struct dsp_module * module,unsigned long port,float * data_location)239 static void eq2_connect_port(struct dsp_module *module,
240 			     unsigned long port, float *data_location)
241 {
242 	struct eq2_data *data = (struct eq2_data *) module->data;
243 	data->ports[port] = data_location;
244 }
245 
eq2_run(struct dsp_module * module,unsigned long sample_count)246 static void eq2_run(struct dsp_module *module, unsigned long sample_count)
247 {
248 	struct eq2_data *data = (struct eq2_data *) module->data;
249 	if (!data->eq2) {
250 		float nyquist = data->sample_rate / 2;
251 		int i, channel;
252 
253 		data->eq2 = eq2_new();
254 		for (i = 4; i < 4 + MAX_BIQUADS_PER_EQ2 * 8; i += 8) {
255 			if (!data->ports[i])
256 				break;
257 			for (channel = 0; channel < 2; channel++) {
258 				int k = i + channel * 4;
259 				int type = (int) *data->ports[k];
260 				float freq = *data->ports[k+1];
261 				float Q = *data->ports[k+2];
262 				float gain = *data->ports[k+3];
263 				eq2_append_biquad(data->eq2, channel, type,
264 						  freq / nyquist, Q, gain);
265 			}
266 		}
267 	}
268 
269 
270 	if (data->ports[0] != data->ports[2])
271 		memcpy(data->ports[2], data->ports[0],
272 		       sizeof(float) * sample_count);
273 	if (data->ports[3] != data->ports[1])
274 		memcpy(data->ports[3], data->ports[1],
275 		       sizeof(float) * sample_count);
276 
277 	eq2_process(data->eq2, data->ports[2], data->ports[3],
278 		    (int) sample_count);
279 }
280 
eq2_deinstantiate(struct dsp_module * module)281 static void eq2_deinstantiate(struct dsp_module *module)
282 {
283 	struct eq2_data *data = (struct eq2_data *) module->data;
284 	if (data->eq2)
285 		eq2_free(data->eq2);
286 	free(data);
287 }
288 
eq2_init_module(struct dsp_module * module)289 static void eq2_init_module(struct dsp_module *module)
290 {
291 	module->instantiate = &eq2_instantiate;
292 	module->connect_port = &eq2_connect_port;
293 	module->get_delay = &empty_get_delay;
294 	module->run = &eq2_run;
295 	module->deinstantiate = &eq2_deinstantiate;
296 	module->free_module = &empty_free_module;
297 	module->get_properties = &empty_get_properties;
298 }
299 
300 /*
301  *  drc module functions
302  */
303 struct drc_data {
304 	int sample_rate;
305 	struct drc *drc;  /* Initialized in the first call of drc_run() */
306 
307 	/* Two ports for input, two for output, one for disable_emphasis,
308 	 * and 8 parameters each band */
309 	float *ports[4 + 1 + 8 * 3];
310 };
311 
drc_instantiate(struct dsp_module * module,unsigned long sample_rate)312 static int drc_instantiate(struct dsp_module *module, unsigned long sample_rate)
313 {
314 	struct drc_data *data;
315 
316 	module->data = calloc(1, sizeof(struct drc_data));
317 	data = (struct drc_data *) module->data;
318 	data->sample_rate = (int) sample_rate;
319 	return 0;
320 }
321 
drc_connect_port(struct dsp_module * module,unsigned long port,float * data_location)322 static void drc_connect_port(struct dsp_module *module,
323 			    unsigned long port, float *data_location)
324 {
325 	struct drc_data *data = (struct drc_data *) module->data;
326 	data->ports[port] = data_location;
327 }
328 
drc_get_delay(struct dsp_module * module)329 static int drc_get_delay(struct dsp_module *module)
330 {
331 	struct drc_data *data = (struct drc_data *) module->data;
332 	return DRC_DEFAULT_PRE_DELAY * data->sample_rate;
333 }
334 
drc_run(struct dsp_module * module,unsigned long sample_count)335 static void drc_run(struct dsp_module *module, unsigned long sample_count)
336 {
337 	struct drc_data *data = (struct drc_data *) module->data;
338 	if (!data->drc) {
339 		int i;
340 		float nyquist = data->sample_rate / 2;
341 		struct drc *drc = drc_new(data->sample_rate);
342 
343 		data->drc = drc;
344 		drc->emphasis_disabled = (int) *data->ports[4];
345 		for (i = 0; i < 3; i++) {
346 			int k = 5 + i * 8;
347 			float f = *data->ports[k];
348 			float enable = *data->ports[k+1];
349 			float threshold = *data->ports[k+2];
350 			float knee = *data->ports[k+3];
351 			float ratio = *data->ports[k+4];
352 			float attack = *data->ports[k+5];
353 			float release = *data->ports[k+6];
354 			float boost = *data->ports[k+7];
355 			drc_set_param(drc, i, PARAM_CROSSOVER_LOWER_FREQ,
356 				      f / nyquist);
357 			drc_set_param(drc, i, PARAM_ENABLED, enable);
358 			drc_set_param(drc, i, PARAM_THRESHOLD, threshold);
359 			drc_set_param(drc, i, PARAM_KNEE, knee);
360 			drc_set_param(drc, i, PARAM_RATIO, ratio);
361 			drc_set_param(drc, i, PARAM_ATTACK, attack);
362 			drc_set_param(drc, i, PARAM_RELEASE, release);
363 			drc_set_param(drc, i, PARAM_POST_GAIN, boost);
364 		}
365 		drc_init(drc);
366 	}
367 	if (data->ports[0] != data->ports[2])
368 		memcpy(data->ports[2], data->ports[0],
369 		       sizeof(float) * sample_count);
370 	if (data->ports[1] != data->ports[3])
371 		memcpy(data->ports[3], data->ports[1],
372 		       sizeof(float) * sample_count);
373 
374 	drc_process(data->drc, &data->ports[2], (int) sample_count);
375 }
376 
drc_deinstantiate(struct dsp_module * module)377 static void drc_deinstantiate(struct dsp_module *module)
378 {
379 	struct drc_data *data = (struct drc_data *) module->data;
380 	if (data->drc)
381 		drc_free(data->drc);
382 	free(data);
383 }
384 
drc_init_module(struct dsp_module * module)385 static void drc_init_module(struct dsp_module *module)
386 {
387 	module->instantiate = &drc_instantiate;
388 	module->connect_port = &drc_connect_port;
389 	module->get_delay = &drc_get_delay;
390 	module->run = &drc_run;
391 	module->deinstantiate = &drc_deinstantiate;
392 	module->free_module = &empty_free_module;
393 	module->get_properties = &empty_get_properties;
394 }
395 
396 /*
397  *  builtin module dispatcher
398  */
cras_dsp_module_load_builtin(struct plugin * plugin)399 struct dsp_module *cras_dsp_module_load_builtin(struct plugin *plugin)
400 {
401 	struct dsp_module *module;
402 	if (strcmp(plugin->library, "builtin") != 0)
403 		return NULL;
404 
405 	module = calloc(1, sizeof(struct dsp_module));
406 
407 	if (strcmp(plugin->label, "mix_stereo") == 0) {
408 		mix_stereo_init_module(module);
409 	} else if (strcmp(plugin->label, "invert_lr") == 0) {
410 		invert_lr_init_module(module);
411 	} else if (strcmp(plugin->label, "eq") == 0) {
412 		eq_init_module(module);
413 	} else if (strcmp(plugin->label, "eq2") == 0) {
414 		eq2_init_module(module);
415 	} else if (strcmp(plugin->label, "drc") == 0) {
416 		drc_init_module(module);
417 	} else {
418 		empty_init_module(module);
419 	}
420 
421 	return module;
422 }
423