rate: add some sanity checking
[sox.git] / src / ladspa.c
blob374e2e5bfbdbdef1fb021012bc521830a4423691
1 /* LADSPA effect support for sox
2 * (c) Reuben Thomas <rrt@sc3d.org> 2007
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or (at
7 * your option) any later version.
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
12 * General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #include "sox_i.h"
21 #ifdef HAVE_LADSPA_H
23 #include <assert.h>
24 #include <limits.h>
25 #include <string.h>
26 #include <math.h>
27 #include "ladspa.h"
30 * Assuming LADSPA_Data == float. This is the case in 2012 and has been
31 * the case for many years now.
33 #define SOX_SAMPLE_TO_LADSPA_DATA(d,clips) \
34 SOX_SAMPLE_TO_FLOAT_32BIT((d),(clips))
35 #define LADSPA_DATA_TO_SOX_SAMPLE(d,clips) \
36 SOX_FLOAT_32BIT_TO_SAMPLE((d),(clips))
38 static sox_effect_handler_t sox_ladspa_effect;
40 /* Private data for resampling */
41 typedef struct {
42 char *name; /* plugin name */
43 lt_dlhandle lth; /* dynamic object handle */
44 sox_bool clone;
45 const LADSPA_Descriptor *desc; /* plugin descriptor */
46 LADSPA_Handle *handles; /* instantiated plugin handles */
47 size_t handle_count;
48 LADSPA_Data *control; /* control ports */
49 unsigned long *inputs;
50 size_t input_count;
51 unsigned long *outputs;
52 size_t output_count;
53 sox_bool latency_compensation;
54 LADSPA_Data *latency_control_port;
55 unsigned long in_latency;
56 unsigned long out_latency;
57 } priv_t;
59 static LADSPA_Data ladspa_default(const LADSPA_PortRangeHint *p)
61 LADSPA_Data d;
63 if (LADSPA_IS_HINT_DEFAULT_0(p->HintDescriptor))
64 d = 0.0;
65 else if (LADSPA_IS_HINT_DEFAULT_1(p->HintDescriptor))
66 d = 1.0;
67 else if (LADSPA_IS_HINT_DEFAULT_100(p->HintDescriptor))
68 d = 100.0;
69 else if (LADSPA_IS_HINT_DEFAULT_440(p->HintDescriptor))
70 d = 440.0;
71 else if (LADSPA_IS_HINT_DEFAULT_MINIMUM(p->HintDescriptor))
72 d = p->LowerBound;
73 else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(p->HintDescriptor))
74 d = p->UpperBound;
75 else if (LADSPA_IS_HINT_DEFAULT_LOW(p->HintDescriptor)) {
76 if (LADSPA_IS_HINT_LOGARITHMIC(p->HintDescriptor))
77 d = exp(log(p->LowerBound) * 0.75 + log(p->UpperBound) * 0.25);
78 else
79 d = p->LowerBound * 0.75 + p->UpperBound * 0.25;
80 } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(p->HintDescriptor)) {
81 if (LADSPA_IS_HINT_LOGARITHMIC(p->HintDescriptor))
82 d = exp(log(p->LowerBound) * 0.5 + log(p->UpperBound) * 0.5);
83 else
84 d = p->LowerBound * 0.5 + p->UpperBound * 0.5;
85 } else if (LADSPA_IS_HINT_DEFAULT_HIGH(p->HintDescriptor)) {
86 if (LADSPA_IS_HINT_LOGARITHMIC(p->HintDescriptor))
87 d = exp(log(p->LowerBound) * 0.25 + log(p->UpperBound) * 0.75);
88 else
89 d = p->LowerBound * 0.25 + p->UpperBound * 0.75;
90 } else { /* shouldn't happen */
91 /* FIXME: Deal with this at a higher level */
92 lsx_fail("non-existent default value; using 0.1");
93 d = 0.1; /* Should at least avoid divide by 0 */
96 return d;
100 * Process options
102 static int sox_ladspa_getopts(sox_effect_t *effp, int argc, char **argv)
104 priv_t * l_st = (priv_t *)effp->priv;
105 char *path;
106 int c;
107 union {LADSPA_Descriptor_Function fn; lt_ptr ptr;} ltptr;
108 unsigned long index = 0, i;
109 double arg;
110 lsx_getopt_t optstate;
111 lsx_getopt_init(argc, argv, "+rl", NULL, lsx_getopt_flag_none, 1, &optstate);
113 while ((c = lsx_getopt(&optstate)) != -1) switch (c) {
114 case 'r': l_st->clone = sox_true; break;
115 case 'l': l_st->latency_compensation = sox_true; break;
116 default:
117 lsx_fail("unknown option `-%c'", optstate.opt);
118 return lsx_usage(effp);
120 argc -= optstate.ind, argv += optstate.ind;
122 /* Get module name */
123 if (argc >= 1) {
124 l_st->name = argv[0];
125 argc--; argv++;
128 /* Load module */
129 path = getenv("LADSPA_PATH");
130 if (path == NULL)
131 path = LADSPA_PATH;
133 if(lt_dlinit() || lt_dlsetsearchpath(path)
134 || (l_st->lth = lt_dlopenext(l_st->name)) == NULL) {
135 lsx_fail("could not open LADSPA plugin %s", l_st->name);
136 return SOX_EOF;
139 /* Get descriptor function */
140 if ((ltptr.ptr = lt_dlsym(l_st->lth, "ladspa_descriptor")) == NULL) {
141 lsx_fail("could not find ladspa_descriptor");
142 return SOX_EOF;
145 /* If no plugins in this module, complain */
146 if (ltptr.fn(0UL) == NULL) {
147 lsx_fail("no plugins found");
148 return SOX_EOF;
151 /* Get first plugin descriptor */
152 l_st->desc = ltptr.fn(0UL);
153 assert(l_st->desc); /* We already know this will work */
155 /* If more than one plugin, or first argument is not a number, try
156 to use first argument as plugin label. */
157 if (argc > 0 && (ltptr.fn(1UL) != NULL || !sscanf(argv[0], "%lf", &arg))) {
158 while (l_st->desc && strcmp(l_st->desc->Label, argv[0]) != 0)
159 l_st->desc = ltptr.fn(++index);
160 if (l_st->desc == NULL) {
161 lsx_fail("no plugin called `%s' found", argv[0]);
162 return SOX_EOF;
164 argc--; argv++;
167 /* Scan the ports for inputs and outputs */
168 l_st->control = lsx_calloc(l_st->desc->PortCount, sizeof(LADSPA_Data));
169 l_st->inputs = lsx_malloc(l_st->desc->PortCount * sizeof(unsigned long));
170 l_st->outputs = lsx_malloc(l_st->desc->PortCount * sizeof(unsigned long));
172 for (i = 0; i < l_st->desc->PortCount; i++) {
173 const LADSPA_PortDescriptor port = l_st->desc->PortDescriptors[i];
175 /* Check port is well specified. All control ports should be
176 inputs, but don't bother checking, as we never rely on this. */
177 if (LADSPA_IS_PORT_INPUT(port) && LADSPA_IS_PORT_OUTPUT(port)) {
178 lsx_fail("port %lu is both input and output", i);
179 return SOX_EOF;
180 } else if (LADSPA_IS_PORT_CONTROL(port) && LADSPA_IS_PORT_AUDIO(port)) {
181 lsx_fail("port %lu is both audio and control", i);
182 return SOX_EOF;
185 if (LADSPA_IS_PORT_AUDIO(port)) {
186 if (LADSPA_IS_PORT_INPUT(port)) {
187 l_st->inputs[l_st->input_count++] = i;
188 } else if (LADSPA_IS_PORT_OUTPUT(port)) {
189 l_st->outputs[l_st->output_count++] = i;
191 } else { /* Control port */
192 if (l_st->latency_compensation &&
193 LADSPA_IS_PORT_CONTROL(port) &&
194 LADSPA_IS_PORT_OUTPUT(port) &&
195 strcmp(l_st->desc->PortNames[i], "latency") == 0) {
196 /* automatic latency compensation, Ardour does this, too */
197 l_st->latency_control_port = &l_st->control[i];
198 assert(*l_st->latency_control_port == 0);
199 lsx_debug("latency control port is %lu", i);
200 } else if (argc == 0) {
201 if (!LADSPA_IS_HINT_HAS_DEFAULT(l_st->desc->PortRangeHints[i].HintDescriptor)) {
202 lsx_fail("not enough arguments for control ports");
203 return SOX_EOF;
205 l_st->control[i] = ladspa_default(&(l_st->desc->PortRangeHints[i]));
206 lsx_debug("default argument for port %lu is %f", i, l_st->control[i]);
207 } else {
208 if (!sscanf(argv[0], "%lf", &arg))
209 return lsx_usage(effp);
210 l_st->control[i] = (LADSPA_Data)arg;
211 lsx_debug("argument for port %lu is %f", i, l_st->control[i]);
212 argc--; argv++;
217 /* Stop if we have any unused arguments */
218 return argc? lsx_usage(effp) : SOX_SUCCESS;
222 * Prepare processing.
224 static int sox_ladspa_start(sox_effect_t * effp)
226 priv_t * l_st = (priv_t *)effp->priv;
227 unsigned long i;
228 size_t h;
229 unsigned long rate = (unsigned long)effp->in_signal.rate;
231 /* Instantiate the plugin */
232 lsx_debug("rate for plugin is %g", effp->in_signal.rate);
234 if (l_st->input_count == 1 && l_st->output_count == 1 &&
235 effp->in_signal.channels == effp->out_signal.channels) {
236 /* for mono plugins, they are common */
238 if (!l_st->clone && effp->in_signal.channels > 1) {
239 lsx_fail("expected 1 input channel(s), found %u; consider using -r",
240 effp->in_signal.channels);
241 return SOX_EOF;
245 * create one handle per channel for mono plugins. ecasound does this, too.
246 * mono LADSPA plugins are common and SoX supported mono LADSPA plugins
247 * exclusively for a while.
249 l_st->handles = lsx_malloc(effp->in_signal.channels *
250 sizeof(LADSPA_Handle *));
252 while (l_st->handle_count < effp->in_signal.channels)
253 l_st->handles[l_st->handle_count++] = l_st->desc->instantiate(l_st->desc, rate);
255 } else {
257 * assume the plugin is multi-channel capable with one instance,
258 * Some LADSPA plugins are stereo (e.g. bs2b-ladspa)
261 if (l_st->input_count < effp->in_signal.channels) {
262 lsx_fail("fewer plugin input ports than input channels (%u < %u)",
263 (unsigned)l_st->input_count, effp->in_signal.channels);
264 return SOX_EOF;
267 /* warn if LADSPA audio ports are unused. ecasound does this, too */
268 if (l_st->input_count > effp->in_signal.channels)
269 lsx_warn("more plugin input ports than input channels (%u > %u)",
270 (unsigned)l_st->input_count, effp->in_signal.channels);
273 * some LADSPA plugins increase/decrease the channel count
274 * (e.g. "mixer" in cmt or vocoder):
276 if (l_st->output_count != effp->out_signal.channels) {
277 lsx_debug("changing output channels to match plugin output ports (%u => %u)",
278 effp->out_signal.channels, (unsigned)l_st->output_count);
279 effp->out_signal.channels = l_st->output_count;
282 l_st->handle_count = 1;
283 l_st->handles = lsx_malloc(sizeof(LADSPA_Handle *));
284 l_st->handles[0] = l_st->desc->instantiate(l_st->desc, rate);
287 /* abandon everything completely on any failed handle instantiation */
288 for (h = 0; h < l_st->handle_count; h++) {
289 if (l_st->handles[h] == NULL) {
290 /* cleanup the handles that did instantiate successfully */
291 for (h = 0; l_st->desc->cleanup && h < l_st->handle_count; h++) {
292 if (l_st->handles[h])
293 l_st->desc->cleanup(l_st->handles[h]);
296 free(l_st->handles);
297 l_st->handle_count = 0;
298 lsx_fail("could not instantiate plugin");
299 return SOX_EOF;
303 for (i = 0; i < l_st->desc->PortCount; i++) {
304 const LADSPA_PortDescriptor port = l_st->desc->PortDescriptors[i];
306 if (LADSPA_IS_PORT_CONTROL(port)) {
307 for (h = 0; h < l_st->handle_count; h++)
308 l_st->desc->connect_port(l_st->handles[h], i, &(l_st->control[i]));
312 /* If needed, activate the plugin instances */
313 if (l_st->desc->activate) {
314 for (h = 0; h < l_st->handle_count; h++)
315 l_st->desc->activate(l_st->handles[h]);
318 return SOX_SUCCESS;
322 * Process one bufferful of data.
324 static int sox_ladspa_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
325 size_t *isamp, size_t *osamp)
327 priv_t * l_st = (priv_t *)effp->priv;
328 size_t i, len = min(*isamp, *osamp);
329 size_t j;
330 size_t h;
331 const size_t total_input_count = l_st->input_count * l_st->handle_count;
332 const size_t total_output_count = l_st->output_count * l_st->handle_count;
333 const size_t input_len = len / total_input_count;
334 size_t output_len = len / total_output_count;
336 if (total_output_count < total_input_count)
337 output_len = input_len;
339 *isamp = len;
340 *osamp = 0;
342 if (len) {
343 LADSPA_Data *buf = lsx_calloc(len, sizeof(LADSPA_Data));
344 LADSPA_Data *outbuf = lsx_calloc(len, sizeof(LADSPA_Data));
345 LADSPA_Handle handle;
346 unsigned long port, l;
347 SOX_SAMPLE_LOCALS;
350 * prepare buffer for LADSPA input
351 * deinterleave sox samples and write non-interleaved data to
352 * input_port-specific buffer locations
354 for (i = 0; i < input_len; i++) {
355 for (j = 0; j < total_input_count; j++) {
356 const sox_sample_t s = *ibuf++;
357 buf[j * input_len + i] = SOX_SAMPLE_TO_LADSPA_DATA(s, effp->clips);
361 /* Connect the LADSPA input port(s) to the prepared buffers */
362 for (j = 0; j < total_input_count; j++) {
363 handle = l_st->handles[j / l_st->input_count];
364 port = l_st->inputs[j / l_st->handle_count];
365 l_st->desc->connect_port(handle, port, buf + j * input_len);
368 /* Connect the LADSPA output port(s) if used */
369 for (j = 0; j < total_output_count; j++) {
370 handle = l_st->handles[j / l_st->output_count];
371 port = l_st->outputs[j / l_st->handle_count];
372 l_st->desc->connect_port(handle, port, outbuf + j * output_len);
375 /* Run the plugin for each handle */
376 for (h = 0; h < l_st->handle_count; h++)
377 l_st->desc->run(l_st->handles[h], input_len);
379 /* check the latency control port if we have one */
380 if (l_st->latency_control_port) {
381 lsx_debug("latency detected is %g", *l_st->latency_control_port);
382 l_st->in_latency = (unsigned long)floor(*l_st->latency_control_port);
384 /* we will need this later in sox_ladspa_drain */
385 l_st->out_latency = l_st->in_latency;
387 /* latency for plugins is constant, only compensate once */
388 l_st->latency_control_port = NULL;
391 /* Grab output if effect produces it, re-interleaving it */
392 l = min(output_len, l_st->in_latency);
393 for (i = l; i < output_len; i++) {
394 for (j = 0; j < total_output_count; j++) {
395 LADSPA_Data d = outbuf[j * output_len + i];
396 *obuf++ = LADSPA_DATA_TO_SOX_SAMPLE(d, effp->clips);
397 (*osamp)++;
400 l_st->in_latency -= l;
402 free(outbuf);
403 free(buf);
406 return SOX_SUCCESS;
410 * Nothing to do if the plugin has no latency or latency compensation is
411 * disabled.
413 static int sox_ladspa_drain(sox_effect_t * effp, sox_sample_t *obuf, size_t *osamp)
415 priv_t * l_st = (priv_t *)effp->priv;
416 sox_sample_t *ibuf, *dbuf;
417 size_t isamp, dsamp;
418 int r;
420 if (l_st->out_latency == 0) {
421 *osamp = 0;
422 return SOX_SUCCESS;
425 /* feed some silence at the end to push the rest of the data out */
426 isamp = l_st->out_latency * effp->in_signal.channels;
427 dsamp = l_st->out_latency * effp->out_signal.channels;
428 ibuf = lsx_calloc(isamp, sizeof(sox_sample_t));
429 dbuf = lsx_calloc(dsamp, sizeof(sox_sample_t));
431 r = sox_ladspa_flow(effp, ibuf, dbuf, &isamp, &dsamp);
432 *osamp = min(dsamp, *osamp);
433 memcpy(obuf, dbuf, *osamp * sizeof(sox_sample_t));
435 free(ibuf);
436 free(dbuf);
438 return r == SOX_SUCCESS ? SOX_EOF : 0;
442 * Do anything required when you stop reading samples.
443 * Don't close input file!
445 static int sox_ladspa_stop(sox_effect_t * effp)
447 priv_t * l_st = (priv_t *)effp->priv;
448 size_t h;
450 for (h = 0; h < l_st->handle_count; h++) {
451 /* If needed, deactivate and cleanup the plugin */
452 if (l_st->desc->deactivate)
453 l_st->desc->deactivate(l_st->handles[h]);
454 if (l_st->desc->cleanup)
455 l_st->desc->cleanup(l_st->handles[h]);
457 free(l_st->handles);
458 l_st->handle_count = 0;
460 return SOX_SUCCESS;
463 static int sox_ladspa_kill(sox_effect_t * effp)
465 priv_t * l_st = (priv_t *)effp->priv;
467 free(l_st->control);
468 free(l_st->inputs);
469 free(l_st->outputs);
471 return SOX_SUCCESS;
474 static sox_effect_handler_t sox_ladspa_effect = {
475 "ladspa",
476 "MODULE [PLUGIN] [ARGUMENT...]",
477 SOX_EFF_MCHAN | SOX_EFF_CHAN | SOX_EFF_GAIN,
478 sox_ladspa_getopts,
479 sox_ladspa_start,
480 sox_ladspa_flow,
481 sox_ladspa_drain,
482 sox_ladspa_stop,
483 sox_ladspa_kill,
484 sizeof(priv_t)
487 const sox_effect_handler_t *lsx_ladspa_effect_fn(void)
489 return &sox_ladspa_effect;
492 #endif /* HAVE_LADSPA */