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_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 */ 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 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 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 82 static void invert_lr_deinstantiate(struct dsp_module *module) 83 { 84 free(module->data); 85 } 86 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 */ 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 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 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 130 static void mix_stereo_deinstantiate(struct dsp_module *module) 131 { 132 free(module->data); 133 } 134 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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