tizen 2.3.1 release
[external/alsa-lib.git] / src / pcm / pcm_ladspa.c
1 /**
2  * \file pcm/pcm_ladspa.c
3  * \ingroup PCM_Plugins
4  * \brief ALSA Plugin <-> LADSPA Plugin Interface
5  * \author Jaroslav Kysela <perex@perex.cz>
6  * \author Jaroslav Kysela <perex@perex.cz>
7  * \date 2001,2006
8  */
9 /*
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>
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@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                                 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);
349                                 free(instance);
350                         } else {
351                                 if (plugin->desc->activate)
352                                         plugin->desc->activate(instance->handle);
353                         }
354                 }
355                 if (cleanup) {
356                         assert(list_empty(&plugin->instances));
357                 }
358         }
359 }
360
361 static int snd_pcm_ladspa_add_to_carray(snd_pcm_ladspa_array_t *array,
362                                         unsigned int idx,
363                                         unsigned int val)
364 {
365         unsigned int *narray;
366         unsigned int idx1;
367
368         if (idx >= array->size) {
369                 narray = realloc(array->array, sizeof(unsigned int) * (idx + 1));
370                 if (narray == NULL)
371                         return -ENOMEM;
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;
377                 return 0;
378         }
379         if (array->array[idx] == NO_ASSIGN)
380                 array->array[idx] = val;
381         else
382                 return -EINVAL;
383         return 0;
384 }
385
386 static int snd_pcm_ladspa_add_to_array(snd_pcm_ladspa_array_t *array,
387                                        unsigned int idx,
388                                        unsigned int val)
389 {
390         unsigned int *narray;
391         unsigned int idx1;
392
393         if (idx >= array->size) {
394                 narray = realloc(array->array, sizeof(unsigned int) * (idx + 1));
395                 if (narray == NULL)
396                         return -ENOMEM;
397                 for (idx1 = array->size; idx1 < idx; idx1++)
398                         narray[idx1] = NO_ASSIGN;
399                 array->array = narray;
400                 array->size = idx + 1;
401         }
402         array->array[idx] = val;
403         return 0;
404 }
405
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)
409 {
410         unsigned int port, channels, idx, idx1;
411         int err;
412
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];
420                 else {
421                         err = snd_pcm_ladspa_find_port(&port, plugin, io->pdesc | LADSPA_PORT_AUDIO, idx);
422                         if (err < 0) {
423                                 SNDERR("unable to find audio %s port %u plugin '%s'", io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", idx, plugin->desc->Name);
424                                 return err;
425                         }
426                 }
427                 if (port == NO_ASSIGN)
428                         continue;
429                 err = snd_pcm_ladspa_add_to_carray(&eps->channels, idx1, idx);
430                 if (err < 0) {
431                         SNDERR("unable to add channel %u for audio %s plugin '%s'", idx, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name);
432                         return err;
433                 }
434                 err = snd_pcm_ladspa_add_to_array(&eps->ports, idx1, port);
435                 if (err < 0) {
436                         SNDERR("unable to add port %u for audio %s plugin '%s'", port, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name);
437                         return err;
438                 }
439                 idx1++;
440         }
441         return 0;
442 }
443
444 static int snd_pcm_ladspa_connect_plugin(snd_pcm_ladspa_plugin_t *plugin,
445                                          snd_pcm_ladspa_instance_t *instance)
446 {
447         int err;
448         
449         err = snd_pcm_ladspa_connect_plugin1(plugin, &plugin->input, &instance->input);
450         if (err < 0)
451                 return err;
452         err = snd_pcm_ladspa_connect_plugin1(plugin, &plugin->output, &instance->output);
453         if (err < 0)
454                 return err;
455         return 0;
456 }
457
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,
461                                                     unsigned int idx)
462 {
463         unsigned int port;
464         int err;
465
466         assert(plugin->policy == SND_PCM_LADSPA_POLICY_DUPLICATE);
467         if (io->port_bindings_size > 0) {
468                 port = io->port_bindings[0];
469         } else {
470                 err = snd_pcm_ladspa_find_port(&port, plugin, io->pdesc | LADSPA_PORT_AUDIO, 0);
471                 if (err < 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);
473                         return err;
474                 }
475         }
476         err = snd_pcm_ladspa_add_to_carray(&eps->channels, 0, idx);
477         if (err < 0) {
478                 SNDERR("unable to add channel %u for audio %s plugin '%s'", idx, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name);
479                 return err;
480         }
481         err = snd_pcm_ladspa_add_to_array(&eps->ports, 0, port);
482         if (err < 0) {
483                 SNDERR("unable to add port %u for audio %s plugin '%s'", port, io->pdesc & LADSPA_PORT_INPUT ? "input" : "output", plugin->desc->Name);
484                 return err;
485         }
486         return 0;
487 }
488
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,
493                                                    unsigned int idx)
494 {
495         int err;
496
497         err = snd_pcm_ladspa_connect_plugin_duplicate1(plugin, in_io, &instance->input, idx);
498         if (err < 0)
499                 return err;
500         err = snd_pcm_ladspa_connect_plugin_duplicate1(plugin, out_io, &instance->output, idx);
501         if (err < 0)
502                 return err;
503         return 0;
504 }
505
506 static void snd_pcm_ladspa_get_default_cvalue(const LADSPA_Descriptor * desc, unsigned int port, LADSPA_Data *val) 
507 {
508         LADSPA_PortRangeHintDescriptor hdesc;
509
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;
514                 break;
515         case LADSPA_HINT_DEFAULT_LOW:
516                 if (LADSPA_IS_HINT_LOGARITHMIC(hdesc)) {
517                         *val = exp(log(desc->PortRangeHints[port].LowerBound)
518                                         * 0.75
519                                         + log(desc->PortRangeHints[port].UpperBound)
520                                         * 0.25);
521                 } else {
522                         *val = (desc->PortRangeHints[port].LowerBound * 0.75) +
523                                (desc->PortRangeHints[port].UpperBound * 0.25);
524                 }
525                 break;
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);
530                 } else {
531                         *val = 0.5 *
532                                (desc->PortRangeHints[port].LowerBound +
533                                 desc->PortRangeHints[port].UpperBound);
534                 }
535                 break;
536         case LADSPA_HINT_DEFAULT_HIGH:
537                 if (LADSPA_IS_HINT_LOGARITHMIC(hdesc)) {
538                         *val = exp(log(desc->PortRangeHints[port].LowerBound)
539                                         * 0.25
540                                         + log(desc->PortRangeHints[port].UpperBound)
541                                         * 0.75);
542                 } else {
543                         *val = (desc->PortRangeHints[port].LowerBound * 0.25) +
544                                (desc->PortRangeHints[port].UpperBound * 0.75);
545                 }
546                 break;
547         case LADSPA_HINT_DEFAULT_MAXIMUM:
548                 *val = desc->PortRangeHints[port].UpperBound;
549                 break;
550         case LADSPA_HINT_DEFAULT_0:
551                 *val = 0;
552                 break;
553         case LADSPA_HINT_DEFAULT_1:
554                 *val = 1;
555                 break;
556         case LADSPA_HINT_DEFAULT_100:
557                 *val = 100;
558                 break;
559         case LADSPA_HINT_DEFAULT_440:
560                 *val = 440;
561                 break;
562         default:
563                 *val = 0;       /* reasonable default, if everything fails */
564                 break;
565         }
566 }
567
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)
571 {
572         unsigned long idx, midx;
573
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]);
580                         } else {
581                                 return -EINVAL;
582                         }
583                         midx++;
584                 }
585         return 0;
586 }
587
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,
591                                         unsigned int depth)
592 {
593         unsigned int idx, midx;
594         int err = 0;
595
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);
600                                 err++;
601                         }
602                         midx++;
603                 }
604         if (err > 0) {
605                 SNDERR("%i connection errors total", err);
606                 return -EINVAL;
607         }
608         return 0;
609 }
610
611 static int snd_pcm_ladspa_allocate_instances(snd_pcm_t *pcm, snd_pcm_ladspa_t *ladspa)
612 {
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;
619         int err;
620         
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);
624         depth = 0;
625         out_channels = 0;
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);
632                 count = 1;
633                 if (plugin->policy == SND_PCM_LADSPA_POLICY_DUPLICATE) {
634                         if (in_ports == 1 && out_ports == 1)
635                                 count = in_channels;
636                         else
637                                 plugin->policy = SND_PCM_LADSPA_POLICY_NONE;
638                 }
639                 in_channel = 0;
640                 out_channel = 0;
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)
644                                 return -ENOMEM;
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);
650                                 free(instance);
651                                 return -EINVAL;
652                         }
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);
658                                 if (err < 0) {
659                                         SNDERR("Unable to connect duplicate port of plugin '%s' channel %u depth %u", plugin->desc->Name, idx, instance->depth);
660                                         return err;
661                                 }
662                         } else {
663                                 err = snd_pcm_ladspa_connect_plugin(plugin, instance);
664                                 if (err < 0) {
665                                         SNDERR("Unable to connect plugin '%s' depth %u", plugin->desc->Name, depth);
666                                         return err;
667                                 }
668                         }
669                         err = snd_pcm_ladspa_connect_controls(plugin, &plugin->input, instance);
670                         assert(err >= 0);
671                         err = snd_pcm_ladspa_connect_controls(plugin, &plugin->output, instance);
672                         assert(err >= 0);
673                 }
674                 err = snd_pcm_ladspa_check_connect(plugin, &plugin->input, &instance->input, depth);
675                 if (err < 0)
676                         return err;
677                 err = snd_pcm_ladspa_check_connect(plugin, &plugin->output, &instance->output, depth);
678                 if (err < 0)
679                         return err;
680                 depth++;
681         }
682         return 0;
683 }
684
685 static LADSPA_Data *snd_pcm_ladspa_allocate_zero(snd_pcm_ladspa_t *ladspa, unsigned int idx)
686 {
687         if (ladspa->zero[idx] == NULL)
688                 ladspa->zero[idx] = calloc(ladspa->allocated, sizeof(LADSPA_Data));
689         return ladspa->zero[idx];
690 }
691
692 static int snd_pcm_ladspa_allocate_memory(snd_pcm_t *pcm, snd_pcm_ladspa_t *ladspa)
693 {
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;
700         
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;
707         } else {
708                 ichannels = ladspa->plug.gen.slave->channels;
709                 ochannels = pcm->channels;
710         }
711         pchannels = calloc(1, sizeof(void *) * channels);
712         if (pchannels == NULL)
713                 return -ENOMEM;
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)
724                                         nchannels = chn + 1;
725                         }
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)
730                                         nchannels = chn + 1;
731                         }
732                         if (nchannels != channels) {
733                                 npchannels = realloc(pchannels, nchannels * sizeof(void *));
734                                 if (npchannels == NULL) {
735                                         free(pchannels);
736                                         return -ENOMEM;
737                                 }
738                                 for (idx = channels; idx < nchannels; idx++)
739                                         npchannels[idx] = NULL;
740                                 pchannels = npchannels;
741                         }
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) {
754                                 free(pchannels);
755                                 return -ENOMEM;
756                         }
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;
761                                         continue;
762                                 }
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) {
767                                                 free(pchannels);
768                                                 return -ENOMEM;
769                                         }
770                                 }
771                         }
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) {
778                                         free(pchannels);
779                                         return -ENOMEM;
780                                 }
781                                 pchannels[chn] = instance->output.m_data[idx] = instance->output.data[idx];
782                         }
783                 }
784         }
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;
800                                         } else {
801                                                 instance->output.data[idx] = snd_pcm_ladspa_allocate_zero(ladspa, 1);
802                                                 if (instance->output.data[idx] == NULL) {
803                                                         free(pchannels);
804                                                         return -ENOMEM;
805                                                 }
806                                         }
807                                 }
808                         }
809                 }
810         }
811 #if 0
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]);
822                 }
823         }
824 #endif
825         free(pchannels);
826         return 0;
827 }
828
829 static int snd_pcm_ladspa_init(snd_pcm_t *pcm)
830 {
831         snd_pcm_ladspa_t *ladspa = pcm->private_data;
832         int err;
833         
834         snd_pcm_ladspa_free_instances(pcm, ladspa, 1);
835         err = snd_pcm_ladspa_allocate_instances(pcm, ladspa);
836         if (err < 0) {
837                 snd_pcm_ladspa_free_instances(pcm, ladspa, 1);
838                 return err;
839         }
840         err = snd_pcm_ladspa_allocate_memory(pcm, ladspa);
841         if (err < 0) {
842                 snd_pcm_ladspa_free_instances(pcm, ladspa, 1);
843                 return err;
844         }
845         return 0;
846 }
847
848 static int snd_pcm_ladspa_hw_free(snd_pcm_t *pcm)
849 {
850         snd_pcm_ladspa_t *ladspa = pcm->private_data;
851
852         snd_pcm_ladspa_free_instances(pcm, ladspa, 1);
853         return snd_pcm_generic_hw_free(pcm);
854 }
855
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)
864 {
865         snd_pcm_ladspa_t *ladspa = pcm->private_data;
866         snd_pcm_ladspa_instance_t *instance;
867         struct list_head *pos, *pos1;
868         LADSPA_Data *data;
869         unsigned int idx, chn, size1, size2;
870         
871         if (size > *slave_sizep)
872                 size = *slave_sizep;
873         size2 = size;
874 #if 0   /* no processing - for testing purposes only */
875         snd_pcm_areas_copy(slave_areas, slave_offset,
876                            areas, offset,
877                            pcm->channels, size, pcm->format);
878 #else
879         while (size > 0) {
880                 size1 = size;
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];
890                                         if (data == NULL) {
891                                                 data = (LADSPA_Data *)((char *)areas[chn].addr + (areas[chn].first / 8));
892                                                 data += offset;
893                                         }
894                                         instance->desc->connect_port(instance->handle, instance->input.ports.array[idx], data);
895                                 }
896                                 for (idx = 0; idx < instance->output.channels.size; idx++) {
897                                         chn = instance->output.channels.array[idx];
898                                         data = instance->output.data[idx];
899                                         if (data == NULL) {
900                                                 data = (LADSPA_Data *)((char *)slave_areas[chn].addr + (areas[chn].first / 8));
901                                                 data += slave_offset;
902                                         }
903                                         instance->desc->connect_port(instance->handle, instance->output.ports.array[idx], data);
904                                 }
905                                 instance->desc->run(instance->handle, size1);
906                         }
907                 }
908                 offset += size1;
909                 slave_offset += size1;
910                 size -= size1;
911         }
912 #endif
913         *slave_sizep = size2;
914         return size2;
915 }
916
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)
925 {
926         snd_pcm_ladspa_t *ladspa = pcm->private_data;
927         snd_pcm_ladspa_instance_t *instance;
928         struct list_head *pos, *pos1;
929         LADSPA_Data *data;
930         unsigned int idx, chn, size1, size2;;
931
932         if (size > *slave_sizep)
933                 size = *slave_sizep;
934         size2 = size;
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);
939 #else
940         while (size > 0) {
941                 size1 = size;
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];
951                                         if (data == NULL) {
952                                                 data = (LADSPA_Data *)((char *)slave_areas[chn].addr + (areas[chn].first / 8));
953                                                 data += slave_offset;
954                                         }       
955                                         instance->desc->connect_port(instance->handle, instance->input.ports.array[idx], data);
956                                 }
957                                 for (idx = 0; idx < instance->output.channels.size; idx++) {
958                                         chn = instance->output.channels.array[idx];
959                                         data = instance->output.data[idx];
960                                         if (data == NULL) {
961                                                 data = (LADSPA_Data *)((char *)areas[chn].addr + (areas[chn].first / 8));
962                                                 data += offset;
963                                         }
964                                         instance->desc->connect_port(instance->handle, instance->output.ports.array[idx], data);
965                                 }
966                                 instance->desc->run(instance->handle, size1);
967                         }
968                 }
969                 offset += size1;
970                 slave_offset += size1;
971                 size -= size1;
972         }
973 #endif
974         *slave_sizep = size2;
975         return size2;
976 }
977
978 static void snd_pcm_ladspa_dump_direction(snd_pcm_ladspa_plugin_t *plugin,
979                                           snd_pcm_ladspa_plugin_io_t *io,
980                                           snd_output_t *out)
981 {
982         unsigned int idx, midx;
983
984         if (io->port_bindings_size == 0)
985                 goto __control;
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);
990                 else
991                         snd_output_printf(out, "      %i -> %i\n", idx, io->port_bindings[idx]);
992         }
993       __control:
994         if (io->controls_size == 0)
995                 return;
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]);
1000                         midx++;
1001                 }
1002         }
1003 }
1004
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)
1008 {
1009         unsigned int size = array->size;
1010         unsigned int val, idx = 0;
1011
1012         while (size-- > 0) {
1013                 if (idx > 0) {
1014                         snd_output_putc(out, ',');
1015                         snd_output_putc(out, ' ');
1016                 }
1017                 val = array->array[idx++];
1018                 if (val == NO_ASSIGN)
1019                         snd_output_putc(out, '-');
1020                 else
1021                         snd_output_printf(out, "%u", val);
1022                 if (plugin && val != NO_ASSIGN)
1023                         snd_output_printf(out, " \"%s\"", plugin->desc->PortNames[val]);
1024         }
1025 }
1026
1027 static void snd_pcm_ladspa_plugins_dump(struct list_head *list, snd_output_t *out)
1028 {
1029         struct list_head *pos, *pos2;
1030         
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");
1051                 }
1052                 snd_pcm_ladspa_dump_direction(plugin, &plugin->input, out);
1053                 snd_pcm_ladspa_dump_direction(plugin, &plugin->output, out);
1054         }
1055 }
1056
1057 static void snd_pcm_ladspa_dump(snd_pcm_t *pcm, snd_output_t *out)
1058 {
1059         snd_pcm_ladspa_t *ladspa = pcm->private_data;
1060
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);
1066         if (pcm->setup) {
1067                 snd_output_printf(out, "Its setup is:\n");
1068                 snd_pcm_dump_setup(pcm, out);
1069         }
1070         snd_output_printf(out, "Slave: ");
1071         snd_pcm_dump(ladspa->plug.gen.slave, out);
1072 }
1073
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 };
1088
1089 static int snd_pcm_ladspa_check_file(snd_pcm_ladspa_plugin_t * const plugin,
1090                                      const char *filename,
1091                                      const char *label,
1092                                      const unsigned long ladspa_id)
1093 {
1094         void *handle;
1095
1096         assert(filename);
1097         handle = dlopen(filename, RTLD_LAZY);
1098         if (handle) {
1099                 LADSPA_Descriptor_Function fcn = (LADSPA_Descriptor_Function)dlsym(handle, "ladspa_descriptor");
1100                 if (fcn) {
1101                         long idx;
1102                         const LADSPA_Descriptor *d;
1103                         for (idx = 0; (d = fcn(idx)) != NULL; idx++) {
1104 /*
1105  * avoid locale problems - see ALSA bug#1553
1106  */
1107 #if 0
1108                                 if (strcmp(label, d->Label))
1109                                         continue;
1110 #else
1111                                 char *labellocale;
1112                                 struct lconv *lc;
1113                                 if (label != NULL) {
1114                                         lc = localeconv ();
1115                                         labellocale = malloc (strlen (label) + 1);
1116                                         if (labellocale == NULL) {
1117                                                 dlclose(handle);
1118                                                 return -ENOMEM;
1119                                         }
1120                                         strcpy (labellocale, label);
1121                                         if (strrchr(labellocale, '.'))
1122                                                 *strrchr (labellocale, '.') = *lc->decimal_point;
1123                                         if (strcmp(label, d->Label) && strcmp(labellocale, d->Label)) {
1124                                                 free(labellocale);
1125                                                 continue;
1126                                         }
1127                                         free (labellocale);
1128                                 }
1129 #endif
1130                                 if (ladspa_id > 0 && d->UniqueID != ladspa_id)
1131                                         continue;
1132                                 plugin->filename = strdup(filename);
1133                                 if (plugin->filename == NULL) {
1134                                         dlclose(handle);
1135                                         return -ENOMEM;
1136                                 }
1137                                 plugin->dl_handle = handle;
1138                                 plugin->desc = d;
1139                                 return 1;
1140                         }
1141                 }
1142                 dlclose(handle);
1143         }
1144         return -ENOENT;
1145 }
1146
1147 static int snd_pcm_ladspa_check_dir(snd_pcm_ladspa_plugin_t * const plugin,
1148                                     const char *path,
1149                                     const char *label,
1150                                     const unsigned long ladspa_id)
1151 {
1152         DIR *dir;
1153         struct dirent * dirent;
1154         int len = strlen(path), err;
1155         int need_slash;
1156         char *filename;
1157         
1158         if (len < 1)
1159                 return 0;
1160         need_slash = path[len - 1] != '/';
1161         
1162         dir = opendir(path);
1163         if (!dir)
1164                 return -ENOENT;
1165                 
1166         while (1) {
1167                 dirent = readdir(dir);
1168                 if (!dirent) {
1169                         closedir(dir);
1170                         return 0;
1171                 }
1172                 
1173                 filename = malloc(len + strlen(dirent->d_name) + 1 + need_slash);
1174                 if (filename == NULL) {
1175                         closedir(dir);
1176                         return -ENOMEM;
1177                 }
1178                 strcpy(filename, path);
1179                 if (need_slash)
1180                         strcat(filename, "/");
1181                 strcat(filename, dirent->d_name);
1182                 err = snd_pcm_ladspa_check_file(plugin, filename, label, ladspa_id);
1183                 free(filename);
1184                 if (err < 0 && err != -ENOENT) {
1185                         closedir(dir);
1186                         return err;
1187                 }
1188                 if (err > 0) {
1189                         closedir(dir);
1190                         return 1;
1191                 }
1192         }
1193         /* never reached */
1194         return 0;
1195 }
1196
1197 static int snd_pcm_ladspa_look_for_plugin(snd_pcm_ladspa_plugin_t * const plugin,
1198                                           const char *path,
1199                                           const char *label,
1200                                           const long ladspa_id)
1201 {
1202         const char *c;
1203         size_t l;
1204         int err;
1205         
1206         for (c = path; (l = strcspn(c, ": ")) > 0; ) {
1207                 char name[l + 1];
1208                 char *fullpath;
1209                 memcpy(name, c, l);
1210                 name[l] = 0;
1211                 err = snd_user_file(name, &fullpath);
1212                 if (err < 0)
1213                         return err;
1214                 err = snd_pcm_ladspa_check_dir(plugin, fullpath, label, ladspa_id);
1215                 free(fullpath);
1216                 if (err < 0)
1217                         return err;
1218                 if (err > 0)
1219                         return 0;
1220                 c += l;
1221                 if (!*c)
1222                         break;
1223                 c++;
1224         }
1225         return -ENOENT;
1226 }                                         
1227
1228 static int snd_pcm_ladspa_add_default_controls(snd_pcm_ladspa_plugin_t *lplug,
1229                                                snd_pcm_ladspa_plugin_io_t *io) 
1230 {
1231         unsigned int count = 0;
1232         LADSPA_Data *array;
1233         unsigned char *initialized;
1234         unsigned long idx;
1235
1236         for (idx = 0; idx < lplug->desc->PortCount; idx++)
1237                 if ((lplug->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_CONTROL)) == (io->pdesc | LADSPA_PORT_CONTROL))
1238                         count++;
1239         array = (LADSPA_Data *)calloc(count, sizeof(LADSPA_Data));
1240         if (!array)
1241                 return -ENOMEM;
1242         initialized = (unsigned char *)calloc(count, sizeof(unsigned char));
1243         if (!initialized) {
1244                 free(array);
1245                 return -ENOMEM;
1246         }
1247         io->controls_size = count;
1248         io->controls_initialized = initialized;
1249         io->controls = array;
1250
1251         return 0;
1252 }       
1253
1254 static int snd_pcm_ladspa_parse_controls(snd_pcm_ladspa_plugin_t *lplug,
1255                                          snd_pcm_ladspa_plugin_io_t *io,
1256                                          snd_config_t *controls) 
1257 {
1258         snd_config_iterator_t i, next;
1259         int err;
1260
1261         if (snd_config_get_type(controls) != SND_CONFIG_TYPE_COMPOUND) {
1262                 SNDERR("controls definition must be a compound");
1263                 return -EINVAL;
1264         }
1265
1266         snd_config_for_each(i, next, controls) {
1267                 snd_config_t *n = snd_config_iterator_entry(i);
1268                 const char *id;
1269                 long lval;
1270                 unsigned int port, uval;
1271                 double dval;
1272                 if (snd_config_get_id(n, &id) < 0)
1273                         continue;
1274                 err = safe_strtol(id, &lval);
1275                 if (err >= 0) {
1276                         err = snd_pcm_ladspa_find_port(&port, lplug, io->pdesc | LADSPA_PORT_CONTROL, lval);
1277                 } else {
1278                         err = snd_pcm_ladspa_find_sport(&port, lplug, io->pdesc | LADSPA_PORT_CONTROL, id);
1279                 }
1280                 if (err < 0) {
1281                         SNDERR("Unable to find an control port (%s)", id);
1282                         return err;
1283                 }
1284                 if (snd_config_get_ireal(n, &dval) < 0) {
1285                         SNDERR("Control port %s has not an float or integer value", id);
1286                         return err;
1287                 }
1288                 err = snd_pcm_ladspa_find_port_idx(&uval, lplug, io->pdesc | LADSPA_PORT_CONTROL, port);
1289                 if (err < 0) {
1290                         SNDERR("internal error");
1291                         return err;
1292                 }
1293                 io->controls_initialized[uval] = 1;
1294                 io->controls[uval] = (LADSPA_Data)dval;
1295         }
1296
1297         return 0;
1298 }
1299
1300 static int snd_pcm_ladspa_parse_bindings(snd_pcm_ladspa_plugin_t *lplug,
1301                                          snd_pcm_ladspa_plugin_io_t *io,
1302                                          snd_config_t *bindings) 
1303 {
1304         unsigned int count = 0;
1305         unsigned int *array;
1306         snd_config_iterator_t i, next;
1307         int err;
1308
1309         if (snd_config_get_type(bindings) != SND_CONFIG_TYPE_COMPOUND) {
1310                 SNDERR("bindings definition must be a compound");
1311                 return -EINVAL;
1312         }
1313         snd_config_for_each(i, next, bindings) {
1314                 snd_config_t *n = snd_config_iterator_entry(i);
1315                 const char *id;
1316                 long channel;
1317                 if (snd_config_get_id(n, &id) < 0)
1318                         continue;
1319                 err = safe_strtol(id, &channel);
1320                 if (err < 0 || channel < 0) {
1321                         SNDERR("Invalid channel number: %s", id);
1322                         return -EINVAL;
1323                 }
1324                 if (lplug->policy == SND_PCM_LADSPA_POLICY_DUPLICATE && channel > 0) {
1325                         SNDERR("Wrong channel specification for duplicate policy");
1326                         return -EINVAL;
1327                 }
1328                 if (count < (unsigned int)(channel + 1))
1329                         count = (unsigned int)(channel + 1);
1330         }
1331         if (count > 0) {
1332                 array = (unsigned int *)calloc(count, sizeof(unsigned int));
1333                 if (! array)
1334                         return -ENOMEM;
1335                 memset(array, 0xff, count * sizeof(unsigned int));
1336                 io->port_bindings_size = count;
1337                 io->port_bindings = array;
1338                 snd_config_for_each(i, next, bindings) {
1339                         snd_config_t *n = snd_config_iterator_entry(i);
1340                         const char *id, *sport;
1341                         long channel, port;
1342                         if (snd_config_get_id(n, &id) < 0)
1343                                 continue;
1344                         err = safe_strtol(id, &channel);
1345                         if (err < 0 || channel < 0) {
1346                                 assert(0);      /* should never happen */
1347                                 return -EINVAL;
1348                         }
1349                         err = snd_config_get_integer(n, &port);
1350                         if (err >= 0) {
1351                                 err = snd_pcm_ladspa_find_port(&array[channel], lplug, io->pdesc | LADSPA_PORT_AUDIO, port);
1352                                 if (err < 0) {
1353                                         SNDERR("Unable to find an audio port (%li) for channel %s", port, id);
1354                                         return err;
1355                                 }
1356                                 continue;
1357                         }
1358                         err = snd_config_get_string(n, &sport);
1359                         if (err < 0) {
1360                                 SNDERR("Invalid LADSPA port field type for %s", id);
1361                                 return -EINVAL;
1362                         }
1363                         err = snd_pcm_ladspa_find_sport(&array[channel], lplug, io->pdesc | LADSPA_PORT_AUDIO, sport);
1364                         if (err < 0) {
1365                                 SNDERR("Unable to find an audio port (%s) for channel %s", sport, id);
1366                                 return err;
1367                         }
1368                 }
1369         }
1370
1371         return 0;
1372 }
1373
1374 static int snd_pcm_ladspa_parse_ioconfig(snd_pcm_ladspa_plugin_t *lplug,
1375                                          snd_pcm_ladspa_plugin_io_t *io,
1376                                          snd_config_t *conf)
1377 {
1378         snd_config_iterator_t i, next;
1379         snd_config_t *bindings = NULL, *controls = NULL;
1380         int err;
1381
1382         /* always add default controls for both input and output */
1383         err = snd_pcm_ladspa_add_default_controls(lplug, io);
1384         if (err < 0) {
1385                 SNDERR("error adding default controls");
1386                 return err;
1387         }
1388                 
1389         if (conf == NULL) {
1390                 return 0;
1391         }
1392
1393         if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
1394                 SNDERR("input or output definition must be a compound");
1395                 return -EINVAL;
1396         }
1397         snd_config_for_each(i, next, conf) {
1398                 snd_config_t *n = snd_config_iterator_entry(i);
1399                 const char *id;
1400                 if (snd_config_get_id(n, &id) < 0)
1401                         continue;
1402                 if (strcmp(id, "bindings") == 0) {
1403                         bindings = n;
1404                         continue;
1405                 }
1406                 if (strcmp(id, "controls") == 0) {
1407                         controls = n;
1408                         continue;
1409                 }
1410         }
1411
1412         /* ignore values of parameters for output controls */
1413         if (controls && !(io->pdesc & LADSPA_PORT_OUTPUT)) {
1414                 err = snd_pcm_ladspa_parse_controls(lplug, io, controls);
1415                 if (err < 0) 
1416                         return err;
1417         }
1418
1419         if (bindings) {
1420                 err = snd_pcm_ladspa_parse_bindings(lplug, io, bindings);
1421                 if (err < 0) 
1422                         return err;
1423         }
1424
1425
1426         return 0;
1427 }
1428
1429 static int snd_pcm_ladspa_add_plugin(struct list_head *list,
1430                                      const char *path,
1431                                      snd_config_t *plugin,
1432                                      int reverse)
1433 {
1434         snd_config_iterator_t i, next;
1435         const char *label = NULL, *filename = NULL;
1436         long ladspa_id = 0;
1437         int err;
1438         snd_pcm_ladspa_plugin_t *lplug;
1439         snd_pcm_ladspa_policy_t policy = SND_PCM_LADSPA_POLICY_DUPLICATE;
1440         snd_config_t *input = NULL, *output = NULL;
1441
1442         snd_config_for_each(i, next, plugin) {
1443                 snd_config_t *n = snd_config_iterator_entry(i);
1444                 const char *id;
1445                 if (snd_config_get_id(n, &id) < 0)
1446                         continue;
1447                 if (strcmp(id, "label") == 0) {
1448                         err = snd_config_get_string(n, &label);
1449                         if (err < 0)
1450                                 return err;
1451                         continue;
1452                 }
1453                 if (strcmp(id, "id") == 0) {
1454                         err = snd_config_get_integer(n, &ladspa_id);
1455                         if (err < 0)
1456                                 return err;
1457                         continue;
1458                 }
1459                 if (strcmp(id, "filename") == 0) {
1460                         err = snd_config_get_string(n, &filename);
1461                         if (err < 0)
1462                                 return err;
1463                         continue;
1464                 }
1465                 if (strcmp(id, "input") == 0) {
1466                         input = n;
1467                         continue;
1468                 }
1469                 if (strcmp(id, "output") == 0) {
1470                         output = n;
1471                         continue;
1472                 }
1473                 if (strcmp(id, "policy") == 0) {
1474                         const char *str;
1475                         err = snd_config_get_string(n, &str);
1476                         if (err < 0) {
1477                                 SNDERR("policy field must be a string");
1478                                 return err;
1479                         }
1480                         if (strcmp(str, "none") == 0)
1481                                 policy = SND_PCM_LADSPA_POLICY_NONE;
1482                         else if (strcmp(str, "duplicate") == 0)
1483                                 policy = SND_PCM_LADSPA_POLICY_DUPLICATE;
1484                         else {
1485                                 SNDERR("unknown policy definition");
1486                                 return -EINVAL;
1487                         }
1488                         continue;
1489                 }
1490         }
1491         if (label == NULL && ladspa_id <= 0) {
1492                 SNDERR("no plugin label or id");
1493                 return -EINVAL;
1494         }
1495         lplug = (snd_pcm_ladspa_plugin_t *)calloc(1, sizeof(snd_pcm_ladspa_plugin_t));
1496         if (lplug == NULL)
1497                 return -ENOMEM;
1498         lplug->policy = policy;
1499         lplug->input.pdesc = LADSPA_PORT_INPUT;
1500         lplug->output.pdesc = LADSPA_PORT_OUTPUT;
1501         INIT_LIST_HEAD(&lplug->instances);
1502         if (filename) {
1503                 err = snd_pcm_ladspa_check_file(lplug, filename, label, ladspa_id);
1504                 if (err < 0) {
1505                         SNDERR("Unable to load plugin '%s' ID %li, filename '%s'", label, ladspa_id, filename);
1506                         free(lplug);
1507                         return err;
1508                 }
1509         } else {
1510                 err = snd_pcm_ladspa_look_for_plugin(lplug, path, label, ladspa_id);
1511                 if (err < 0) {
1512                         SNDERR("Unable to find or load plugin '%s' ID %li, path '%s'", label, ladspa_id, path);
1513                         free(lplug);
1514                         return err;
1515                 }
1516         }
1517         if (!reverse) {
1518                 list_add_tail(&lplug->list, list);
1519         } else {
1520                 list_add(&lplug->list, list);
1521         }
1522         err = snd_pcm_ladspa_parse_ioconfig(lplug, &lplug->input, input);
1523         if (err < 0)
1524                 return err;
1525         err = snd_pcm_ladspa_parse_ioconfig(lplug, &lplug->output, output);
1526         if (err < 0)
1527                 return err;
1528         return 0;
1529 }
1530
1531 static int snd_pcm_ladspa_build_plugins(struct list_head *list,
1532                                         const char *path,
1533                                         snd_config_t *plugins,
1534                                         int reverse)
1535 {
1536         snd_config_iterator_t i, next;
1537         int idx = 0, hit, err;
1538
1539         if (plugins == NULL)    /* nothing TODO */
1540                 return 0;
1541         if (snd_config_get_type(plugins) != SND_CONFIG_TYPE_COMPOUND) {
1542                 SNDERR("plugins must be defined inside a compound");
1543                 return -EINVAL;
1544         }
1545         do {
1546                 hit = 0;
1547                 snd_config_for_each(i, next, plugins) {
1548                         snd_config_t *n = snd_config_iterator_entry(i);
1549                         const char *id;
1550                         long i;
1551                         if (snd_config_get_id(n, &id) < 0)
1552                                 continue;
1553                         err = safe_strtol(id, &i);
1554                         if (err < 0) {
1555                                 SNDERR("id of field %s is not an integer", id);
1556                                 return err;
1557                         }
1558                         if (i == idx) {
1559                                 idx++;
1560                                 err = snd_pcm_ladspa_add_plugin(list, path, n, reverse);
1561                                 if (err < 0)
1562                                         return err;
1563                                 hit = 1;
1564                         }
1565                 }
1566         } while (hit);
1567         if (list_empty(list)) {
1568                 SNDERR("empty plugin list is not accepted");
1569                 return -EINVAL;
1570         }
1571         return 0;
1572 }
1573
1574 /**
1575  * \brief Creates a new LADSPA<->ALSA Plugin
1576  * \param pcmp Returns created PCM handle
1577  * \param name Name of PCM
1578  * \param ladspa_path The path for LADSPA plugins
1579  * \param channels Force input channel count to LADSPA plugin chain, 0 = no force (auto)
1580  * \param ladspa_pplugins The playback configuration
1581  * \param ladspa_cplugins The capture configuration
1582  * \param slave Slave PCM handle
1583  * \param close_slave When set, the slave PCM handle is closed with copy PCM
1584  * \retval zero on success otherwise a negative error code
1585  * \warning Using of this function might be dangerous in the sense
1586  *          of compatibility reasons. The prototype might be freely
1587  *          changed in future.
1588  */
1589 int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
1590                         const char *ladspa_path,
1591                         unsigned int channels,
1592                         snd_config_t *ladspa_pplugins,
1593                         snd_config_t *ladspa_cplugins,
1594                         snd_pcm_t *slave, int close_slave)
1595 {
1596         snd_pcm_t *pcm;
1597         snd_pcm_ladspa_t *ladspa;
1598         int err, reverse = 0;
1599
1600         assert(pcmp && (ladspa_pplugins || ladspa_cplugins) && slave);
1601
1602         if (!ladspa_path && !(ladspa_path = getenv("LADSPA_PATH")))
1603                 return -ENOENT;
1604         ladspa = calloc(1, sizeof(snd_pcm_ladspa_t));
1605         if (!ladspa)
1606                 return -ENOMEM;
1607         snd_pcm_plugin_init(&ladspa->plug);
1608         ladspa->plug.init = snd_pcm_ladspa_init;
1609         ladspa->plug.read = snd_pcm_ladspa_read_areas;
1610         ladspa->plug.write = snd_pcm_ladspa_write_areas;
1611         ladspa->plug.undo_read = snd_pcm_plugin_undo_read_generic;
1612         ladspa->plug.undo_write = snd_pcm_plugin_undo_write_generic;
1613         ladspa->plug.gen.slave = slave;
1614         ladspa->plug.gen.close_slave = close_slave;
1615
1616         INIT_LIST_HEAD(&ladspa->pplugins);
1617         INIT_LIST_HEAD(&ladspa->cplugins);
1618         ladspa->channels = channels;
1619
1620         if (slave->stream == SND_PCM_STREAM_PLAYBACK) {
1621                 err = snd_pcm_ladspa_build_plugins(&ladspa->pplugins, ladspa_path, ladspa_pplugins, reverse);
1622                 if (err < 0) {
1623                         snd_pcm_ladspa_free(ladspa);
1624                         return err;
1625                 }
1626         }
1627         if (slave->stream == SND_PCM_STREAM_CAPTURE) {
1628                 if (ladspa_cplugins == ladspa_pplugins)
1629                         reverse = 1;
1630                 err = snd_pcm_ladspa_build_plugins(&ladspa->cplugins, ladspa_path, ladspa_cplugins, reverse);
1631                 if (err < 0) {
1632                         snd_pcm_ladspa_free(ladspa);
1633                         return err;
1634                 }
1635         }
1636
1637         err = snd_pcm_new(&pcm, SND_PCM_TYPE_LADSPA, name, slave->stream, slave->mode);
1638         if (err < 0) {
1639                 snd_pcm_ladspa_free(ladspa);
1640                 return err;
1641         }
1642         pcm->ops = &snd_pcm_ladspa_ops;
1643         pcm->fast_ops = &snd_pcm_plugin_fast_ops;
1644         pcm->private_data = ladspa;
1645         pcm->poll_fd = slave->poll_fd;
1646         pcm->poll_events = slave->poll_events;
1647         pcm->monotonic = slave->monotonic;
1648         snd_pcm_set_hw_ptr(pcm, &ladspa->plug.hw_ptr, -1, 0);
1649         snd_pcm_set_appl_ptr(pcm, &ladspa->plug.appl_ptr, -1, 0);
1650         *pcmp = pcm;
1651
1652         return 0;
1653 }
1654
1655 /*! \page pcm_plugins
1656
1657 \section pcm_plugins_ladpsa Plugin: LADSPA <-> ALSA
1658
1659 This plugin allows to apply a set of LADPSA plugins.
1660 The input and output format is always #SND_PCM_FORMAT_FLOAT (note: this type
1661 can be either little or big-endian depending on architecture).
1662
1663 The policy duplicate means that there must be only one binding definition for
1664 channel zero. This definition is automatically duplicated for all channels.
1665 If the LADSPA plugin has multiple audio inputs or outputs the policy duplicate
1666 is automatically switched to policy none.
1667
1668 The plugin serialization works as expected. You can eventually use more
1669 channels (inputs / outputs) inside the LADPSA plugin chain than processed
1670 in the ALSA plugin chain. If ALSA channel does not exist for given LADSPA
1671 input audio port, zero samples are given to this LADSPA port. On the output
1672 side (ALSA next plugin input), the valid channels are checked, too.
1673 If specific ALSA channel does not exist, the LADSPA output port is
1674 connected to a dummy sample area.
1675
1676 Instances of LADSPA plugins are created dynamically.
1677
1678 \code
1679 pcm.name {
1680         type ladspa             # ALSA<->LADSPA PCM
1681         slave STR               # Slave name
1682         # or
1683         slave {                 # Slave definition
1684                 pcm STR         # Slave PCM name
1685                 # or
1686                 pcm { }         # Slave PCM definition
1687         }
1688         [channels INT]          # count input channels (input to LADSPA plugin chain)
1689         [path STR]              # Path (directory) with LADSPA plugins
1690         plugins |               # Definition for both directions
1691         playback_plugins |      # Definition for playback direction
1692         capture_plugins {       # Definition for capture direction
1693                 N {             # Configuration for LADPSA plugin N
1694                         [id INT]        # LADSPA plugin ID (for example 1043)
1695                         [label STR]     # LADSPA plugin label (for example 'delay_5s')
1696                         [filename STR]  # Full filename of .so library with LADSPA plugin code
1697                         [policy STR]    # Policy can be 'none' or 'duplicate'
1698                         input | output {
1699                                 bindings {
1700                                         C INT or STR    # C - channel, INT - audio port index, STR - audio port name
1701                                 }
1702                                 controls {
1703                                         # valid only in the input block
1704                                         I INT or REAL   # I - control port index, INT or REAL - control value
1705                                         # or
1706                                         STR INT or REAL # STR - control port name, INT or REAL - control value
1707                                 }
1708                         }
1709                 }
1710         }
1711 }
1712 \endcode
1713
1714 \subsection pcm_plugins_ladspa_funcref Function reference
1715
1716 <UL>
1717   <LI>snd_pcm_ladspa_open()
1718   <LI>_snd_pcm_ladspa_open()
1719 </UL>
1720
1721 */
1722
1723 /**
1724  * \brief Creates a new LADSPA<->ALSA PCM
1725  * \param pcmp Returns created PCM handle
1726  * \param name Name of PCM
1727  * \param root Root configuration node
1728  * \param conf Configuration node with LADSPA<->ALSA PCM description
1729  * \param stream Stream type
1730  * \param mode Stream mode
1731  * \retval zero on success otherwise a negative error code
1732  * \warning Using of this function might be dangerous in the sense
1733  *          of compatibility reasons. The prototype might be freely
1734  *          changed in future.
1735  */
1736 int _snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
1737                          snd_config_t *root, snd_config_t *conf, 
1738                          snd_pcm_stream_t stream, int mode)
1739 {
1740         snd_config_iterator_t i, next;
1741         int err;
1742         snd_pcm_t *spcm;
1743         snd_config_t *slave = NULL, *sconf;
1744         const char *path = NULL;
1745         long channels = 0;
1746         snd_config_t *plugins = NULL, *pplugins = NULL, *cplugins = NULL;
1747         snd_config_for_each(i, next, conf) {
1748                 snd_config_t *n = snd_config_iterator_entry(i);
1749                 const char *id;
1750                 if (snd_config_get_id(n, &id) < 0)
1751                         continue;
1752                 if (snd_pcm_conf_generic_id(id))
1753                         continue;
1754                 if (strcmp(id, "slave") == 0) {
1755                         slave = n;
1756                         continue;
1757                 }
1758                 if (strcmp(id, "path") == 0) {
1759                         snd_config_get_string(n, &path);
1760                         continue;
1761                 }
1762                 if (strcmp(id, "channels") == 0) {
1763                         snd_config_get_integer(n, &channels);
1764                         if (channels > 1024)
1765                                 channels = 1024;
1766                         if (channels < 0)
1767                                 channels = 0;
1768                         continue;
1769                 }
1770                 if (strcmp(id, "plugins") == 0) {
1771                         plugins = n;
1772                         continue;
1773                 }
1774                 if (strcmp(id, "playback_plugins") == 0) {
1775                         pplugins = n;
1776                         continue;
1777                 }
1778                 if (strcmp(id, "capture_plugins") == 0) {
1779                         cplugins = n;
1780                         continue;
1781                 }
1782                 SNDERR("Unknown field %s", id);
1783                 return -EINVAL;
1784         }
1785         if (!slave) {
1786                 SNDERR("slave is not defined");
1787                 return -EINVAL;
1788         }
1789         if (plugins) {
1790                 if (pplugins || cplugins) {
1791                         SNDERR("'plugins' definition cannot be combined with 'playback_plugins' or 'capture_plugins'");
1792                         return -EINVAL;
1793                 }
1794                 pplugins = plugins;
1795                 cplugins = plugins;
1796         }
1797         err = snd_pcm_slave_conf(root, slave, &sconf, 0);
1798         if (err < 0)
1799                 return err;
1800         err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode, conf);
1801         snd_config_delete(sconf);
1802         if (err < 0)
1803                 return err;
1804         err = snd_pcm_ladspa_open(pcmp, name, path, channels, pplugins, cplugins, spcm, 1);
1805         if (err < 0)
1806                 snd_pcm_close(spcm);
1807         return err;
1808 }
1809 #ifndef DOC_HIDDEN
1810 SND_DLSYM_BUILD_VERSION(_snd_pcm_ladspa_open, SND_PCM_DLSYM_VERSION);
1811 #endif