2 * \file pcm/pcm_ladspa.c
4 * \brief ALSA Plugin <-> LADSPA Plugin Interface
5 * \author Jaroslav Kysela <perex@perex.cz>
6 * \author Jaroslav Kysela <perex@perex.cz>
10 * PCM - LADSPA integration plugin
11 * Copyright (c) 2001-2006 by Jaroslav Kysela <perex@perex.cz>
12 * Copyright (c) 2005 by Jaroslav Kysela <perex@perex.cz>
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.
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.
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
30 * perex@perex.cz 2005/12/13
31 * The LADSPA plugin rewrite was sponsored by MediaNet AG
32 * http://www.medianet.ag
38 #include "pcm_local.h"
39 #include "pcm_plugin.h"
44 /* entry for static linking */
45 const char *_snd_module_pcm_ladspa = "";
50 #define NO_ASSIGN 0xffffffff
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;
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 */
71 } snd_pcm_ladspa_array_t;
74 snd_pcm_ladspa_array_t channels;
75 snd_pcm_ladspa_array_t ports;
78 } snd_pcm_ladspa_eps_t;
80 typedef struct snd_pcm_ladspa_instance {
81 struct list_head list;
82 const LADSPA_Descriptor *desc;
83 LADSPA_Handle *handle;
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;
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;
101 struct list_head list;
102 snd_pcm_ladspa_policy_t policy;
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;
111 #endif /* DOC_HIDDEN */
113 static unsigned int snd_pcm_ladspa_count_ports(snd_pcm_ladspa_plugin_t *lplug,
114 LADSPA_PortDescriptor pdesc)
116 unsigned int res = 0, idx;
117 for (idx = 0; idx < lplug->desc->PortCount; idx++) {
118 if ((lplug->desc->PortDescriptors[idx] & pdesc) == pdesc)
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)
131 for (idx = 0; idx < lplug->desc->PortCount; idx++)
132 if ((lplug->desc->PortDescriptors[idx] & pdesc) == pdesc) {
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)
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)) {
158 static int snd_pcm_ladspa_find_port_idx(unsigned int *res,
159 snd_pcm_ladspa_plugin_t *lplug,
160 LADSPA_PortDescriptor pdesc,
166 if (port >= lplug->desc->PortCount)
168 for (idx = 0; idx < port; idx++)
169 if ((lplug->desc->PortDescriptors[idx] & pdesc) == pdesc)
175 static void snd_pcm_ladspa_free_io(snd_pcm_ladspa_plugin_io_t *io)
178 free(io->controls_initialized);
181 static void snd_pcm_ladspa_free_plugins(struct list_head *plugins)
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);
195 static void snd_pcm_ladspa_free(snd_pcm_ladspa_t *ladspa)
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;
205 ladspa->allocated = 0;
208 static int snd_pcm_ladspa_close(snd_pcm_t *pcm)
210 snd_pcm_ladspa_t *ladspa = pcm->private_data;
212 snd_pcm_ladspa_free(ladspa);
213 return snd_pcm_generic_close(pcm);
216 static int snd_pcm_ladspa_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params)
218 snd_pcm_ladspa_t *ladspa = pcm->private_data;
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,
225 err = _snd_pcm_hw_params_set_format(params, SND_PCM_FORMAT_FLOAT);
228 err = _snd_pcm_hw_params_set_subformat(params, SND_PCM_SUBFORMAT_STD);
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);
236 params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
240 static int snd_pcm_ladspa_hw_refine_sprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *sparams)
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,
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);
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)
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);
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)
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);
290 static int snd_pcm_ladspa_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
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);
300 static int snd_pcm_ladspa_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
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);
313 static void snd_pcm_ladspa_free_eps(snd_pcm_ladspa_eps_t *eps)
315 free(eps->channels.array);
316 free(eps->ports.array);
319 static void snd_pcm_ladspa_free_instances(snd_pcm_t *pcm, snd_pcm_ladspa_t *ladspa, int cleanup)
321 struct list_head *list, *pos, *pos1, *next1;
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);
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);
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);
344 free(instance->input.data);
345 free(instance->output.data);
346 list_del(&(instance->list));
347 snd_pcm_ladspa_free_eps(&instance->input);
348 snd_pcm_ladspa_free_eps(&instance->output);
351 if (plugin->desc->activate)
352 plugin->desc->activate(instance->handle);
356 assert(list_empty(&plugin->instances));
361 static int snd_pcm_ladspa_add_to_carray(snd_pcm_ladspa_array_t *array,
365 unsigned int *narray;
368 if (idx >= array->size) {
369 narray = realloc(array->array, sizeof(unsigned int) * (idx + 1));
372 for (idx1 = array->size; idx1 < idx; idx1++)
373 narray[idx1] = NO_ASSIGN;
374 array->array = narray;
375 array->size = idx + 1;
376 array->array[idx] = val;
379 if (array->array[idx] == NO_ASSIGN)
380 array->array[idx] = val;
386 static int snd_pcm_ladspa_add_to_array(snd_pcm_ladspa_array_t *array,
390 unsigned int *narray;
393 if (idx >= array->size) {
394 narray = realloc(array->array, sizeof(unsigned int) * (idx + 1));
397 for (idx1 = array->size; idx1 < idx; idx1++)
398 narray[idx1] = NO_ASSIGN;
399 array->array = narray;
400 array->size = idx + 1;
402 array->array[idx] = val;
406 static int snd_pcm_ladspa_connect_plugin1(snd_pcm_ladspa_plugin_t *plugin,
407 snd_pcm_ladspa_plugin_io_t *io,
408 snd_pcm_ladspa_eps_t *eps)
410 unsigned int port, channels, idx, idx1;
413 assert(plugin->policy == SND_PCM_LADSPA_POLICY_NONE);
414 channels = io->port_bindings_size > 0 ?
415 io->port_bindings_size :
416 snd_pcm_ladspa_count_ports(plugin, io->pdesc | LADSPA_PORT_AUDIO);
417 for (idx = idx1 = 0; idx < channels; idx++) {
418 if (io->port_bindings_size > 0)
419 port = io->port_bindings[idx];
421 err = snd_pcm_ladspa_find_port(&port, plugin, io->pdesc | LADSPA_PORT_AUDIO, idx);
423 SNDERR("unable to find audio %s port %u plugin '%s'", io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", idx, plugin->desc->Name);
427 if (port == NO_ASSIGN)
429 err = snd_pcm_ladspa_add_to_carray(&eps->channels, idx1, idx);
431 SNDERR("unable to add channel %u for audio %s plugin '%s'", idx, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name);
434 err = snd_pcm_ladspa_add_to_array(&eps->ports, idx1, port);
436 SNDERR("unable to add port %u for audio %s plugin '%s'", port, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name);
444 static int snd_pcm_ladspa_connect_plugin(snd_pcm_ladspa_plugin_t *plugin,
445 snd_pcm_ladspa_instance_t *instance)
449 err = snd_pcm_ladspa_connect_plugin1(plugin, &plugin->input, &instance->input);
452 err = snd_pcm_ladspa_connect_plugin1(plugin, &plugin->output, &instance->output);
458 static int snd_pcm_ladspa_connect_plugin_duplicate1(snd_pcm_ladspa_plugin_t *plugin,
459 snd_pcm_ladspa_plugin_io_t *io,
460 snd_pcm_ladspa_eps_t *eps,
466 assert(plugin->policy == SND_PCM_LADSPA_POLICY_DUPLICATE);
467 if (io->port_bindings_size > 0) {
468 port = io->port_bindings[0];
470 err = snd_pcm_ladspa_find_port(&port, plugin, io->pdesc | LADSPA_PORT_AUDIO, 0);
472 SNDERR("unable to find audio %s port %u plugin '%s'", io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", (unsigned int)0, plugin->desc->Name);
476 err = snd_pcm_ladspa_add_to_carray(&eps->channels, 0, idx);
478 SNDERR("unable to add channel %u for audio %s plugin '%s'", idx, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name);
481 err = snd_pcm_ladspa_add_to_array(&eps->ports, 0, port);
483 SNDERR("unable to add port %u for audio %s plugin '%s'", port, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name);
489 static int snd_pcm_ladspa_connect_plugin_duplicate(snd_pcm_ladspa_plugin_t *plugin,
490 snd_pcm_ladspa_plugin_io_t *in_io,
491 snd_pcm_ladspa_plugin_io_t *out_io,
492 snd_pcm_ladspa_instance_t *instance,
497 err = snd_pcm_ladspa_connect_plugin_duplicate1(plugin, in_io, &instance->input, idx);
500 err = snd_pcm_ladspa_connect_plugin_duplicate1(plugin, out_io, &instance->output, idx);
506 static void snd_pcm_ladspa_get_default_cvalue(const LADSPA_Descriptor * desc, unsigned int port, LADSPA_Data *val)
508 LADSPA_PortRangeHintDescriptor hdesc;
510 hdesc = desc->PortRangeHints[port].HintDescriptor;
511 switch (hdesc & LADSPA_HINT_DEFAULT_MASK) {
512 case LADSPA_HINT_DEFAULT_MINIMUM:
513 *val = desc->PortRangeHints[port].LowerBound;
515 case LADSPA_HINT_DEFAULT_LOW:
516 if (LADSPA_IS_HINT_LOGARITHMIC(hdesc)) {
517 *val = exp(log(desc->PortRangeHints[port].LowerBound)
519 + log(desc->PortRangeHints[port].UpperBound)
522 *val = (desc->PortRangeHints[port].LowerBound * 0.75) +
523 (desc->PortRangeHints[port].UpperBound * 0.25);
526 case LADSPA_HINT_DEFAULT_MIDDLE:
527 if (LADSPA_IS_HINT_LOGARITHMIC(hdesc)) {
528 *val = sqrt(desc->PortRangeHints[port].LowerBound *
529 desc->PortRangeHints[port].UpperBound);
532 (desc->PortRangeHints[port].LowerBound +
533 desc->PortRangeHints[port].UpperBound);
536 case LADSPA_HINT_DEFAULT_HIGH:
537 if (LADSPA_IS_HINT_LOGARITHMIC(hdesc)) {
538 *val = exp(log(desc->PortRangeHints[port].LowerBound)
540 + log(desc->PortRangeHints[port].UpperBound)
543 *val = (desc->PortRangeHints[port].LowerBound * 0.25) +
544 (desc->PortRangeHints[port].UpperBound * 0.75);
547 case LADSPA_HINT_DEFAULT_MAXIMUM:
548 *val = desc->PortRangeHints[port].UpperBound;
550 case LADSPA_HINT_DEFAULT_0:
553 case LADSPA_HINT_DEFAULT_1:
556 case LADSPA_HINT_DEFAULT_100:
559 case LADSPA_HINT_DEFAULT_440:
563 *val = 0; /* reasonable default, if everything fails */
568 static int snd_pcm_ladspa_connect_controls(snd_pcm_ladspa_plugin_t *plugin,
569 snd_pcm_ladspa_plugin_io_t *io,
570 snd_pcm_ladspa_instance_t *instance)
572 unsigned long idx, midx;
574 for (idx = midx = 0; idx < plugin->desc->PortCount; idx++)
575 if ((plugin->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_CONTROL)) == (io->pdesc | LADSPA_PORT_CONTROL)) {
576 if (io->controls_size > midx) {
577 if (!io->controls_initialized[midx])
578 snd_pcm_ladspa_get_default_cvalue(plugin->desc, idx, &io->controls[midx]);
579 plugin->desc->connect_port(instance->handle, idx, &io->controls[midx]);
588 static int snd_pcm_ladspa_check_connect(snd_pcm_ladspa_plugin_t *plugin,
589 snd_pcm_ladspa_plugin_io_t *io,
590 snd_pcm_ladspa_eps_t *eps,
593 unsigned int idx, midx;
596 for (idx = midx = 0; idx < plugin->desc->PortCount; idx++)
597 if ((plugin->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_AUDIO)) == (io->pdesc | LADSPA_PORT_AUDIO)) {
598 if (eps->channels.array[midx] == NO_ASSIGN) {
599 SNDERR("%s port for plugin %s depth %u is not connected", io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name, depth);
605 SNDERR("%i connection errors total", err);
611 static int snd_pcm_ladspa_allocate_instances(snd_pcm_t *pcm, snd_pcm_ladspa_t *ladspa)
613 struct list_head *list, *pos;
614 unsigned int depth, idx, count;
615 unsigned int in_channel, out_channel;
616 unsigned int in_channels, out_channels;
617 unsigned int in_ports, out_ports;
618 snd_pcm_ladspa_instance_t *instance = NULL;
621 list = pcm->stream == SND_PCM_STREAM_PLAYBACK ? &ladspa->pplugins : &ladspa->cplugins;
622 in_channels = ladspa->channels > 0 ? ladspa->channels :
623 (pcm->stream == SND_PCM_STREAM_PLAYBACK ? pcm->channels : ladspa->plug.gen.slave->channels);
626 list_for_each(pos, list) {
627 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list);
628 if (pos->next == list) /* last entry */
629 out_channels = pcm->stream == SND_PCM_STREAM_PLAYBACK ? ladspa->plug.gen.slave->channels : pcm->channels;
630 in_ports = snd_pcm_ladspa_count_ports(plugin, LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO);
631 out_ports = snd_pcm_ladspa_count_ports(plugin, LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO);
633 if (plugin->policy == SND_PCM_LADSPA_POLICY_DUPLICATE) {
634 if (in_ports == 1 && out_ports == 1)
637 plugin->policy = SND_PCM_LADSPA_POLICY_NONE;
641 for (idx = 0; idx < count; idx++) {
642 instance = (snd_pcm_ladspa_instance_t *)calloc(1, sizeof(snd_pcm_ladspa_instance_t));
643 if (instance == NULL)
645 instance->desc = plugin->desc;
646 instance->handle = plugin->desc->instantiate(plugin->desc, pcm->rate);
647 instance->depth = depth;
648 if (instance->handle == NULL) {
649 SNDERR("Unable to create instance of LADSPA plugin '%s'", plugin->desc->Name);
653 list_add_tail(&instance->list, &plugin->instances);
654 if (plugin->desc->activate)
655 plugin->desc->activate(instance->handle);
656 if (plugin->policy == SND_PCM_LADSPA_POLICY_DUPLICATE) {
657 err = snd_pcm_ladspa_connect_plugin_duplicate(plugin, &plugin->input, &plugin->output, instance, idx);
659 SNDERR("Unable to connect duplicate port of plugin '%s' channel %u depth %u", plugin->desc->Name, idx, instance->depth);
663 err = snd_pcm_ladspa_connect_plugin(plugin, instance);
665 SNDERR("Unable to connect plugin '%s' depth %u", plugin->desc->Name, depth);
669 err = snd_pcm_ladspa_connect_controls(plugin, &plugin->input, instance);
671 err = snd_pcm_ladspa_connect_controls(plugin, &plugin->output, instance);
674 err = snd_pcm_ladspa_check_connect(plugin, &plugin->input, &instance->input, depth);
677 err = snd_pcm_ladspa_check_connect(plugin, &plugin->output, &instance->output, depth);
685 static LADSPA_Data *snd_pcm_ladspa_allocate_zero(snd_pcm_ladspa_t *ladspa, unsigned int idx)
687 if (ladspa->zero[idx] == NULL)
688 ladspa->zero[idx] = calloc(ladspa->allocated, sizeof(LADSPA_Data));
689 return ladspa->zero[idx];
692 static int snd_pcm_ladspa_allocate_memory(snd_pcm_t *pcm, snd_pcm_ladspa_t *ladspa)
694 struct list_head *list, *pos, *pos1;
695 snd_pcm_ladspa_instance_t *instance;
696 unsigned int channels = 16, nchannels;
697 unsigned int ichannels, ochannels;
698 void **pchannels, **npchannels;
699 unsigned int idx, chn;
701 ladspa->allocated = 2048;
702 if (pcm->buffer_size > ladspa->allocated)
703 ladspa->allocated = pcm->buffer_size;
704 if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
705 ichannels = pcm->channels;
706 ochannels = ladspa->plug.gen.slave->channels;
708 ichannels = ladspa->plug.gen.slave->channels;
709 ochannels = pcm->channels;
711 pchannels = calloc(1, sizeof(void *) * channels);
712 if (pchannels == NULL)
714 list = pcm->stream == SND_PCM_STREAM_PLAYBACK ? &ladspa->pplugins : &ladspa->cplugins;
715 list_for_each(pos, list) {
716 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list);
717 list_for_each(pos1, &plugin->instances) {
718 instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list);
719 nchannels = channels;
720 for (idx = 0; idx < instance->input.channels.size; idx++) {
721 chn = instance->input.channels.array[idx];
722 assert(instance->input.ports.array[idx] != NO_ASSIGN);
723 if (chn >= nchannels)
726 for (idx = 0; idx < instance->output.channels.size; idx++) {
727 chn = instance->output.channels.array[idx];
728 assert(instance->output.ports.array[idx] != NO_ASSIGN);
729 if (chn >= nchannels)
732 if (nchannels != channels) {
733 npchannels = realloc(pchannels, nchannels * sizeof(void *));
734 if (npchannels == NULL) {
738 for (idx = channels; idx < nchannels; idx++)
739 npchannels[idx] = NULL;
740 pchannels = npchannels;
742 assert(instance->input.data == NULL);
743 assert(instance->input.m_data == NULL);
744 assert(instance->output.data == NULL);
745 assert(instance->output.m_data == NULL);
746 instance->input.data = calloc(instance->input.channels.size, sizeof(void *));
747 instance->input.m_data = calloc(instance->input.channels.size, sizeof(void *));
748 instance->output.data = calloc(instance->output.channels.size, sizeof(void *));
749 instance->output.m_data = calloc(instance->output.channels.size, sizeof(void *));
750 if (instance->input.data == NULL ||
751 instance->input.m_data == NULL ||
752 instance->output.data == NULL ||
753 instance->output.m_data == NULL) {
757 for (idx = 0; idx < instance->input.channels.size; idx++) {
758 chn = instance->output.channels.array[idx];
759 if (pchannels[chn] == NULL && chn < ichannels) {
760 instance->input.data[idx] = NULL;
763 instance->input.data[idx] = pchannels[chn];
764 if (instance->input.data[idx] == NULL) {
765 instance->input.data[idx] = snd_pcm_ladspa_allocate_zero(ladspa, 0);
766 if (instance->input.data[idx] == NULL) {
772 for (idx = 0; idx < instance->output.channels.size; idx++) {
773 chn = instance->output.channels.array[idx];
774 /* FIXME/OPTIMIZE: check if we can remove double alloc */
775 /* if LADSPA plugin has no broken inplace */
776 instance->output.data[idx] = malloc(sizeof(LADSPA_Data) * ladspa->allocated);
777 if (instance->output.data[idx] == NULL) {
781 pchannels[chn] = instance->output.m_data[idx] = instance->output.data[idx];
785 /* OPTIMIZE: we have already allocated areas for ALSA output channels */
786 /* next loop deallocates the last output LADSPA areas and connects */
787 /* them to ALSA areas (NULL) or dummy area ladpsa->free[1] ; */
788 /* this algorithm might be optimized to not allocate the last LADSPA outputs */
789 list_for_each(pos, list) {
790 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list);
791 list_for_each(pos1, &plugin->instances) {
792 instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list);
793 for (idx = 0; idx < instance->output.channels.size; idx++) {
794 chn = instance->output.channels.array[idx];
795 if (instance->output.data[idx] == pchannels[chn]) {
796 free(instance->output.m_data[idx]);
797 instance->output.m_data[idx] = NULL;
798 if (chn < ochannels) {
799 instance->output.data[idx] = NULL;
801 instance->output.data[idx] = snd_pcm_ladspa_allocate_zero(ladspa, 1);
802 if (instance->output.data[idx] == NULL) {
812 printf("zero[0] = %p\n", ladspa->zero[0]);
813 printf("zero[1] = %p\n", ladspa->zero[1]);
814 list_for_each(pos, list) {
815 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list);
816 list_for_each(pos1, &plugin->instances) {
817 instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list);
818 for (idx = 0; idx < instance->input.channels.size; idx++)
819 printf("%i:alloc-input%i: data = %p, m_data = %p\n", instance->depth, idx, instance->input.data[idx], instance->input.m_data[idx]);
820 for (idx = 0; idx < instance->output.channels.size; idx++)
821 printf("%i:alloc-output%i: data = %p, m_data = %p\n", instance->depth, idx, instance->output.data[idx], instance->output.m_data[idx]);
829 static int snd_pcm_ladspa_init(snd_pcm_t *pcm)
831 snd_pcm_ladspa_t *ladspa = pcm->private_data;
834 snd_pcm_ladspa_free_instances(pcm, ladspa, 1);
835 err = snd_pcm_ladspa_allocate_instances(pcm, ladspa);
837 snd_pcm_ladspa_free_instances(pcm, ladspa, 1);
840 err = snd_pcm_ladspa_allocate_memory(pcm, ladspa);
842 snd_pcm_ladspa_free_instances(pcm, ladspa, 1);
848 static int snd_pcm_ladspa_hw_free(snd_pcm_t *pcm)
850 snd_pcm_ladspa_t *ladspa = pcm->private_data;
852 snd_pcm_ladspa_free_instances(pcm, ladspa, 1);
853 return snd_pcm_generic_hw_free(pcm);
856 static snd_pcm_uframes_t
857 snd_pcm_ladspa_write_areas(snd_pcm_t *pcm,
858 const snd_pcm_channel_area_t *areas,
859 snd_pcm_uframes_t offset,
860 snd_pcm_uframes_t size,
861 const snd_pcm_channel_area_t *slave_areas,
862 snd_pcm_uframes_t slave_offset,
863 snd_pcm_uframes_t *slave_sizep)
865 snd_pcm_ladspa_t *ladspa = pcm->private_data;
866 snd_pcm_ladspa_instance_t *instance;
867 struct list_head *pos, *pos1;
869 unsigned int idx, chn, size1, size2;
871 if (size > *slave_sizep)
874 #if 0 /* no processing - for testing purposes only */
875 snd_pcm_areas_copy(slave_areas, slave_offset,
877 pcm->channels, size, pcm->format);
881 if (size1 > ladspa->allocated)
882 size1 = ladspa->allocated;
883 list_for_each(pos, &ladspa->pplugins) {
884 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list);
885 list_for_each(pos1, &plugin->instances) {
886 instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list);
887 for (idx = 0; idx < instance->input.channels.size; idx++) {
888 chn = instance->input.channels.array[idx];
889 data = instance->input.data[idx];
891 data = (LADSPA_Data *)((char *)areas[chn].addr + (areas[chn].first / 8));
894 instance->desc->connect_port(instance->handle, instance->input.ports.array[idx], data);
896 for (idx = 0; idx < instance->output.channels.size; idx++) {
897 chn = instance->output.channels.array[idx];
898 data = instance->output.data[idx];
900 data = (LADSPA_Data *)((char *)slave_areas[chn].addr + (areas[chn].first / 8));
901 data += slave_offset;
903 instance->desc->connect_port(instance->handle, instance->output.ports.array[idx], data);
905 instance->desc->run(instance->handle, size1);
909 slave_offset += size1;
913 *slave_sizep = size2;
917 static snd_pcm_uframes_t
918 snd_pcm_ladspa_read_areas(snd_pcm_t *pcm,
919 const snd_pcm_channel_area_t *areas,
920 snd_pcm_uframes_t offset,
921 snd_pcm_uframes_t size,
922 const snd_pcm_channel_area_t *slave_areas,
923 snd_pcm_uframes_t slave_offset,
924 snd_pcm_uframes_t *slave_sizep)
926 snd_pcm_ladspa_t *ladspa = pcm->private_data;
927 snd_pcm_ladspa_instance_t *instance;
928 struct list_head *pos, *pos1;
930 unsigned int idx, chn, size1, size2;;
932 if (size > *slave_sizep)
935 #if 0 /* no processing - for testing purposes only */
936 snd_pcm_areas_copy(areas, offset,
937 slave_areas, slave_offset,
938 pcm->channels, size, pcm->format);
942 if (size1 > ladspa->allocated)
943 size1 = ladspa->allocated;
944 list_for_each(pos, &ladspa->cplugins) {
945 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list);
946 list_for_each(pos1, &plugin->instances) {
947 instance = list_entry(pos1, snd_pcm_ladspa_instance_t, list);
948 for (idx = 0; idx < instance->input.channels.size; idx++) {
949 chn = instance->input.channels.array[idx];
950 data = instance->input.data[idx];
952 data = (LADSPA_Data *)((char *)slave_areas[chn].addr + (areas[chn].first / 8));
953 data += slave_offset;
955 instance->desc->connect_port(instance->handle, instance->input.ports.array[idx], data);
957 for (idx = 0; idx < instance->output.channels.size; idx++) {
958 chn = instance->output.channels.array[idx];
959 data = instance->output.data[idx];
961 data = (LADSPA_Data *)((char *)areas[chn].addr + (areas[chn].first / 8));
964 instance->desc->connect_port(instance->handle, instance->output.ports.array[idx], data);
966 instance->desc->run(instance->handle, size1);
970 slave_offset += size1;
974 *slave_sizep = size2;
978 static void snd_pcm_ladspa_dump_direction(snd_pcm_ladspa_plugin_t *plugin,
979 snd_pcm_ladspa_plugin_io_t *io,
982 unsigned int idx, midx;
984 if (io->port_bindings_size == 0)
986 snd_output_printf(out, " Audio %s port bindings:\n", io->pdesc == LADSPA_PORT_INPUT ? "input" : "output");
987 for (idx = 0; idx < io->port_bindings_size; idx++) {
988 if (io->port_bindings[idx] == NO_ASSIGN)
989 snd_output_printf(out, " %i -> NONE\n", idx);
991 snd_output_printf(out, " %i -> %i\n", idx, io->port_bindings[idx]);
994 if (io->controls_size == 0)
996 snd_output_printf(out, " Control %s port initial values:\n", io->pdesc == LADSPA_PORT_INPUT ? "input" : "output");
997 for (idx = midx = 0; idx < plugin->desc->PortCount; idx++) {
998 if ((plugin->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_CONTROL)) == (io->pdesc | LADSPA_PORT_CONTROL)) {
999 snd_output_printf(out, " %i \"%s\" = %.8f\n", idx, plugin->desc->PortNames[idx], io->controls[midx]);
1005 static void snd_pcm_ladspa_dump_array(snd_output_t *out,
1006 snd_pcm_ladspa_array_t *array,
1007 snd_pcm_ladspa_plugin_t *plugin)
1009 unsigned int size = array->size;
1010 unsigned int val, idx = 0;
1012 while (size-- > 0) {
1014 snd_output_putc(out, ',');
1015 snd_output_putc(out, ' ');
1017 val = array->array[idx++];
1018 if (val == NO_ASSIGN)
1019 snd_output_putc(out, '-');
1021 snd_output_printf(out, "%u", val);
1022 if (plugin && val != NO_ASSIGN)
1023 snd_output_printf(out, " \"%s\"", plugin->desc->PortNames[val]);
1027 static void snd_pcm_ladspa_plugins_dump(struct list_head *list, snd_output_t *out)
1029 struct list_head *pos, *pos2;
1031 list_for_each(pos, list) {
1032 snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list);
1033 snd_output_printf(out, " Policy: %s\n", plugin->policy == SND_PCM_LADSPA_POLICY_NONE ? "none" : "duplicate");
1034 snd_output_printf(out, " Filename: %s\n", plugin->filename);
1035 snd_output_printf(out, " Plugin Name: %s\n", plugin->desc->Name);
1036 snd_output_printf(out, " Plugin Label: %s\n", plugin->desc->Label);
1037 snd_output_printf(out, " Plugin Unique ID: %lu\n", plugin->desc->UniqueID);
1038 snd_output_printf(out, " Instances:\n");
1039 list_for_each(pos2, &plugin->instances) {
1040 snd_pcm_ladspa_instance_t *in = (snd_pcm_ladspa_instance_t *) pos2;
1041 snd_output_printf(out, " Depth: %i\n", in->depth);
1042 snd_output_printf(out, " InChannels: ");
1043 snd_pcm_ladspa_dump_array(out, &in->input.channels, NULL);
1044 snd_output_printf(out, "\n InPorts: ");
1045 snd_pcm_ladspa_dump_array(out, &in->input.ports, plugin);
1046 snd_output_printf(out, "\n OutChannels: ");
1047 snd_pcm_ladspa_dump_array(out, &in->output.channels, NULL);
1048 snd_output_printf(out, "\n OutPorts: ");
1049 snd_pcm_ladspa_dump_array(out, &in->output.ports, plugin);
1050 snd_output_printf(out, "\n");
1052 snd_pcm_ladspa_dump_direction(plugin, &plugin->input, out);
1053 snd_pcm_ladspa_dump_direction(plugin, &plugin->output, out);
1057 static void snd_pcm_ladspa_dump(snd_pcm_t *pcm, snd_output_t *out)
1059 snd_pcm_ladspa_t *ladspa = pcm->private_data;
1061 snd_output_printf(out, "LADSPA PCM\n");
1062 snd_output_printf(out, " Playback:\n");
1063 snd_pcm_ladspa_plugins_dump(&ladspa->pplugins, out);
1064 snd_output_printf(out, " Capture:\n");
1065 snd_pcm_ladspa_plugins_dump(&ladspa->cplugins, out);
1067 snd_output_printf(out, "Its setup is:\n");
1068 snd_pcm_dump_setup(pcm, out);
1070 snd_output_printf(out, "Slave: ");
1071 snd_pcm_dump(ladspa->plug.gen.slave, out);
1074 static const snd_pcm_ops_t snd_pcm_ladspa_ops = {
1075 .close = snd_pcm_ladspa_close,
1076 .info = snd_pcm_generic_info,
1077 .hw_refine = snd_pcm_ladspa_hw_refine,
1078 .hw_params = snd_pcm_ladspa_hw_params,
1079 .hw_free = snd_pcm_ladspa_hw_free,
1080 .sw_params = snd_pcm_generic_sw_params,
1081 .channel_info = snd_pcm_generic_channel_info,
1082 .dump = snd_pcm_ladspa_dump,
1083 .nonblock = snd_pcm_generic_nonblock,
1084 .async = snd_pcm_generic_async,
1085 .mmap = snd_pcm_generic_mmap,
1086 .munmap = snd_pcm_generic_munmap,
1087 .query_chmaps = snd_pcm_generic_query_chmaps,
1088 .get_chmap = snd_pcm_generic_get_chmap,
1089 .set_chmap = snd_pcm_generic_set_chmap,
1092 static int snd_pcm_ladspa_check_file(snd_pcm_ladspa_plugin_t * const plugin,
1093 const char *filename,
1095 const unsigned long ladspa_id)
1100 handle = dlopen(filename, RTLD_LAZY);
1102 LADSPA_Descriptor_Function fcn = (LADSPA_Descriptor_Function)dlsym(handle, "ladspa_descriptor");
1105 const LADSPA_Descriptor *d;
1106 for (idx = 0; (d = fcn(idx)) != NULL; idx++) {
1108 * avoid locale problems - see ALSA bug#1553
1111 if (strcmp(label, d->Label))
1116 if (label != NULL) {
1118 labellocale = malloc (strlen (label) + 1);
1119 if (labellocale == NULL) {
1123 strcpy (labellocale, label);
1124 if (strrchr(labellocale, '.'))
1125 *strrchr (labellocale, '.') = *lc->decimal_point;
1126 if (strcmp(label, d->Label) && strcmp(labellocale, d->Label)) {
1133 if (ladspa_id > 0 && d->UniqueID != ladspa_id)
1135 plugin->filename = strdup(filename);
1136 if (plugin->filename == NULL) {
1140 plugin->dl_handle = handle;
1150 static int snd_pcm_ladspa_check_dir(snd_pcm_ladspa_plugin_t * const plugin,
1153 const unsigned long ladspa_id)
1156 struct dirent * dirent;
1157 int len = strlen(path), err;
1163 need_slash = path[len - 1] != '/';
1165 dir = opendir(path);
1170 dirent = readdir(dir);
1176 filename = malloc(len + strlen(dirent->d_name) + 1 + need_slash);
1177 if (filename == NULL) {
1181 strcpy(filename, path);
1183 strcat(filename, "/");
1184 strcat(filename, dirent->d_name);
1185 err = snd_pcm_ladspa_check_file(plugin, filename, label, ladspa_id);
1187 if (err < 0 && err != -ENOENT) {
1200 static int snd_pcm_ladspa_look_for_plugin(snd_pcm_ladspa_plugin_t * const plugin,
1203 const long ladspa_id)
1209 for (c = path; (l = strcspn(c, ": ")) > 0; ) {
1214 err = snd_user_file(name, &fullpath);
1217 err = snd_pcm_ladspa_check_dir(plugin, fullpath, label, ladspa_id);
1231 static int snd_pcm_ladspa_add_default_controls(snd_pcm_ladspa_plugin_t *lplug,
1232 snd_pcm_ladspa_plugin_io_t *io)
1234 unsigned int count = 0;
1236 unsigned char *initialized;
1239 for (idx = 0; idx < lplug->desc->PortCount; idx++)
1240 if ((lplug->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_CONTROL)) == (io->pdesc | LADSPA_PORT_CONTROL))
1242 array = (LADSPA_Data *)calloc(count, sizeof(LADSPA_Data));
1245 initialized = (unsigned char *)calloc(count, sizeof(unsigned char));
1250 io->controls_size = count;
1251 io->controls_initialized = initialized;
1252 io->controls = array;
1257 static int snd_pcm_ladspa_parse_controls(snd_pcm_ladspa_plugin_t *lplug,
1258 snd_pcm_ladspa_plugin_io_t *io,
1259 snd_config_t *controls)
1261 snd_config_iterator_t i, next;
1264 if (snd_config_get_type(controls) != SND_CONFIG_TYPE_COMPOUND) {
1265 SNDERR("controls definition must be a compound");
1269 snd_config_for_each(i, next, controls) {
1270 snd_config_t *n = snd_config_iterator_entry(i);
1273 unsigned int port, uval;
1275 if (snd_config_get_id(n, &id) < 0)
1277 err = safe_strtol(id, &lval);
1279 err = snd_pcm_ladspa_find_port(&port, lplug, io->pdesc | LADSPA_PORT_CONTROL, lval);
1281 err = snd_pcm_ladspa_find_sport(&port, lplug, io->pdesc | LADSPA_PORT_CONTROL, id);
1284 SNDERR("Unable to find an control port (%s)", id);
1287 if (snd_config_get_ireal(n, &dval) < 0) {
1288 SNDERR("Control port %s has not an float or integer value", id);
1291 err = snd_pcm_ladspa_find_port_idx(&uval, lplug, io->pdesc | LADSPA_PORT_CONTROL, port);
1293 SNDERR("internal error");
1296 io->controls_initialized[uval] = 1;
1297 io->controls[uval] = (LADSPA_Data)dval;
1303 static int snd_pcm_ladspa_parse_bindings(snd_pcm_ladspa_plugin_t *lplug,
1304 snd_pcm_ladspa_plugin_io_t *io,
1305 snd_config_t *bindings)
1307 unsigned int count = 0;
1308 unsigned int *array;
1309 snd_config_iterator_t i, next;
1312 if (snd_config_get_type(bindings) != SND_CONFIG_TYPE_COMPOUND) {
1313 SNDERR("bindings definition must be a compound");
1316 snd_config_for_each(i, next, bindings) {
1317 snd_config_t *n = snd_config_iterator_entry(i);
1320 if (snd_config_get_id(n, &id) < 0)
1322 err = safe_strtol(id, &channel);
1323 if (err < 0 || channel < 0) {
1324 SNDERR("Invalid channel number: %s", id);
1327 if (lplug->policy == SND_PCM_LADSPA_POLICY_DUPLICATE && channel > 0) {
1328 SNDERR("Wrong channel specification for duplicate policy");
1331 if (count < (unsigned int)(channel + 1))
1332 count = (unsigned int)(channel + 1);
1335 array = (unsigned int *)calloc(count, sizeof(unsigned int));
1338 memset(array, 0xff, count * sizeof(unsigned int));
1339 io->port_bindings_size = count;
1340 io->port_bindings = array;
1341 snd_config_for_each(i, next, bindings) {
1342 snd_config_t *n = snd_config_iterator_entry(i);
1343 const char *id, *sport;
1345 if (snd_config_get_id(n, &id) < 0)
1347 err = safe_strtol(id, &channel);
1348 if (err < 0 || channel < 0) {
1349 assert(0); /* should never happen */
1352 err = snd_config_get_integer(n, &port);
1354 err = snd_pcm_ladspa_find_port(&array[channel], lplug, io->pdesc | LADSPA_PORT_AUDIO, port);
1356 SNDERR("Unable to find an audio port (%li) for channel %s", port, id);
1361 err = snd_config_get_string(n, &sport);
1363 SNDERR("Invalid LADSPA port field type for %s", id);
1366 err = snd_pcm_ladspa_find_sport(&array[channel], lplug, io->pdesc | LADSPA_PORT_AUDIO, sport);
1368 SNDERR("Unable to find an audio port (%s) for channel %s", sport, id);
1377 static int snd_pcm_ladspa_parse_ioconfig(snd_pcm_ladspa_plugin_t *lplug,
1378 snd_pcm_ladspa_plugin_io_t *io,
1381 snd_config_iterator_t i, next;
1382 snd_config_t *bindings = NULL, *controls = NULL;
1385 /* always add default controls for both input and output */
1386 err = snd_pcm_ladspa_add_default_controls(lplug, io);
1388 SNDERR("error adding default controls");
1396 if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
1397 SNDERR("input or output definition must be a compound");
1400 snd_config_for_each(i, next, conf) {
1401 snd_config_t *n = snd_config_iterator_entry(i);
1403 if (snd_config_get_id(n, &id) < 0)
1405 if (strcmp(id, "bindings") == 0) {
1409 if (strcmp(id, "controls") == 0) {
1415 /* ignore values of parameters for output controls */
1416 if (controls && !(io->pdesc & LADSPA_PORT_OUTPUT)) {
1417 err = snd_pcm_ladspa_parse_controls(lplug, io, controls);
1423 err = snd_pcm_ladspa_parse_bindings(lplug, io, bindings);
1432 static int snd_pcm_ladspa_add_plugin(struct list_head *list,
1434 snd_config_t *plugin,
1437 snd_config_iterator_t i, next;
1438 const char *label = NULL, *filename = NULL;
1441 snd_pcm_ladspa_plugin_t *lplug;
1442 snd_pcm_ladspa_policy_t policy = SND_PCM_LADSPA_POLICY_DUPLICATE;
1443 snd_config_t *input = NULL, *output = NULL;
1445 snd_config_for_each(i, next, plugin) {
1446 snd_config_t *n = snd_config_iterator_entry(i);
1448 if (snd_config_get_id(n, &id) < 0)
1450 if (strcmp(id, "label") == 0) {
1451 err = snd_config_get_string(n, &label);
1456 if (strcmp(id, "id") == 0) {
1457 err = snd_config_get_integer(n, &ladspa_id);
1462 if (strcmp(id, "filename") == 0) {
1463 err = snd_config_get_string(n, &filename);
1468 if (strcmp(id, "input") == 0) {
1472 if (strcmp(id, "output") == 0) {
1476 if (strcmp(id, "policy") == 0) {
1478 err = snd_config_get_string(n, &str);
1480 SNDERR("policy field must be a string");
1483 if (strcmp(str, "none") == 0)
1484 policy = SND_PCM_LADSPA_POLICY_NONE;
1485 else if (strcmp(str, "duplicate") == 0)
1486 policy = SND_PCM_LADSPA_POLICY_DUPLICATE;
1488 SNDERR("unknown policy definition");
1494 if (label == NULL && ladspa_id <= 0) {
1495 SNDERR("no plugin label or id");
1498 lplug = (snd_pcm_ladspa_plugin_t *)calloc(1, sizeof(snd_pcm_ladspa_plugin_t));
1501 lplug->policy = policy;
1502 lplug->input.pdesc = LADSPA_PORT_INPUT;
1503 lplug->output.pdesc = LADSPA_PORT_OUTPUT;
1504 INIT_LIST_HEAD(&lplug->instances);
1506 err = snd_pcm_ladspa_check_file(lplug, filename, label, ladspa_id);
1508 SNDERR("Unable to load plugin '%s' ID %li, filename '%s'", label, ladspa_id, filename);
1513 err = snd_pcm_ladspa_look_for_plugin(lplug, path, label, ladspa_id);
1515 SNDERR("Unable to find or load plugin '%s' ID %li, path '%s'", label, ladspa_id, path);
1521 list_add_tail(&lplug->list, list);
1523 list_add(&lplug->list, list);
1525 err = snd_pcm_ladspa_parse_ioconfig(lplug, &lplug->input, input);
1528 err = snd_pcm_ladspa_parse_ioconfig(lplug, &lplug->output, output);
1534 static int snd_pcm_ladspa_build_plugins(struct list_head *list,
1536 snd_config_t *plugins,
1539 snd_config_iterator_t i, next;
1540 int idx = 0, hit, err;
1542 if (plugins == NULL) /* nothing TODO */
1544 if (snd_config_get_type(plugins) != SND_CONFIG_TYPE_COMPOUND) {
1545 SNDERR("plugins must be defined inside a compound");
1550 snd_config_for_each(i, next, plugins) {
1551 snd_config_t *n = snd_config_iterator_entry(i);
1554 if (snd_config_get_id(n, &id) < 0)
1556 err = safe_strtol(id, &i);
1558 SNDERR("id of field %s is not an integer", id);
1563 err = snd_pcm_ladspa_add_plugin(list, path, n, reverse);
1570 if (list_empty(list)) {
1571 SNDERR("empty plugin list is not accepted");
1578 * \brief Creates a new LADSPA<->ALSA Plugin
1579 * \param pcmp Returns created PCM handle
1580 * \param name Name of PCM
1581 * \param ladspa_path The path for LADSPA plugins
1582 * \param channels Force input channel count to LADSPA plugin chain, 0 = no force (auto)
1583 * \param ladspa_pplugins The playback configuration
1584 * \param ladspa_cplugins The capture configuration
1585 * \param slave Slave PCM handle
1586 * \param close_slave When set, the slave PCM handle is closed with copy PCM
1587 * \retval zero on success otherwise a negative error code
1588 * \warning Using of this function might be dangerous in the sense
1589 * of compatibility reasons. The prototype might be freely
1590 * changed in future.
1592 int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
1593 const char *ladspa_path,
1594 unsigned int channels,
1595 snd_config_t *ladspa_pplugins,
1596 snd_config_t *ladspa_cplugins,
1597 snd_pcm_t *slave, int close_slave)
1600 snd_pcm_ladspa_t *ladspa;
1601 int err, reverse = 0;
1603 assert(pcmp && (ladspa_pplugins || ladspa_cplugins) && slave);
1605 if (!ladspa_path && !(ladspa_path = getenv("LADSPA_PATH")))
1607 ladspa = calloc(1, sizeof(snd_pcm_ladspa_t));
1610 snd_pcm_plugin_init(&ladspa->plug);
1611 ladspa->plug.init = snd_pcm_ladspa_init;
1612 ladspa->plug.read = snd_pcm_ladspa_read_areas;
1613 ladspa->plug.write = snd_pcm_ladspa_write_areas;
1614 ladspa->plug.undo_read = snd_pcm_plugin_undo_read_generic;
1615 ladspa->plug.undo_write = snd_pcm_plugin_undo_write_generic;
1616 ladspa->plug.gen.slave = slave;
1617 ladspa->plug.gen.close_slave = close_slave;
1619 INIT_LIST_HEAD(&ladspa->pplugins);
1620 INIT_LIST_HEAD(&ladspa->cplugins);
1621 ladspa->channels = channels;
1623 if (slave->stream == SND_PCM_STREAM_PLAYBACK) {
1624 err = snd_pcm_ladspa_build_plugins(&ladspa->pplugins, ladspa_path, ladspa_pplugins, reverse);
1626 snd_pcm_ladspa_free(ladspa);
1630 if (slave->stream == SND_PCM_STREAM_CAPTURE) {
1631 if (ladspa_cplugins == ladspa_pplugins)
1633 err = snd_pcm_ladspa_build_plugins(&ladspa->cplugins, ladspa_path, ladspa_cplugins, reverse);
1635 snd_pcm_ladspa_free(ladspa);
1640 err = snd_pcm_new(&pcm, SND_PCM_TYPE_LADSPA, name, slave->stream, slave->mode);
1642 snd_pcm_ladspa_free(ladspa);
1645 pcm->ops = &snd_pcm_ladspa_ops;
1646 pcm->fast_ops = &snd_pcm_plugin_fast_ops;
1647 pcm->private_data = ladspa;
1648 pcm->poll_fd = slave->poll_fd;
1649 pcm->poll_events = slave->poll_events;
1650 pcm->monotonic = slave->monotonic;
1651 snd_pcm_set_hw_ptr(pcm, &ladspa->plug.hw_ptr, -1, 0);
1652 snd_pcm_set_appl_ptr(pcm, &ladspa->plug.appl_ptr, -1, 0);
1658 /*! \page pcm_plugins
1660 \section pcm_plugins_ladpsa Plugin: LADSPA <-> ALSA
1662 This plugin allows to apply a set of LADPSA plugins.
1663 The input and output format is always #SND_PCM_FORMAT_FLOAT (note: this type
1664 can be either little or big-endian depending on architecture).
1666 The policy duplicate means that there must be only one binding definition for
1667 channel zero. This definition is automatically duplicated for all channels.
1668 If the LADSPA plugin has multiple audio inputs or outputs the policy duplicate
1669 is automatically switched to policy none.
1671 The plugin serialization works as expected. You can eventually use more
1672 channels (inputs / outputs) inside the LADPSA plugin chain than processed
1673 in the ALSA plugin chain. If ALSA channel does not exist for given LADSPA
1674 input audio port, zero samples are given to this LADSPA port. On the output
1675 side (ALSA next plugin input), the valid channels are checked, too.
1676 If specific ALSA channel does not exist, the LADSPA output port is
1677 connected to a dummy sample area.
1679 Instances of LADSPA plugins are created dynamically.
1683 type ladspa # ALSA<->LADSPA PCM
1684 slave STR # Slave name
1686 slave { # Slave definition
1687 pcm STR # Slave PCM name
1689 pcm { } # Slave PCM definition
1691 [channels INT] # count input channels (input to LADSPA plugin chain)
1692 [path STR] # Path (directory) with LADSPA plugins
1693 plugins | # Definition for both directions
1694 playback_plugins | # Definition for playback direction
1695 capture_plugins { # Definition for capture direction
1696 N { # Configuration for LADPSA plugin N
1697 [id INT] # LADSPA plugin ID (for example 1043)
1698 [label STR] # LADSPA plugin label (for example 'delay_5s')
1699 [filename STR] # Full filename of .so library with LADSPA plugin code
1700 [policy STR] # Policy can be 'none' or 'duplicate'
1703 C INT or STR # C - channel, INT - audio port index, STR - audio port name
1706 # valid only in the input block
1707 I INT or REAL # I - control port index, INT or REAL - control value
1709 STR INT or REAL # STR - control port name, INT or REAL - control value
1717 \subsection pcm_plugins_ladspa_funcref Function reference
1720 <LI>snd_pcm_ladspa_open()
1721 <LI>_snd_pcm_ladspa_open()
1727 * \brief Creates a new LADSPA<->ALSA PCM
1728 * \param pcmp Returns created PCM handle
1729 * \param name Name of PCM
1730 * \param root Root configuration node
1731 * \param conf Configuration node with LADSPA<->ALSA PCM description
1732 * \param stream Stream type
1733 * \param mode Stream mode
1734 * \retval zero on success otherwise a negative error code
1735 * \warning Using of this function might be dangerous in the sense
1736 * of compatibility reasons. The prototype might be freely
1737 * changed in future.
1739 int _snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
1740 snd_config_t *root, snd_config_t *conf,
1741 snd_pcm_stream_t stream, int mode)
1743 snd_config_iterator_t i, next;
1746 snd_config_t *slave = NULL, *sconf;
1747 const char *path = NULL;
1749 snd_config_t *plugins = NULL, *pplugins = NULL, *cplugins = NULL;
1750 snd_config_for_each(i, next, conf) {
1751 snd_config_t *n = snd_config_iterator_entry(i);
1753 if (snd_config_get_id(n, &id) < 0)
1755 if (snd_pcm_conf_generic_id(id))
1757 if (strcmp(id, "slave") == 0) {
1761 if (strcmp(id, "path") == 0) {
1762 snd_config_get_string(n, &path);
1765 if (strcmp(id, "channels") == 0) {
1766 snd_config_get_integer(n, &channels);
1767 if (channels > 1024)
1773 if (strcmp(id, "plugins") == 0) {
1777 if (strcmp(id, "playback_plugins") == 0) {
1781 if (strcmp(id, "capture_plugins") == 0) {
1785 SNDERR("Unknown field %s", id);
1789 SNDERR("slave is not defined");
1793 if (pplugins || cplugins) {
1794 SNDERR("'plugins' definition cannot be combined with 'playback_plugins' or 'capture_plugins'");
1800 err = snd_pcm_slave_conf(root, slave, &sconf, 0);
1803 err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode, conf);
1804 snd_config_delete(sconf);
1807 err = snd_pcm_ladspa_open(pcmp, name, path, channels, pplugins, cplugins, spcm, 1);
1809 snd_pcm_close(spcm);
1813 SND_DLSYM_BUILD_VERSION(_snd_pcm_ladspa_open, SND_PCM_DLSYM_VERSION);