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