1 /** 2 * \file pcm/pcm_ladspa.c 3 * \ingroup PCM_Plugins 4 * \brief ALSA Plugin <-> LADSPA Plugin Interface 5 * \author Jaroslav Kysela <perex (at) perex.cz> 6 * \author Jaroslav Kysela <perex (at) perex.cz> 7 * \date 2001,2006 8 */ 9 /* 10 * PCM - LADSPA integration plugin 11 * Copyright (c) 2001-2006 by Jaroslav Kysela <perex (at) perex.cz> 12 * Copyright (c) 2005 by Jaroslav Kysela <perex (at) perex.cz> 13 * 14 * 15 * This library is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU Lesser General Public License as 17 * published by the Free Software Foundation; either version 2.1 of 18 * the License, or (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * GNU Lesser General Public License for more details. 24 * 25 * You should have received a copy of the GNU Lesser General Public 26 * License along with this library; if not, write to the Free Software 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 * 29 * 30 * perex (at) perex.cz 2005/12/13 31 * The LADSPA plugin rewrite was sponsored by MediaNet AG 32 * http://www.medianet.ag 33 */ 34 35 #include <dirent.h> 36 #include <locale.h> 37 #include <math.h> 38 #include "pcm_local.h" 39 #include "pcm_plugin.h" 40 41 #include "ladspa.h" 42 43 #ifndef PIC 44 /* entry for static linking */ 45 const char *_snd_module_pcm_ladspa = ""; 46 #endif 47 48 #ifndef DOC_HIDDEN 49 50 #define NO_ASSIGN 0xffffffff 51 52 typedef enum _snd_pcm_ladspa_policy { 53 SND_PCM_LADSPA_POLICY_NONE, /* use bindings only */ 54 SND_PCM_LADSPA_POLICY_DUPLICATE /* duplicate bindings for all channels */ 55 } snd_pcm_ladspa_policy_t; 56 57 typedef struct { 58 /* This field need to be the first */ 59 snd_pcm_plugin_t plug; 60 /* Plugin custom fields */ 61 struct list_head pplugins; 62 struct list_head cplugins; 63 unsigned int channels; /* forced input channels, 0 = auto */ 64 unsigned int allocated; /* count of allocated samples */ 65 LADSPA_Data *zero[2]; /* zero input or dummy output */ 66 } snd_pcm_ladspa_t; 67 68 typedef struct { 69 unsigned int size; 70 unsigned int *array; 71 } snd_pcm_ladspa_array_t; 72 73 typedef struct { 74 snd_pcm_ladspa_array_t channels; 75 snd_pcm_ladspa_array_t ports; 76 LADSPA_Data **m_data; 77 LADSPA_Data **data; 78 } snd_pcm_ladspa_eps_t; 79 80 typedef struct snd_pcm_ladspa_instance { 81 struct list_head list; 82 const LADSPA_Descriptor *desc; 83 LADSPA_Handle *handle; 84 unsigned int depth; 85 snd_pcm_ladspa_eps_t input; 86 snd_pcm_ladspa_eps_t output; 87 struct snd_pcm_ladspa_instance *prev; 88 struct snd_pcm_ladspa_instance *next; 89 } snd_pcm_ladspa_instance_t; 90 91 typedef struct { 92 LADSPA_PortDescriptor pdesc; /* port description */ 93 unsigned int port_bindings_size; /* size of array */ 94 unsigned int *port_bindings; /* index = channel number, value = LADSPA port */ 95 unsigned int controls_size; /* size of array */ 96 unsigned char *controls_initialized; /* initialized by ALSA user */ 97 LADSPA_Data *controls; /* index = LADSPA control port index */ 98 } snd_pcm_ladspa_plugin_io_t; 99 100 typedef struct { 101 struct list_head list; 102 snd_pcm_ladspa_policy_t policy; 103 char *filename; 104 void *dl_handle; 105 const LADSPA_Descriptor *desc; 106 snd_pcm_ladspa_plugin_io_t input; 107 snd_pcm_ladspa_plugin_io_t output; 108 struct list_head instances; /* one LADSPA plugin might be used multiple times */ 109 } snd_pcm_ladspa_plugin_t; 110 111 #endif /* DOC_HIDDEN */ 112 113 static unsigned int snd_pcm_ladspa_count_ports(snd_pcm_ladspa_plugin_t *lplug, 114 LADSPA_PortDescriptor pdesc) 115 { 116 unsigned int res = 0, idx; 117 for (idx = 0; idx < lplug->desc->PortCount; idx++) { 118 if ((lplug->desc->PortDescriptors[idx] & pdesc) == pdesc) 119 res++; 120 } 121 return res; 122 } 123 124 static int snd_pcm_ladspa_find_port(unsigned int *res, 125 snd_pcm_ladspa_plugin_t *lplug, 126 LADSPA_PortDescriptor pdesc, 127 unsigned int port_idx) 128 { 129 unsigned long idx; 130 131 for (idx = 0; idx < lplug->desc->PortCount; idx++) 132 if ((lplug->desc->PortDescriptors[idx] & pdesc) == pdesc) { 133 if (port_idx == 0) { 134 *res = idx; 135 return 0; 136 } 137 port_idx--; 138 } 139 return -EINVAL; 140 } 141 142 static int snd_pcm_ladspa_find_sport(unsigned int *res, 143 snd_pcm_ladspa_plugin_t *lplug, 144 LADSPA_PortDescriptor pdesc, 145 const char *port_name) 146 { 147 unsigned long idx; 148 149 for (idx = 0; idx < lplug->desc->PortCount; idx++) 150 if ((lplug->desc->PortDescriptors[idx] & pdesc) == pdesc && 151 !strcmp(lplug->desc->PortNames[idx], port_name)) { 152 *res = idx; 153 return 0; 154 } 155 return -EINVAL; 156 } 157 158 static int snd_pcm_ladspa_find_port_idx(unsigned int *res, 159 snd_pcm_ladspa_plugin_t *lplug, 160 LADSPA_PortDescriptor pdesc, 161 unsigned int port) 162 { 163 unsigned long idx; 164 unsigned int r = 0; 165 166 if (port >= lplug->desc->PortCount) 167 return -EINVAL; 168 for (idx = 0; idx < port; idx++) 169 if ((lplug->desc->PortDescriptors[idx] & pdesc) == pdesc) 170 r++; 171 *res = r; 172 return 0; 173 } 174 175 static void snd_pcm_ladspa_free_io(snd_pcm_ladspa_plugin_io_t *io) 176 { 177 free(io->controls); 178 free(io->controls_initialized); 179 } 180 181 static void snd_pcm_ladspa_free_plugins(struct list_head *plugins) 182 { 183 while (!list_empty(plugins)) { 184 snd_pcm_ladspa_plugin_t *plugin = list_entry(plugins->next, snd_pcm_ladspa_plugin_t, list); 185 snd_pcm_ladspa_free_io(&plugin->input); 186 snd_pcm_ladspa_free_io(&plugin->output); 187 if (plugin->dl_handle) 188 dlclose(plugin->dl_handle); 189 free(plugin->filename); 190 list_del(&plugin->list); 191 free(plugin); 192 } 193 } 194 195 static void snd_pcm_ladspa_free(snd_pcm_ladspa_t *ladspa) 196 { 197 unsigned int idx; 198 199 snd_pcm_ladspa_free_plugins(&ladspa->pplugins); 200 snd_pcm_ladspa_free_plugins(&ladspa->cplugins); 201 for (idx = 0; idx < 2; idx++) { 202 free(ladspa->zero[idx]); 203 ladspa->zero[idx] = NULL; 204 } 205 ladspa->allocated = 0; 206 } 207 208 static int snd_pcm_ladspa_close(snd_pcm_t *pcm) 209 { 210 snd_pcm_ladspa_t *ladspa = pcm->private_data; 211 212 snd_pcm_ladspa_free(ladspa); 213 return snd_pcm_generic_close(pcm); 214 } 215 216 static int snd_pcm_ladspa_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params) 217 { 218 snd_pcm_ladspa_t *ladspa = pcm->private_data; 219 int err; 220 snd_pcm_access_mask_t access_mask = { SND_PCM_ACCBIT_SHMN }; 221 err = _snd_pcm_hw_param_set_mask(params, SND_PCM_HW_PARAM_ACCESS, 222 &access_mask); 223 if (err < 0) 224 return err; 225 err = _snd_pcm_hw_params_set_format(params, SND_PCM_FORMAT_FLOAT); 226 if (err < 0) 227 return err; 228 err = _snd_pcm_hw_params_set_subformat(params, SND_PCM_SUBFORMAT_STD); 229 if (err < 0) 230 return err; 231 if (ladspa->channels > 0 && pcm->stream == SND_PCM_STREAM_PLAYBACK) { 232 err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_CHANNELS, ladspa->channels, 0); 233 if (err < 0) 234 return err; 235 } 236 params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID); 237 return 0; 238 } 239 240 static int snd_pcm_ladspa_hw_refine_sprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *sparams) 241 { 242 snd_pcm_ladspa_t *ladspa = pcm->private_data; 243 snd_pcm_access_mask_t saccess_mask = { SND_PCM_ACCBIT_MMAPN }; 244 _snd_pcm_hw_params_any(sparams); 245 _snd_pcm_hw_param_set_mask(sparams, SND_PCM_HW_PARAM_ACCESS, 246 &saccess_mask); 247 _snd_pcm_hw_params_set_format(sparams, SND_PCM_FORMAT_FLOAT); 248 _snd_pcm_hw_params_set_subformat(sparams, SND_PCM_SUBFORMAT_STD); 249 if (ladspa->channels > 0 && pcm->stream == SND_PCM_STREAM_CAPTURE) 250 _snd_pcm_hw_param_set(sparams, SND_PCM_HW_PARAM_CHANNELS, ladspa->channels, 0); 251 return 0; 252 } 253 254 static int snd_pcm_ladspa_hw_refine_schange(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params, 255 snd_pcm_hw_params_t *sparams) 256 { 257 int err; 258 unsigned int links = (SND_PCM_HW_PARBIT_CHANNELS | 259 SND_PCM_HW_PARBIT_RATE | 260 SND_PCM_HW_PARBIT_PERIOD_SIZE | 261 SND_PCM_HW_PARBIT_BUFFER_SIZE | 262 SND_PCM_HW_PARBIT_PERIODS | 263 SND_PCM_HW_PARBIT_PERIOD_TIME | 264 SND_PCM_HW_PARBIT_BUFFER_TIME | 265 SND_PCM_HW_PARBIT_TICK_TIME); 266 err = _snd_pcm_hw_params_refine(sparams, links, params); 267 if (err < 0) 268 return err; 269 return 0; 270 } 271 272 static int snd_pcm_ladspa_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params, 273 snd_pcm_hw_params_t *sparams) 274 { 275 int err; 276 unsigned int links = (SND_PCM_HW_PARBIT_CHANNELS | 277 SND_PCM_HW_PARBIT_RATE | 278 SND_PCM_HW_PARBIT_PERIOD_SIZE | 279 SND_PCM_HW_PARBIT_BUFFER_SIZE | 280 SND_PCM_HW_PARBIT_PERIODS | 281 SND_PCM_HW_PARBIT_PERIOD_TIME | 282 SND_PCM_HW_PARBIT_BUFFER_TIME | 283 SND_PCM_HW_PARBIT_TICK_TIME); 284 err = _snd_pcm_hw_params_refine(params, links, sparams); 285 if (err < 0) 286 return err; 287 return 0; 288 } 289 290 static int snd_pcm_ladspa_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) 291 { 292 return snd_pcm_hw_refine_slave(pcm, params, 293 snd_pcm_ladspa_hw_refine_cprepare, 294 snd_pcm_ladspa_hw_refine_cchange, 295 snd_pcm_ladspa_hw_refine_sprepare, 296 snd_pcm_ladspa_hw_refine_schange, 297 snd_pcm_generic_hw_refine); 298 } 299 300 static int snd_pcm_ladspa_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) 301 { 302 // snd_pcm_ladspa_t *ladspa = pcm->private_data; 303 int err = snd_pcm_hw_params_slave(pcm, params, 304 snd_pcm_ladspa_hw_refine_cchange, 305 snd_pcm_ladspa_hw_refine_sprepare, 306 snd_pcm_ladspa_hw_refine_schange, 307 snd_pcm_generic_hw_params); 308 if (err < 0) 309 return err; 310 return 0; 311 } 312 313 static void snd_pcm_ladspa_free_eps(snd_pcm_ladspa_eps_t *eps) 314 { 315 free(eps->channels.array); 316 free(eps->ports.array); 317 } 318 319 static void snd_pcm_ladspa_free_instances(snd_pcm_t *pcm, snd_pcm_ladspa_t *ladspa, int cleanup) 320 { 321 struct list_head *list, *pos, *pos1, *next1; 322 unsigned int idx; 323 324 list = pcm->stream == SND_PCM_STREAM_PLAYBACK ? &ladspa->pplugins : &ladspa->cplugins; 325 list_for_each(pos, list) { 326 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list); 327 list_for_each_safe(pos1, next1, &plugin->instances) { 328 snd_pcm_ladspa_instance_t *instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list); 329 if (plugin->desc->deactivate) 330 plugin->desc->deactivate(instance->handle); 331 if (cleanup) { 332 if (plugin->desc->cleanup) 333 plugin->desc->cleanup(instance->handle); 334 if (instance->input.m_data) { 335 for (idx = 0; idx < instance->input.channels.size; idx++) 336 free(instance->input.m_data[idx]); 337 free(instance->input.m_data); 338 } 339 if (instance->output.m_data) { 340 for (idx = 0; idx < instance->output.channels.size; idx++) 341 free(instance->output.m_data[idx]); 342 free(instance->output.m_data); 343 } 344 list_del(&(instance->list)); 345 snd_pcm_ladspa_free_eps(&instance->input); 346 snd_pcm_ladspa_free_eps(&instance->output); 347 free(instance); 348 } else { 349 if (plugin->desc->activate) 350 plugin->desc->activate(instance->handle); 351 } 352 } 353 if (cleanup) { 354 assert(list_empty(&plugin->instances)); 355 } 356 } 357 } 358 359 static int snd_pcm_ladspa_add_to_carray(snd_pcm_ladspa_array_t *array, 360 unsigned int idx, 361 unsigned int val) 362 { 363 unsigned int *narray; 364 unsigned int idx1; 365 366 if (idx >= array->size) { 367 narray = realloc(array->array, sizeof(unsigned int) * (idx + 1)); 368 if (narray == NULL) 369 return -ENOMEM; 370 for (idx1 = array->size; idx1 < idx; idx1++) 371 narray[idx1] = NO_ASSIGN; 372 array->array = narray; 373 array->size = idx + 1; 374 array->array[idx] = val; 375 return 0; 376 } 377 if (array->array[idx] == NO_ASSIGN) 378 array->array[idx] = val; 379 else 380 return -EINVAL; 381 return 0; 382 } 383 384 static int snd_pcm_ladspa_add_to_array(snd_pcm_ladspa_array_t *array, 385 unsigned int idx, 386 unsigned int val) 387 { 388 unsigned int *narray; 389 unsigned int idx1; 390 391 if (idx >= array->size) { 392 narray = realloc(array->array, sizeof(unsigned int) * (idx + 1)); 393 if (narray == NULL) 394 return -ENOMEM; 395 for (idx1 = array->size; idx1 < idx; idx1++) 396 narray[idx1] = NO_ASSIGN; 397 array->array = narray; 398 array->size = idx + 1; 399 } 400 array->array[idx] = val; 401 return 0; 402 } 403 404 static int snd_pcm_ladspa_connect_plugin1(snd_pcm_ladspa_plugin_t *plugin, 405 snd_pcm_ladspa_plugin_io_t *io, 406 snd_pcm_ladspa_eps_t *eps) 407 { 408 unsigned int port, channels, idx, idx1; 409 int err; 410 411 assert(plugin->policy == SND_PCM_LADSPA_POLICY_NONE); 412 channels = io->port_bindings_size > 0 ? 413 io->port_bindings_size : 414 snd_pcm_ladspa_count_ports(plugin, io->pdesc | LADSPA_PORT_AUDIO); 415 for (idx = idx1 = 0; idx < channels; idx++) { 416 if (io->port_bindings_size > 0) 417 port = io->port_bindings[idx]; 418 else { 419 err = snd_pcm_ladspa_find_port(&port, plugin, io->pdesc | LADSPA_PORT_AUDIO, idx); 420 if (err < 0) { 421 SNDERR("unable to find audio %s port %u plugin '%s'", io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", idx, plugin->desc->Name); 422 return err; 423 } 424 } 425 if (port == NO_ASSIGN) 426 continue; 427 err = snd_pcm_ladspa_add_to_carray(&eps->channels, idx1, idx); 428 if (err < 0) { 429 SNDERR("unable to add channel %u for audio %s plugin '%s'", idx, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name); 430 return err; 431 } 432 err = snd_pcm_ladspa_add_to_array(&eps->ports, idx1, port); 433 if (err < 0) { 434 SNDERR("unable to add port %u for audio %s plugin '%s'", port, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name); 435 return err; 436 } 437 idx1++; 438 } 439 return 0; 440 } 441 442 static int snd_pcm_ladspa_connect_plugin(snd_pcm_ladspa_plugin_t *plugin, 443 snd_pcm_ladspa_instance_t *instance) 444 { 445 int err; 446 447 err = snd_pcm_ladspa_connect_plugin1(plugin, &plugin->input, &instance->input); 448 if (err < 0) 449 return err; 450 err = snd_pcm_ladspa_connect_plugin1(plugin, &plugin->output, &instance->output); 451 if (err < 0) 452 return err; 453 return 0; 454 } 455 456 static int snd_pcm_ladspa_connect_plugin_duplicate1(snd_pcm_ladspa_plugin_t *plugin, 457 snd_pcm_ladspa_plugin_io_t *io, 458 snd_pcm_ladspa_eps_t *eps, 459 unsigned int idx) 460 { 461 unsigned int port; 462 int err; 463 464 assert(plugin->policy == SND_PCM_LADSPA_POLICY_DUPLICATE); 465 if (io->port_bindings_size > 0) { 466 port = io->port_bindings[0]; 467 } else { 468 err = snd_pcm_ladspa_find_port(&port, plugin, io->pdesc | LADSPA_PORT_AUDIO, 0); 469 if (err < 0) { 470 SNDERR("unable to find audio %s port %u plugin '%s'", io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", (unsigned int)0, plugin->desc->Name); 471 return err; 472 } 473 } 474 err = snd_pcm_ladspa_add_to_carray(&eps->channels, 0, idx); 475 if (err < 0) { 476 SNDERR("unable to add channel %u for audio %s plugin '%s'", idx, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name); 477 return err; 478 } 479 err = snd_pcm_ladspa_add_to_array(&eps->ports, 0, port); 480 if (err < 0) { 481 SNDERR("unable to add port %u for audio %s plugin '%s'", port, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name); 482 return err; 483 } 484 return 0; 485 } 486 487 static int snd_pcm_ladspa_connect_plugin_duplicate(snd_pcm_ladspa_plugin_t *plugin, 488 snd_pcm_ladspa_plugin_io_t *in_io, 489 snd_pcm_ladspa_plugin_io_t *out_io, 490 snd_pcm_ladspa_instance_t *instance, 491 unsigned int idx) 492 { 493 int err; 494 495 err = snd_pcm_ladspa_connect_plugin_duplicate1(plugin, in_io, &instance->input, idx); 496 if (err < 0) 497 return err; 498 err = snd_pcm_ladspa_connect_plugin_duplicate1(plugin, out_io, &instance->output, idx); 499 if (err < 0) 500 return err; 501 return 0; 502 } 503 504 static void snd_pcm_ladspa_get_default_cvalue(const LADSPA_Descriptor * desc, unsigned int port, LADSPA_Data *val) 505 { 506 LADSPA_PortRangeHintDescriptor hdesc; 507 508 hdesc = desc->PortRangeHints[port].HintDescriptor; 509 switch (hdesc & LADSPA_HINT_DEFAULT_MASK) { 510 case LADSPA_HINT_DEFAULT_MINIMUM: 511 *val = desc->PortRangeHints[port].LowerBound; 512 break; 513 case LADSPA_HINT_DEFAULT_LOW: 514 if (LADSPA_IS_HINT_LOGARITHMIC(hdesc)) { 515 *val = exp(log(desc->PortRangeHints[port].LowerBound) 516 * 0.75 517 + log(desc->PortRangeHints[port].UpperBound) 518 * 0.25); 519 } else { 520 *val = (desc->PortRangeHints[port].LowerBound * 0.75) + 521 (desc->PortRangeHints[port].UpperBound * 0.25); 522 } 523 break; 524 case LADSPA_HINT_DEFAULT_MIDDLE: 525 if (LADSPA_IS_HINT_LOGARITHMIC(hdesc)) { 526 *val = sqrt(desc->PortRangeHints[port].LowerBound * 527 desc->PortRangeHints[port].UpperBound); 528 } else { 529 *val = 0.5 * 530 (desc->PortRangeHints[port].LowerBound + 531 desc->PortRangeHints[port].UpperBound); 532 } 533 break; 534 case LADSPA_HINT_DEFAULT_HIGH: 535 if (LADSPA_IS_HINT_LOGARITHMIC(hdesc)) { 536 *val = exp(log(desc->PortRangeHints[port].LowerBound) 537 * 0.25 538 + log(desc->PortRangeHints[port].UpperBound) 539 * 0.75); 540 } else { 541 *val = (desc->PortRangeHints[port].LowerBound * 0.25) + 542 (desc->PortRangeHints[port].UpperBound * 0.75); 543 } 544 break; 545 case LADSPA_HINT_DEFAULT_MAXIMUM: 546 *val = desc->PortRangeHints[port].UpperBound; 547 break; 548 case LADSPA_HINT_DEFAULT_0: 549 *val = 0; 550 break; 551 case LADSPA_HINT_DEFAULT_1: 552 *val = 1; 553 break; 554 case LADSPA_HINT_DEFAULT_100: 555 *val = 100; 556 break; 557 case LADSPA_HINT_DEFAULT_440: 558 *val = 440; 559 break; 560 default: 561 *val = 0; /* reasonable default, if everything fails */ 562 break; 563 } 564 } 565 566 static int snd_pcm_ladspa_connect_controls(snd_pcm_ladspa_plugin_t *plugin, 567 snd_pcm_ladspa_plugin_io_t *io, 568 snd_pcm_ladspa_instance_t *instance) 569 { 570 unsigned long idx, midx; 571 572 for (idx = midx = 0; idx < plugin->desc->PortCount; idx++) 573 if ((plugin->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_CONTROL)) == (io->pdesc | LADSPA_PORT_CONTROL)) { 574 if (io->controls_size > midx) { 575 if (!io->controls_initialized[midx]) 576 snd_pcm_ladspa_get_default_cvalue(plugin->desc, idx, &io->controls[midx]); 577 plugin->desc->connect_port(instance->handle, idx, &io->controls[midx]); 578 } else { 579 return -EINVAL; 580 } 581 midx++; 582 } 583 return 0; 584 } 585 586 static int snd_pcm_ladspa_check_connect(snd_pcm_ladspa_plugin_t *plugin, 587 snd_pcm_ladspa_plugin_io_t *io, 588 snd_pcm_ladspa_eps_t *eps, 589 unsigned int depth) 590 { 591 unsigned int idx, midx; 592 int err = 0; 593 594 for (idx = midx = 0; idx < plugin->desc->PortCount; idx++) 595 if ((plugin->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_AUDIO)) == (io->pdesc | LADSPA_PORT_AUDIO)) { 596 if (eps->channels.array[midx] == NO_ASSIGN) { 597 SNDERR("%s port for plugin %s depth %u is not connected", io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name, depth); 598 err++; 599 } 600 midx++; 601 } 602 if (err > 0) { 603 SNDERR("%i connection errors total", err); 604 return -EINVAL; 605 } 606 return 0; 607 } 608 609 static int snd_pcm_ladspa_allocate_instances(snd_pcm_t *pcm, snd_pcm_ladspa_t *ladspa) 610 { 611 struct list_head *list, *pos; 612 unsigned int depth, idx, count; 613 unsigned int in_channel, out_channel; 614 unsigned int in_channels, out_channels; 615 unsigned int in_ports, out_ports; 616 snd_pcm_ladspa_instance_t *instance = NULL; 617 int err; 618 619 list = pcm->stream == SND_PCM_STREAM_PLAYBACK ? &ladspa->pplugins : &ladspa->cplugins; 620 in_channels = ladspa->channels > 0 ? ladspa->channels : 621 (pcm->stream == SND_PCM_STREAM_PLAYBACK ? pcm->channels : ladspa->plug.gen.slave->channels); 622 depth = 0; 623 out_channels = 0; 624 list_for_each(pos, list) { 625 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list); 626 if (pos->next == list) /* last entry */ 627 out_channels = pcm->stream == SND_PCM_STREAM_PLAYBACK ? ladspa->plug.gen.slave->channels : pcm->channels; 628 in_ports = snd_pcm_ladspa_count_ports(plugin, LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO); 629 out_ports = snd_pcm_ladspa_count_ports(plugin, LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO); 630 count = 1; 631 if (plugin->policy == SND_PCM_LADSPA_POLICY_DUPLICATE) { 632 if (in_ports == 1 && out_ports == 1) 633 count = in_channels; 634 else 635 plugin->policy = SND_PCM_LADSPA_POLICY_NONE; 636 } 637 in_channel = 0; 638 out_channel = 0; 639 for (idx = 0; idx < count; idx++) { 640 instance = (snd_pcm_ladspa_instance_t *)calloc(1, sizeof(snd_pcm_ladspa_instance_t)); 641 if (instance == NULL) 642 return -ENOMEM; 643 instance->desc = plugin->desc; 644 instance->handle = plugin->desc->instantiate(plugin->desc, pcm->rate); 645 instance->depth = depth; 646 if (instance->handle == NULL) { 647 SNDERR("Unable to create instance of LADSPA plugin '%s'", plugin->desc->Name); 648 free(instance); 649 return -EINVAL; 650 } 651 list_add_tail(&instance->list, &plugin->instances); 652 if (plugin->desc->activate) 653 plugin->desc->activate(instance->handle); 654 if (plugin->policy == SND_PCM_LADSPA_POLICY_DUPLICATE) { 655 err = snd_pcm_ladspa_connect_plugin_duplicate(plugin, &plugin->input, &plugin->output, instance, idx); 656 if (err < 0) { 657 SNDERR("Unable to connect duplicate port of plugin '%s' channel %u depth %u", plugin->desc->Name, idx, instance->depth); 658 return err; 659 } 660 } else { 661 err = snd_pcm_ladspa_connect_plugin(plugin, instance); 662 if (err < 0) { 663 SNDERR("Unable to connect plugin '%s' depth %u", plugin->desc->Name, depth); 664 return err; 665 } 666 } 667 err = snd_pcm_ladspa_connect_controls(plugin, &plugin->input, instance); 668 assert(err >= 0); 669 err = snd_pcm_ladspa_connect_controls(plugin, &plugin->output, instance); 670 assert(err >= 0); 671 } 672 err = snd_pcm_ladspa_check_connect(plugin, &plugin->input, &instance->input, depth); 673 if (err < 0) 674 return err; 675 err = snd_pcm_ladspa_check_connect(plugin, &plugin->output, &instance->output, depth); 676 if (err < 0) 677 return err; 678 depth++; 679 } 680 return 0; 681 } 682 683 static LADSPA_Data *snd_pcm_ladspa_allocate_zero(snd_pcm_ladspa_t *ladspa, unsigned int idx) 684 { 685 if (ladspa->zero[idx] == NULL) 686 ladspa->zero[idx] = calloc(ladspa->allocated, sizeof(LADSPA_Data)); 687 return ladspa->zero[idx]; 688 } 689 690 static int snd_pcm_ladspa_allocate_memory(snd_pcm_t *pcm, snd_pcm_ladspa_t *ladspa) 691 { 692 struct list_head *list, *pos, *pos1; 693 snd_pcm_ladspa_instance_t *instance; 694 unsigned int channels = 16, nchannels; 695 unsigned int ichannels, ochannels; 696 void **pchannels, **npchannels; 697 unsigned int idx, chn; 698 699 ladspa->allocated = 2048; 700 if (pcm->buffer_size > ladspa->allocated) 701 ladspa->allocated = pcm->buffer_size; 702 if (pcm->stream == SND_PCM_STREAM_PLAYBACK) { 703 ichannels = pcm->channels; 704 ochannels = ladspa->plug.gen.slave->channels; 705 } else { 706 ichannels = ladspa->plug.gen.slave->channels; 707 ochannels = pcm->channels; 708 } 709 pchannels = calloc(1, sizeof(void *) * channels); 710 if (pchannels == NULL) 711 return -ENOMEM; 712 list = pcm->stream == SND_PCM_STREAM_PLAYBACK ? &ladspa->pplugins : &ladspa->cplugins; 713 list_for_each(pos, list) { 714 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list); 715 list_for_each(pos1, &plugin->instances) { 716 instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list); 717 nchannels = channels; 718 for (idx = 0; idx < instance->input.channels.size; idx++) { 719 chn = instance->input.channels.array[idx]; 720 assert(instance->input.ports.array[idx] != NO_ASSIGN); 721 if (chn >= nchannels) 722 nchannels = chn + 1; 723 } 724 for (idx = 0; idx < instance->output.channels.size; idx++) { 725 chn = instance->output.channels.array[idx]; 726 assert(instance->output.ports.array[idx] != NO_ASSIGN); 727 if (chn >= nchannels) 728 nchannels = chn + 1; 729 } 730 if (nchannels != channels) { 731 npchannels = realloc(pchannels, nchannels * sizeof(void *)); 732 if (npchannels == NULL) { 733 free(pchannels); 734 return -ENOMEM; 735 } 736 for (idx = channels; idx < nchannels; idx++) 737 npchannels[idx] = NULL; 738 pchannels = npchannels; 739 } 740 assert(instance->input.data == NULL); 741 assert(instance->input.m_data == NULL); 742 assert(instance->output.data == NULL); 743 assert(instance->output.m_data == NULL); 744 instance->input.data = calloc(instance->input.channels.size, sizeof(void *)); 745 instance->input.m_data = calloc(instance->input.channels.size, sizeof(void *)); 746 instance->output.data = calloc(instance->output.channels.size, sizeof(void *)); 747 instance->output.m_data = calloc(instance->output.channels.size, sizeof(void *)); 748 if (instance->input.data == NULL || 749 instance->input.m_data == NULL || 750 instance->output.data == NULL || 751 instance->output.m_data == NULL) 752 return -ENOMEM; 753 for (idx = 0; idx < instance->input.channels.size; idx++) { 754 chn = instance->output.channels.array[idx]; 755 if (pchannels[chn] == NULL && chn < ichannels) { 756 instance->input.data[idx] = NULL; 757 continue; 758 } 759 instance->input.data[idx] = pchannels[chn]; 760 if (instance->input.data[idx] == NULL) { 761 instance->input.data[idx] = snd_pcm_ladspa_allocate_zero(ladspa, 0); 762 if (instance->input.data[idx] == NULL) 763 return -ENOMEM; 764 } 765 } 766 for (idx = 0; idx < instance->output.channels.size; idx++) { 767 chn = instance->output.channels.array[idx]; 768 /* FIXME/OPTIMIZE: check if we can remove double alloc */ 769 /* if LADSPA plugin has no broken inplace */ 770 instance->output.data[idx] = malloc(sizeof(LADSPA_Data) * ladspa->allocated); 771 if (instance->output.data[idx] == NULL) 772 return -ENOMEM; 773 pchannels[chn] = instance->output.m_data[idx] = instance->output.data[idx]; 774 } 775 } 776 } 777 /* OPTIMIZE: we have already allocated areas for ALSA output channels */ 778 /* next loop deallocates the last output LADSPA areas and connects */ 779 /* them to ALSA areas (NULL) or dummy area ladpsa->free[1] ; */ 780 /* this algorithm might be optimized to not allocate the last LADSPA outputs */ 781 list_for_each(pos, list) { 782 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list); 783 list_for_each(pos1, &plugin->instances) { 784 instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list); 785 for (idx = 0; idx < instance->output.channels.size; idx++) { 786 chn = instance->output.channels.array[idx]; 787 if (instance->output.data[idx] == pchannels[chn]) { 788 free(instance->output.m_data[idx]); 789 instance->output.m_data[idx] = NULL; 790 if (chn < ochannels) { 791 instance->output.data[idx] = NULL; 792 } else { 793 instance->output.data[idx] = snd_pcm_ladspa_allocate_zero(ladspa, 1); 794 if (instance->output.data[idx] == NULL) 795 return -ENOMEM; 796 } 797 } 798 } 799 } 800 } 801 #if 0 802 printf("zero[0] = %p\n", ladspa->zero[0]); 803 printf("zero[1] = %p\n", ladspa->zero[1]); 804 list_for_each(pos, list) { 805 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list); 806 list_for_each(pos1, &plugin->instances) { 807 instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list); 808 for (idx = 0; idx < instance->input.channels.size; idx++) 809 printf("%i:alloc-input%i: data = %p, m_data = %p\n", instance->depth, idx, instance->input.data[idx], instance->input.m_data[idx]); 810 for (idx = 0; idx < instance->output.channels.size; idx++) 811 printf("%i:alloc-output%i: data = %p, m_data = %p\n", instance->depth, idx, instance->output.data[idx], instance->output.m_data[idx]); 812 } 813 } 814 #endif 815 free(pchannels); 816 return 0; 817 } 818 819 static int snd_pcm_ladspa_init(snd_pcm_t *pcm) 820 { 821 snd_pcm_ladspa_t *ladspa = pcm->private_data; 822 int err; 823 824 snd_pcm_ladspa_free_instances(pcm, ladspa, 1); 825 err = snd_pcm_ladspa_allocate_instances(pcm, ladspa); 826 if (err < 0) { 827 snd_pcm_ladspa_free_instances(pcm, ladspa, 1); 828 return err; 829 } 830 err = snd_pcm_ladspa_allocate_memory(pcm, ladspa); 831 if (err < 0) { 832 snd_pcm_ladspa_free_instances(pcm, ladspa, 1); 833 return err; 834 } 835 return 0; 836 } 837 838 static int snd_pcm_ladspa_hw_free(snd_pcm_t *pcm) 839 { 840 snd_pcm_ladspa_t *ladspa = pcm->private_data; 841 842 snd_pcm_ladspa_free_instances(pcm, ladspa, 1); 843 return snd_pcm_generic_hw_free(pcm); 844 } 845 846 static snd_pcm_uframes_t 847 snd_pcm_ladspa_write_areas(snd_pcm_t *pcm, 848 const snd_pcm_channel_area_t *areas, 849 snd_pcm_uframes_t offset, 850 snd_pcm_uframes_t size, 851 const snd_pcm_channel_area_t *slave_areas, 852 snd_pcm_uframes_t slave_offset, 853 snd_pcm_uframes_t *slave_sizep) 854 { 855 snd_pcm_ladspa_t *ladspa = pcm->private_data; 856 snd_pcm_ladspa_instance_t *instance; 857 struct list_head *pos, *pos1; 858 LADSPA_Data *data; 859 unsigned int idx, chn, size1, size2; 860 861 if (size > *slave_sizep) 862 size = *slave_sizep; 863 size2 = size; 864 #if 0 /* no processing - for testing purposes only */ 865 snd_pcm_areas_copy(slave_areas, slave_offset, 866 areas, offset, 867 pcm->channels, size, pcm->format); 868 #else 869 while (size > 0) { 870 size1 = size; 871 if (size1 > ladspa->allocated) 872 size1 = ladspa->allocated; 873 list_for_each(pos, &ladspa->pplugins) { 874 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list); 875 list_for_each(pos1, &plugin->instances) { 876 instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list); 877 for (idx = 0; idx < instance->input.channels.size; idx++) { 878 chn = instance->input.channels.array[idx]; 879 data = instance->input.data[idx]; 880 if (data == NULL) { 881 data = (LADSPA_Data *)((char *)areas[chn].addr + (areas[chn].first / 8)); 882 data += offset; 883 } 884 instance->desc->connect_port(instance->handle, instance->input.ports.array[idx], data); 885 } 886 for (idx = 0; idx < instance->output.channels.size; idx++) { 887 chn = instance->output.channels.array[idx]; 888 data = instance->output.data[idx]; 889 if (data == NULL) { 890 data = (LADSPA_Data *)((char *)slave_areas[chn].addr + (areas[chn].first / 8)); 891 data += slave_offset; 892 } 893 instance->desc->connect_port(instance->handle, instance->output.ports.array[idx], data); 894 } 895 instance->desc->run(instance->handle, size1); 896 } 897 } 898 offset += size1; 899 slave_offset += size1; 900 size -= size1; 901 } 902 #endif 903 *slave_sizep = size2; 904 return size2; 905 } 906 907 static snd_pcm_uframes_t 908 snd_pcm_ladspa_read_areas(snd_pcm_t *pcm, 909 const snd_pcm_channel_area_t *areas, 910 snd_pcm_uframes_t offset, 911 snd_pcm_uframes_t size, 912 const snd_pcm_channel_area_t *slave_areas, 913 snd_pcm_uframes_t slave_offset, 914 snd_pcm_uframes_t *slave_sizep) 915 { 916 snd_pcm_ladspa_t *ladspa = pcm->private_data; 917 snd_pcm_ladspa_instance_t *instance; 918 struct list_head *pos, *pos1; 919 LADSPA_Data *data; 920 unsigned int idx, chn, size1, size2;; 921 922 if (size > *slave_sizep) 923 size = *slave_sizep; 924 size2 = size; 925 #if 0 /* no processing - for testing purposes only */ 926 snd_pcm_areas_copy(areas, offset, 927 slave_areas, slave_offset, 928 pcm->channels, size, pcm->format); 929 #else 930 while (size > 0) { 931 size1 = size; 932 if (size1 > ladspa->allocated) 933 size1 = ladspa->allocated; 934 list_for_each(pos, &ladspa->cplugins) { 935 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list); 936 list_for_each(pos1, &plugin->instances) { 937 instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list); 938 for (idx = 0; idx < instance->input.channels.size; idx++) { 939 chn = instance->input.channels.array[idx]; 940 data = instance->input.data[idx]; 941 if (data == NULL) { 942 data = (LADSPA_Data *)((char *)slave_areas[chn].addr + (areas[chn].first / 8)); 943 data += slave_offset; 944 } 945 instance->desc->connect_port(instance->handle, instance->input.ports.array[idx], data); 946 } 947 for (idx = 0; idx < instance->output.channels.size; idx++) { 948 chn = instance->output.channels.array[idx]; 949 data = instance->output.data[idx]; 950 if (data == NULL) { 951 data = (LADSPA_Data *)((char *)areas[chn].addr + (areas[chn].first / 8)); 952 data += offset; 953 } 954 instance->desc->connect_port(instance->handle, instance->output.ports.array[idx], data); 955 } 956 instance->desc->run(instance->handle, size1); 957 } 958 } 959 offset += size1; 960 slave_offset += size1; 961 size -= size1; 962 } 963 #endif 964 *slave_sizep = size2; 965 return size2; 966 } 967 968 static void snd_pcm_ladspa_dump_direction(snd_pcm_ladspa_plugin_t *plugin, 969 snd_pcm_ladspa_plugin_io_t *io, 970 snd_output_t *out) 971 { 972 unsigned int idx, midx; 973 974 if (io->port_bindings_size == 0) 975 goto __control; 976 snd_output_printf(out, " Audio %s port bindings:\n", io->pdesc == LADSPA_PORT_INPUT ? "input" : "output"); 977 for (idx = 0; idx < io->port_bindings_size; idx++) { 978 if (io->port_bindings[idx] == NO_ASSIGN) 979 snd_output_printf(out, " %i -> NONE\n", idx); 980 else 981 snd_output_printf(out, " %i -> %i\n", idx, io->port_bindings[idx]); 982 } 983 __control: 984 if (io->controls_size == 0) 985 return; 986 snd_output_printf(out, " Control %s port initial values:\n", io->pdesc == LADSPA_PORT_INPUT ? "input" : "output"); 987 for (idx = midx = 0; idx < plugin->desc->PortCount; idx++) { 988 if ((plugin->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_CONTROL)) == (io->pdesc | LADSPA_PORT_CONTROL)) { 989 snd_output_printf(out, " %i \"%s\" = %.8f\n", idx, plugin->desc->PortNames[idx], io->controls[midx]); 990 midx++; 991 } 992 } 993 } 994 995 static void snd_pcm_ladspa_dump_array(snd_output_t *out, 996 snd_pcm_ladspa_array_t *array, 997 snd_pcm_ladspa_plugin_t *plugin) 998 { 999 unsigned int size = array->size; 1000 unsigned int val, idx = 0; 1001 1002 while (size-- > 0) { 1003 if (idx > 0) { 1004 snd_output_putc(out, ','); 1005 snd_output_putc(out, ' '); 1006 } 1007 val = array->array[idx++]; 1008 if (val == NO_ASSIGN) 1009 snd_output_putc(out, '-'); 1010 else 1011 snd_output_printf(out, "%u", val); 1012 if (plugin && val != NO_ASSIGN) 1013 snd_output_printf(out, " \"%s\"", plugin->desc->PortNames[val]); 1014 } 1015 } 1016 1017 static void snd_pcm_ladspa_plugins_dump(struct list_head *list, snd_output_t *out) 1018 { 1019 struct list_head *pos, *pos2; 1020 1021 list_for_each(pos, list) { 1022 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list); 1023 snd_output_printf(out, " Policy: %s\n", plugin->policy == SND_PCM_LADSPA_POLICY_NONE ? "none" : "duplicate"); 1024 snd_output_printf(out, " Filename: %s\n", plugin->filename); 1025 snd_output_printf(out, " Plugin Name: %s\n", plugin->desc->Name); 1026 snd_output_printf(out, " Plugin Label: %s\n", plugin->desc->Label); 1027 snd_output_printf(out, " Plugin Unique ID: %lu\n", plugin->desc->UniqueID); 1028 snd_output_printf(out, " Instances:\n"); 1029 list_for_each(pos2, &plugin->instances) { 1030 snd_pcm_ladspa_instance_t *in = (snd_pcm_ladspa_instance_t *) pos2; 1031 snd_output_printf(out, " Depth: %i\n", in->depth); 1032 snd_output_printf(out, " InChannels: "); 1033 snd_pcm_ladspa_dump_array(out, &in->input.channels, NULL); 1034 snd_output_printf(out, "\n InPorts: "); 1035 snd_pcm_ladspa_dump_array(out, &in->input.ports, plugin); 1036 snd_output_printf(out, "\n OutChannels: "); 1037 snd_pcm_ladspa_dump_array(out, &in->output.channels, NULL); 1038 snd_output_printf(out, "\n OutPorts: "); 1039 snd_pcm_ladspa_dump_array(out, &in->output.ports, plugin); 1040 snd_output_printf(out, "\n"); 1041 } 1042 snd_pcm_ladspa_dump_direction(plugin, &plugin->input, out); 1043 snd_pcm_ladspa_dump_direction(plugin, &plugin->output, out); 1044 } 1045 } 1046 1047 static void snd_pcm_ladspa_dump(snd_pcm_t *pcm, snd_output_t *out) 1048 { 1049 snd_pcm_ladspa_t *ladspa = pcm->private_data; 1050 1051 snd_output_printf(out, "LADSPA PCM\n"); 1052 snd_output_printf(out, " Playback:\n"); 1053 snd_pcm_ladspa_plugins_dump(&ladspa->pplugins, out); 1054 snd_output_printf(out, " Capture:\n"); 1055 snd_pcm_ladspa_plugins_dump(&ladspa->cplugins, out); 1056 if (pcm->setup) { 1057 snd_output_printf(out, "Its setup is:\n"); 1058 snd_pcm_dump_setup(pcm, out); 1059 } 1060 snd_output_printf(out, "Slave: "); 1061 snd_pcm_dump(ladspa->plug.gen.slave, out); 1062 } 1063 1064 static const snd_pcm_ops_t snd_pcm_ladspa_ops = { 1065 .close = snd_pcm_ladspa_close, 1066 .info = snd_pcm_generic_info, 1067 .hw_refine = snd_pcm_ladspa_hw_refine, 1068 .hw_params = snd_pcm_ladspa_hw_params, 1069 .hw_free = snd_pcm_ladspa_hw_free, 1070 .sw_params = snd_pcm_generic_sw_params, 1071 .channel_info = snd_pcm_generic_channel_info, 1072 .dump = snd_pcm_ladspa_dump, 1073 .nonblock = snd_pcm_generic_nonblock, 1074 .async = snd_pcm_generic_async, 1075 .mmap = snd_pcm_generic_mmap, 1076 .munmap = snd_pcm_generic_munmap, 1077 }; 1078 1079 static int snd_pcm_ladspa_check_file(snd_pcm_ladspa_plugin_t * const plugin, 1080 const char *filename, 1081 const char *label, 1082 const unsigned long ladspa_id) 1083 { 1084 void *handle; 1085 1086 assert(filename); 1087 handle = dlopen(filename, RTLD_LAZY); 1088 if (handle) { 1089 LADSPA_Descriptor_Function fcn = (LADSPA_Descriptor_Function)dlsym(handle, "ladspa_descriptor"); 1090 if (fcn) { 1091 long idx; 1092 const LADSPA_Descriptor *d; 1093 for (idx = 0; (d = fcn(idx)) != NULL; idx++) { 1094 /* 1095 * avoid locale problems - see ALSA bug#1553 1096 */ 1097 #if 0 1098 if (strcmp(label, d->Label)) 1099 continue; 1100 #else 1101 char *labellocale; 1102 struct lconv *lc; 1103 if (label != NULL) { 1104 lc = localeconv (); 1105 labellocale = malloc (strlen (label) + 1); 1106 if (labellocale == NULL) { 1107 dlclose(handle); 1108 return -ENOMEM; 1109 } 1110 strcpy (labellocale, label); 1111 if (strrchr(labellocale, '.')) 1112 *strrchr (labellocale, '.') = *lc->decimal_point; 1113 if (strcmp(label, d->Label) && strcmp(labellocale, d->Label)) { 1114 free(labellocale); 1115 continue; 1116 } 1117 free (labellocale); 1118 } 1119 #endif 1120 if (ladspa_id > 0 && d->UniqueID != ladspa_id) 1121 continue; 1122 plugin->filename = strdup(filename); 1123 if (plugin->filename == NULL) { 1124 dlclose(handle); 1125 return -ENOMEM; 1126 } 1127 plugin->dl_handle = handle; 1128 plugin->desc = d; 1129 return 1; 1130 } 1131 } 1132 dlclose(handle); 1133 } 1134 return -ENOENT; 1135 } 1136 1137 static int snd_pcm_ladspa_check_dir(snd_pcm_ladspa_plugin_t * const plugin, 1138 const char *path, 1139 const char *label, 1140 const unsigned long ladspa_id) 1141 { 1142 DIR *dir; 1143 struct dirent * dirent; 1144 int len = strlen(path), err; 1145 int need_slash; 1146 char *filename; 1147 1148 if (len < 1) 1149 return 0; 1150 need_slash = path[len - 1] != '/'; 1151 1152 dir = opendir(path); 1153 if (!dir) 1154 return -ENOENT; 1155 1156 while (1) { 1157 dirent = readdir(dir); 1158 if (!dirent) { 1159 closedir(dir); 1160 return 0; 1161 } 1162 1163 filename = malloc(len + strlen(dirent->d_name) + 1 + need_slash); 1164 if (filename == NULL) { 1165 closedir(dir); 1166 return -ENOMEM; 1167 } 1168 strcpy(filename, path); 1169 if (need_slash) 1170 strcat(filename, "/"); 1171 strcat(filename, dirent->d_name); 1172 err = snd_pcm_ladspa_check_file(plugin, filename, label, ladspa_id); 1173 free(filename); 1174 if (err < 0 && err != -ENOENT) { 1175 closedir(dir); 1176 return err; 1177 } 1178 if (err > 0) { 1179 closedir(dir); 1180 return 1; 1181 } 1182 } 1183 /* never reached */ 1184 return 0; 1185 } 1186 1187 static int snd_pcm_ladspa_look_for_plugin(snd_pcm_ladspa_plugin_t * const plugin, 1188 const char *path, 1189 const char *label, 1190 const long ladspa_id) 1191 { 1192 const char *c; 1193 size_t l; 1194 int err; 1195 1196 for (c = path; (l = strcspn(c, ": ")) > 0; ) { 1197 char name[l + 1]; 1198 char *fullpath; 1199 memcpy(name, c, l); 1200 name[l] = 0; 1201 err = snd_user_file(name, &fullpath); 1202 if (err < 0) 1203 return err; 1204 err = snd_pcm_ladspa_check_dir(plugin, fullpath, label, ladspa_id); 1205 free(fullpath); 1206 if (err < 0) 1207 return err; 1208 if (err > 0) 1209 return 0; 1210 c += l; 1211 if (!*c) 1212 break; 1213 c++; 1214 } 1215 return -ENOENT; 1216 } 1217 1218 static int snd_pcm_ladspa_add_default_controls(snd_pcm_ladspa_plugin_t *lplug, 1219 snd_pcm_ladspa_plugin_io_t *io) 1220 { 1221 unsigned int count = 0; 1222 LADSPA_Data *array; 1223 unsigned char *initialized; 1224 unsigned long idx; 1225 1226 for (idx = 0; idx < lplug->desc->PortCount; idx++) 1227 if ((lplug->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_CONTROL)) == (io->pdesc | LADSPA_PORT_CONTROL)) 1228 count++; 1229 array = (LADSPA_Data *)calloc(count, sizeof(LADSPA_Data)); 1230 if (!array) 1231 return -ENOMEM; 1232 initialized = (unsigned char *)calloc(count, sizeof(unsigned char)); 1233 if (!initialized) { 1234 free(array); 1235 return -ENOMEM; 1236 } 1237 io->controls_size = count; 1238 io->controls_initialized = initialized; 1239 io->controls = array; 1240 1241 return 0; 1242 } 1243 1244 static int snd_pcm_ladspa_parse_controls(snd_pcm_ladspa_plugin_t *lplug, 1245 snd_pcm_ladspa_plugin_io_t *io, 1246 snd_config_t *controls) 1247 { 1248 snd_config_iterator_t i, next; 1249 int err; 1250 1251 if (snd_config_get_type(controls) != SND_CONFIG_TYPE_COMPOUND) { 1252 SNDERR("controls definition must be a compound"); 1253 return -EINVAL; 1254 } 1255 1256 snd_config_for_each(i, next, controls) { 1257 snd_config_t *n = snd_config_iterator_entry(i); 1258 const char *id; 1259 long lval; 1260 unsigned int port, uval; 1261 double dval; 1262 if (snd_config_get_id(n, &id) < 0) 1263 continue; 1264 err = safe_strtol(id, &lval); 1265 if (err >= 0) { 1266 err = snd_pcm_ladspa_find_port(&port, lplug, io->pdesc | LADSPA_PORT_CONTROL, lval); 1267 } else { 1268 err = snd_pcm_ladspa_find_sport(&port, lplug, io->pdesc | LADSPA_PORT_CONTROL, id); 1269 } 1270 if (err < 0) { 1271 SNDERR("Unable to find an control port (%s)", id); 1272 return err; 1273 } 1274 if (snd_config_get_ireal(n, &dval) < 0) { 1275 SNDERR("Control port %s has not an float or integer value", id); 1276 return err; 1277 } 1278 err = snd_pcm_ladspa_find_port_idx(&uval, lplug, io->pdesc | LADSPA_PORT_CONTROL, port); 1279 if (err < 0) { 1280 SNDERR("internal error"); 1281 return err; 1282 } 1283 io->controls_initialized[uval] = 1; 1284 io->controls[uval] = (LADSPA_Data)dval; 1285 } 1286 1287 return 0; 1288 } 1289 1290 static int snd_pcm_ladspa_parse_bindings(snd_pcm_ladspa_plugin_t *lplug, 1291 snd_pcm_ladspa_plugin_io_t *io, 1292 snd_config_t *bindings) 1293 { 1294 unsigned int count = 0; 1295 unsigned int *array; 1296 snd_config_iterator_t i, next; 1297 int err; 1298 1299 if (snd_config_get_type(bindings) != SND_CONFIG_TYPE_COMPOUND) { 1300 SNDERR("bindings definition must be a compound"); 1301 return -EINVAL; 1302 } 1303 snd_config_for_each(i, next, bindings) { 1304 snd_config_t *n = snd_config_iterator_entry(i); 1305 const char *id; 1306 long channel; 1307 if (snd_config_get_id(n, &id) < 0) 1308 continue; 1309 err = safe_strtol(id, &channel); 1310 if (err < 0 || channel < 0) { 1311 SNDERR("Invalid channel number: %s", id); 1312 return -EINVAL; 1313 } 1314 if (lplug->policy == SND_PCM_LADSPA_POLICY_DUPLICATE && channel > 0) { 1315 SNDERR("Wrong channel specification for duplicate policy"); 1316 return -EINVAL; 1317 } 1318 if (count < (unsigned int)(channel + 1)) 1319 count = (unsigned int)(channel + 1); 1320 } 1321 if (count > 0) { 1322 array = (unsigned int *)calloc(count, sizeof(unsigned int)); 1323 if (! array) 1324 return -ENOMEM; 1325 memset(array, 0xff, count * sizeof(unsigned int)); 1326 io->port_bindings_size = count; 1327 io->port_bindings = array; 1328 snd_config_for_each(i, next, bindings) { 1329 snd_config_t *n = snd_config_iterator_entry(i); 1330 const char *id, *sport; 1331 long channel, port; 1332 if (snd_config_get_id(n, &id) < 0) 1333 continue; 1334 err = safe_strtol(id, &channel); 1335 if (err < 0 || channel < 0) { 1336 assert(0); /* should never happen */ 1337 return -EINVAL; 1338 } 1339 err = snd_config_get_integer(n, &port); 1340 if (err >= 0) { 1341 err = snd_pcm_ladspa_find_port(&array[channel], lplug, io->pdesc | LADSPA_PORT_AUDIO, port); 1342 if (err < 0) { 1343 SNDERR("Unable to find an audio port (%li) for channel %s", port, id); 1344 return err; 1345 } 1346 continue; 1347 } 1348 err = snd_config_get_string(n, &sport); 1349 if (err < 0) { 1350 SNDERR("Invalid LADSPA port field type for %s", id); 1351 return -EINVAL; 1352 } 1353 err = snd_pcm_ladspa_find_sport(&array[channel], lplug, io->pdesc | LADSPA_PORT_AUDIO, sport); 1354 if (err < 0) { 1355 SNDERR("Unable to find an audio port (%s) for channel %s", sport, id); 1356 return err; 1357 } 1358 } 1359 } 1360 1361 return 0; 1362 } 1363 1364 static int snd_pcm_ladspa_parse_ioconfig(snd_pcm_ladspa_plugin_t *lplug, 1365 snd_pcm_ladspa_plugin_io_t *io, 1366 snd_config_t *conf) 1367 { 1368 snd_config_iterator_t i, next; 1369 snd_config_t *bindings = NULL, *controls = NULL; 1370 int err; 1371 1372 /* always add default controls for both input and output */ 1373 err = snd_pcm_ladspa_add_default_controls(lplug, io); 1374 if (err < 0) { 1375 SNDERR("error adding default controls"); 1376 return err; 1377 } 1378 1379 if (conf == NULL) { 1380 return 0; 1381 } 1382 1383 if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) { 1384 SNDERR("input or output definition must be a compound"); 1385 return -EINVAL; 1386 } 1387 snd_config_for_each(i, next, conf) { 1388 snd_config_t *n = snd_config_iterator_entry(i); 1389 const char *id; 1390 if (snd_config_get_id(n, &id) < 0) 1391 continue; 1392 if (strcmp(id, "bindings") == 0) { 1393 bindings = n; 1394 continue; 1395 } 1396 if (strcmp(id, "controls") == 0) { 1397 controls = n; 1398 continue; 1399 } 1400 } 1401 1402 /* ignore values of parameters for output controls */ 1403 if (controls && !(io->pdesc & LADSPA_PORT_OUTPUT)) { 1404 err = snd_pcm_ladspa_parse_controls(lplug, io, controls); 1405 if (err < 0) 1406 return err; 1407 } 1408 1409 if (bindings) { 1410 err = snd_pcm_ladspa_parse_bindings(lplug, io, bindings); 1411 if (err < 0) 1412 return err; 1413 } 1414 1415 1416 return 0; 1417 } 1418 1419 static int snd_pcm_ladspa_add_plugin(struct list_head *list, 1420 const char *path, 1421 snd_config_t *plugin, 1422 int reverse) 1423 { 1424 snd_config_iterator_t i, next; 1425 const char *label = NULL, *filename = NULL; 1426 long ladspa_id = 0; 1427 int err; 1428 snd_pcm_ladspa_plugin_t *lplug; 1429 snd_pcm_ladspa_policy_t policy = SND_PCM_LADSPA_POLICY_DUPLICATE; 1430 snd_config_t *input = NULL, *output = NULL; 1431 1432 snd_config_for_each(i, next, plugin) { 1433 snd_config_t *n = snd_config_iterator_entry(i); 1434 const char *id; 1435 if (snd_config_get_id(n, &id) < 0) 1436 continue; 1437 if (strcmp(id, "label") == 0) { 1438 err = snd_config_get_string(n, &label); 1439 if (err < 0) 1440 return err; 1441 continue; 1442 } 1443 if (strcmp(id, "id") == 0) { 1444 err = snd_config_get_integer(n, &ladspa_id); 1445 if (err < 0) 1446 return err; 1447 continue; 1448 } 1449 if (strcmp(id, "filename") == 0) { 1450 err = snd_config_get_string(n, &filename); 1451 if (err < 0) 1452 return err; 1453 continue; 1454 } 1455 if (strcmp(id, "input") == 0) { 1456 input = n; 1457 continue; 1458 } 1459 if (strcmp(id, "output") == 0) { 1460 output = n; 1461 continue; 1462 } 1463 if (strcmp(id, "policy") == 0) { 1464 const char *str; 1465 err = snd_config_get_string(n, &str); 1466 if (err < 0) { 1467 SNDERR("policy field must be a string"); 1468 return err; 1469 } 1470 if (strcmp(str, "none") == 0) 1471 policy = SND_PCM_LADSPA_POLICY_NONE; 1472 else if (strcmp(str, "duplicate") == 0) 1473 policy = SND_PCM_LADSPA_POLICY_DUPLICATE; 1474 else { 1475 SNDERR("unknown policy definition"); 1476 return -EINVAL; 1477 } 1478 continue; 1479 } 1480 } 1481 if (label == NULL && ladspa_id <= 0) { 1482 SNDERR("no plugin label or id"); 1483 return -EINVAL; 1484 } 1485 lplug = (snd_pcm_ladspa_plugin_t *)calloc(1, sizeof(snd_pcm_ladspa_plugin_t)); 1486 if (lplug == NULL) 1487 return -ENOMEM; 1488 lplug->policy = policy; 1489 lplug->input.pdesc = LADSPA_PORT_INPUT; 1490 lplug->output.pdesc = LADSPA_PORT_OUTPUT; 1491 INIT_LIST_HEAD(&lplug->instances); 1492 if (filename) { 1493 err = snd_pcm_ladspa_check_file(lplug, filename, label, ladspa_id); 1494 if (err < 0) { 1495 SNDERR("Unable to load plugin '%s' ID %li, filename '%s'", label, ladspa_id, filename); 1496 free(lplug); 1497 return err; 1498 } 1499 } else { 1500 err = snd_pcm_ladspa_look_for_plugin(lplug, path, label, ladspa_id); 1501 if (err < 0) { 1502 SNDERR("Unable to find or load plugin '%s' ID %li, path '%s'", label, ladspa_id, path); 1503 free(lplug); 1504 return err; 1505 } 1506 } 1507 if (!reverse) { 1508 list_add_tail(&lplug->list, list); 1509 } else { 1510 list_add(&lplug->list, list); 1511 } 1512 err = snd_pcm_ladspa_parse_ioconfig(lplug, &lplug->input, input); 1513 if (err < 0) 1514 return err; 1515 err = snd_pcm_ladspa_parse_ioconfig(lplug, &lplug->output, output); 1516 if (err < 0) 1517 return err; 1518 return 0; 1519 } 1520 1521 static int snd_pcm_ladspa_build_plugins(struct list_head *list, 1522 const char *path, 1523 snd_config_t *plugins, 1524 int reverse) 1525 { 1526 snd_config_iterator_t i, next; 1527 int idx = 0, hit, err; 1528 1529 if (plugins == NULL) /* nothing TODO */ 1530 return 0; 1531 if (snd_config_get_type(plugins) != SND_CONFIG_TYPE_COMPOUND) { 1532 SNDERR("plugins must be defined inside a compound"); 1533 return -EINVAL; 1534 } 1535 do { 1536 hit = 0; 1537 snd_config_for_each(i, next, plugins) { 1538 snd_config_t *n = snd_config_iterator_entry(i); 1539 const char *id; 1540 long i; 1541 if (snd_config_get_id(n, &id) < 0) 1542 continue; 1543 err = safe_strtol(id, &i); 1544 if (err < 0) { 1545 SNDERR("id of field %s is not an integer", id); 1546 return err; 1547 } 1548 if (i == idx) { 1549 idx++; 1550 err = snd_pcm_ladspa_add_plugin(list, path, n, reverse); 1551 if (err < 0) 1552 return err; 1553 hit = 1; 1554 } 1555 } 1556 } while (hit); 1557 if (list_empty(list)) { 1558 SNDERR("empty plugin list is not accepted"); 1559 return -EINVAL; 1560 } 1561 return 0; 1562 } 1563 1564 /** 1565 * \brief Creates a new LADSPA<->ALSA Plugin 1566 * \param pcmp Returns created PCM handle 1567 * \param name Name of PCM 1568 * \param ladspa_path The path for LADSPA plugins 1569 * \param channels Force input channel count to LADSPA plugin chain, 0 = no force (auto) 1570 * \param ladspa_pplugins The playback configuration 1571 * \param ladspa_cplugins The capture configuration 1572 * \param slave Slave PCM handle 1573 * \param close_slave When set, the slave PCM handle is closed with copy PCM 1574 * \retval zero on success otherwise a negative error code 1575 * \warning Using of this function might be dangerous in the sense 1576 * of compatibility reasons. The prototype might be freely 1577 * changed in future. 1578 */ 1579 int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name, 1580 const char *ladspa_path, 1581 unsigned int channels, 1582 snd_config_t *ladspa_pplugins, 1583 snd_config_t *ladspa_cplugins, 1584 snd_pcm_t *slave, int close_slave) 1585 { 1586 snd_pcm_t *pcm; 1587 snd_pcm_ladspa_t *ladspa; 1588 int err, reverse = 0; 1589 1590 assert(pcmp && (ladspa_pplugins || ladspa_cplugins) && slave); 1591 1592 if (!ladspa_path && !(ladspa_path = getenv("LADSPA_PATH"))) 1593 return -ENOENT; 1594 ladspa = calloc(1, sizeof(snd_pcm_ladspa_t)); 1595 if (!ladspa) 1596 return -ENOMEM; 1597 snd_pcm_plugin_init(&ladspa->plug); 1598 ladspa->plug.init = snd_pcm_ladspa_init; 1599 ladspa->plug.read = snd_pcm_ladspa_read_areas; 1600 ladspa->plug.write = snd_pcm_ladspa_write_areas; 1601 ladspa->plug.undo_read = snd_pcm_plugin_undo_read_generic; 1602 ladspa->plug.undo_write = snd_pcm_plugin_undo_write_generic; 1603 ladspa->plug.gen.slave = slave; 1604 ladspa->plug.gen.close_slave = close_slave; 1605 1606 INIT_LIST_HEAD(&ladspa->pplugins); 1607 INIT_LIST_HEAD(&ladspa->cplugins); 1608 ladspa->channels = channels; 1609 1610 if (slave->stream == SND_PCM_STREAM_PLAYBACK) { 1611 err = snd_pcm_ladspa_build_plugins(&ladspa->pplugins, ladspa_path, ladspa_pplugins, reverse); 1612 if (err < 0) { 1613 snd_pcm_ladspa_free(ladspa); 1614 return err; 1615 } 1616 } 1617 if (slave->stream == SND_PCM_STREAM_CAPTURE) { 1618 if (ladspa_cplugins == ladspa_pplugins) 1619 reverse = 1; 1620 err = snd_pcm_ladspa_build_plugins(&ladspa->cplugins, ladspa_path, ladspa_cplugins, reverse); 1621 if (err < 0) { 1622 snd_pcm_ladspa_free(ladspa); 1623 return err; 1624 } 1625 } 1626 1627 err = snd_pcm_new(&pcm, SND_PCM_TYPE_LADSPA, name, slave->stream, slave->mode); 1628 if (err < 0) { 1629 snd_pcm_ladspa_free(ladspa); 1630 return err; 1631 } 1632 pcm->ops = &snd_pcm_ladspa_ops; 1633 pcm->fast_ops = &snd_pcm_plugin_fast_ops; 1634 pcm->private_data = ladspa; 1635 pcm->poll_fd = slave->poll_fd; 1636 pcm->poll_events = slave->poll_events; 1637 pcm->monotonic = slave->monotonic; 1638 snd_pcm_set_hw_ptr(pcm, &ladspa->plug.hw_ptr, -1, 0); 1639 snd_pcm_set_appl_ptr(pcm, &ladspa->plug.appl_ptr, -1, 0); 1640 *pcmp = pcm; 1641 1642 return 0; 1643 } 1644 1645 /*! \page pcm_plugins 1646 1647 \section pcm_plugins_ladpsa Plugin: LADSPA <-> ALSA 1648 1649 This plugin allows to apply a set of LADPSA plugins. 1650 The input and output format is always #SND_PCM_FORMAT_FLOAT (note: this type 1651 can be either little or big-endian depending on architecture). 1652 1653 The policy duplicate means that there must be only one binding definition for 1654 channel zero. This definition is automatically duplicated for all channels. 1655 If the LADSPA plugin has multiple audio inputs or outputs the policy duplicate 1656 is automatically switched to policy none. 1657 1658 The plugin serialization works as expected. You can eventually use more 1659 channels (inputs / outputs) inside the LADPSA plugin chain than processed 1660 in the ALSA plugin chain. If ALSA channel does not exist for given LADSPA 1661 input audio port, zero samples are given to this LADSPA port. On the output 1662 side (ALSA next plugin input), the valid channels are checked, too. 1663 If specific ALSA channel does not exist, the LADSPA output port is 1664 connected to a dummy sample area. 1665 1666 Instances of LADSPA plugins are created dynamically. 1667 1668 \code 1669 pcm.name { 1670 type ladspa # ALSA<->LADSPA PCM 1671 slave STR # Slave name 1672 # or 1673 slave { # Slave definition 1674 pcm STR # Slave PCM name 1675 # or 1676 pcm { } # Slave PCM definition 1677 } 1678 [channels INT] # count input channels (input to LADSPA plugin chain) 1679 [path STR] # Path (directory) with LADSPA plugins 1680 plugins | # Definition for both directions 1681 playback_plugins | # Definition for playback direction 1682 capture_plugins { # Definition for capture direction 1683 N { # Configuration for LADPSA plugin N 1684 [id INT] # LADSPA plugin ID (for example 1043) 1685 [label STR] # LADSPA plugin label (for example 'delay_5s') 1686 [filename STR] # Full filename of .so library with LADSPA plugin code 1687 [policy STR] # Policy can be 'none' or 'duplicate' 1688 input | output { 1689 bindings { 1690 C INT or STR # C - channel, INT - audio port index, STR - audio port name 1691 } 1692 controls { 1693 # valid only in the input block 1694 I INT or REAL # I - control port index, INT or REAL - control value 1695 # or 1696 STR INT or REAL # STR - control port name, INT or REAL - control value 1697 } 1698 } 1699 } 1700 } 1701 } 1702 \endcode 1703 1704 \subsection pcm_plugins_ladspa_funcref Function reference 1705 1706 <UL> 1707 <LI>snd_pcm_ladspa_open() 1708 <LI>_snd_pcm_ladspa_open() 1709 </UL> 1710 1711 */ 1712 1713 /** 1714 * \brief Creates a new LADSPA<->ALSA PCM 1715 * \param pcmp Returns created PCM handle 1716 * \param name Name of PCM 1717 * \param root Root configuration node 1718 * \param conf Configuration node with LADSPA<->ALSA PCM description 1719 * \param stream Stream type 1720 * \param mode Stream mode 1721 * \retval zero on success otherwise a negative error code 1722 * \warning Using of this function might be dangerous in the sense 1723 * of compatibility reasons. The prototype might be freely 1724 * changed in future. 1725 */ 1726 int _snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name, 1727 snd_config_t *root, snd_config_t *conf, 1728 snd_pcm_stream_t stream, int mode) 1729 { 1730 snd_config_iterator_t i, next; 1731 int err; 1732 snd_pcm_t *spcm; 1733 snd_config_t *slave = NULL, *sconf; 1734 const char *path = NULL; 1735 long channels = 0; 1736 snd_config_t *plugins = NULL, *pplugins = NULL, *cplugins = NULL; 1737 snd_config_for_each(i, next, conf) { 1738 snd_config_t *n = snd_config_iterator_entry(i); 1739 const char *id; 1740 if (snd_config_get_id(n, &id) < 0) 1741 continue; 1742 if (snd_pcm_conf_generic_id(id)) 1743 continue; 1744 if (strcmp(id, "slave") == 0) { 1745 slave = n; 1746 continue; 1747 } 1748 if (strcmp(id, "path") == 0) { 1749 snd_config_get_string(n, &path); 1750 continue; 1751 } 1752 if (strcmp(id, "channels") == 0) { 1753 snd_config_get_integer(n, &channels); 1754 if (channels > 1024) 1755 channels = 1024; 1756 if (channels < 0) 1757 channels = 0; 1758 continue; 1759 } 1760 if (strcmp(id, "plugins") == 0) { 1761 plugins = n; 1762 continue; 1763 } 1764 if (strcmp(id, "playback_plugins") == 0) { 1765 pplugins = n; 1766 continue; 1767 } 1768 if (strcmp(id, "capture_plugins") == 0) { 1769 cplugins = n; 1770 continue; 1771 } 1772 SNDERR("Unknown field %s", id); 1773 return -EINVAL; 1774 } 1775 if (!slave) { 1776 SNDERR("slave is not defined"); 1777 return -EINVAL; 1778 } 1779 if (plugins) { 1780 if (pplugins || cplugins) { 1781 SNDERR("'plugins' definition cannot be combined with 'playback_plugins' or 'capture_plugins'"); 1782 return -EINVAL; 1783 } 1784 pplugins = plugins; 1785 cplugins = plugins; 1786 } 1787 err = snd_pcm_slave_conf(root, slave, &sconf, 0); 1788 if (err < 0) 1789 return err; 1790 err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode, conf); 1791 snd_config_delete(sconf); 1792 if (err < 0) 1793 return err; 1794 err = snd_pcm_ladspa_open(pcmp, name, path, channels, pplugins, cplugins, spcm, 1); 1795 if (err < 0) 1796 snd_pcm_close(spcm); 1797 return err; 1798 } 1799 #ifndef DOC_HIDDEN 1800 SND_DLSYM_BUILD_VERSION(_snd_pcm_ladspa_open, SND_PCM_DLSYM_VERSION); 1801 #endif 1802