[alsa-devel] alsa-lib: pcm_plug: fix float conversion for user specified ttable
Move custom ttable with equal channels case from a separate ttable_last exception into a common plugins insertion loop. Fixes plug with ttable for float pcms (jack, ladspa). Example: aplay -fFLOAT_LE /dev/zero pcm.!default { type plug slave.pcm { type null } ttable.0.0 1 } --- src/pcm/pcm_plug.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index ede9c15..6d0454f 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -53,7 +53,7 @@ typedef struct { const snd_config_t *rate_converter; enum snd_pcm_plug_route_policy route_policy; snd_pcm_route_ttable_entry_t *ttable; - int ttable_ok, ttable_last; + int ttable_ok; unsigned int tt_ssize, tt_cused, tt_sused; } snd_pcm_plug_t;
@@ -380,7 +380,7 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm snd_pcm_route_ttable_entry_t *ttable; int err; if (clt->channels == slv->channels && - (!plug->ttable || !plug->ttable_last)) + (!plug->ttable || plug->ttable_ok)) return 0; if (clt->rate != slv->rate && clt->channels > slv->channels) @@ -485,13 +485,15 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p /* No conversion is needed */ if (clt->format == slv->format && clt->rate == slv->rate && - clt->channels == slv->channels) + clt->channels == slv->channels && + (!plug->ttable || plug->ttable_ok)) return 0;
if (snd_pcm_format_linear(slv->format)) { /* Conversion is done in another plugin */ if (clt->rate != slv->rate || - clt->channels != slv->channels) + clt->channels != slv->channels || + (plug->ttable && !plug->ttable_ok)) return 0; cfmt = clt->format; switch (clt->format) { @@ -525,7 +527,8 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p if (snd_pcm_format_linear(clt->format)) { cfmt = clt->format; f = snd_pcm_lfloat_open; - } else if (clt->rate != slv->rate || clt->channels != slv->channels) { + } else if (clt->rate != slv->rate || clt->channels != slv->channels || + (plug->ttable && !plug->ttable_ok)) { cfmt = SND_PCM_FORMAT_S16; f = snd_pcm_lfloat_open; } else @@ -641,11 +644,12 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm, }; snd_pcm_plug_params_t p = *slave; unsigned int k = 0; - plug->ttable_ok = plug->ttable_last = 0; + plug->ttable_ok = 0; while (client->format != p.format || client->channels != p.channels || client->rate != p.rate || - client->access != p.access) { + client->access != p.access || + (plug->ttable && !plug->ttable_ok)) { snd_pcm_t *new; int err; if (k >= sizeof(funcs)/sizeof(*funcs)) @@ -660,24 +664,6 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm, } k++; } -#ifdef BUILD_PCM_PLUGIN_ROUTE - /* it's exception, user specified ttable, but no reduction/expand */ - if (plug->ttable && !plug->ttable_ok) { - snd_pcm_t *new; - int err; - plug->ttable_last = 1; - err = snd_pcm_plug_change_channels(pcm, &new, client, &p); - if (err < 0) { - snd_pcm_plug_clear(pcm); - return err; - } - assert(err); - assert(plug->ttable_ok); - plug->gen.slave = new; - pcm->fast_ops = new->fast_ops; - pcm->fast_op_arg = new->fast_op_arg; - } -#endif return 0; }
2014-6-16 下午11:53 於 "Sergey" sergemp@mail.ru 寫道:
Move custom ttable with equal channels case from a separate ttable_last exception into a common plugins insertion loop. Fixes plug with ttable for float pcms (jack, ladspa). Example: aplay -fFLOAT_LE /dev/zero pcm.!default { type plug slave.pcm { type null } ttable.0.0 1 }
Any reason to use type null in your test case since type null seem can support all format ?
June 17 2014 Raymond Yau wrote:
Move custom ttable with equal channels case from a separate ttable_last exception into a common plugins insertion loop. Fixes plug with ttable for float pcms (jack, ladspa). Example: aplay -fFLOAT_LE /dev/zero pcm.!default { type plug slave.pcm { type null } ttable.0.0 1 }
Any reason to use type null in your test case since type null seem can support all format ?
It was the shortest test to reproduce the bug.
A more restricted config: # aplay -fFLOAT_LE /dev/zero pcm.!default { type plug slave.pcm { type null } slave.format FLOAT_LE ttable.0.0 1 } But that test was enough to reproduce "Assertion failed" bug too.
Actually I've hit this bug with a complex ladspa upmixing code: pcm.upmix { type plug slave.pcm { type ladspa slave.pcm { type plug slave.pcm "..." ttable { ... } } plugins [ ... ] } ttable { ... } } similar to this: http://forums.gentoo.org/viewtopic-p-4528619.html#4528619
This bug crashed the application for me (it generates SIGABRT) so I thought that it should be fixed.
Date 16.6.2014 17:52, Sergey wrote:
Move custom ttable with equal channels case from a separate ttable_last exception into a common plugins insertion loop. Fixes plug with ttable for float pcms (jack, ladspa). Example: aplay -fFLOAT_LE /dev/zero pcm.!default { type plug slave.pcm { type null } ttable.0.0 1 }
src/pcm/pcm_plug.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index ede9c15..6d0454f 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -53,7 +53,7 @@ typedef struct { const snd_config_t *rate_converter; enum snd_pcm_plug_route_policy route_policy; snd_pcm_route_ttable_entry_t *ttable;
- int ttable_ok, ttable_last;
- int ttable_ok; unsigned int tt_ssize, tt_cused, tt_sused;
} snd_pcm_plug_t;
@@ -380,7 +380,7 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm snd_pcm_route_ttable_entry_t *ttable; int err; if (clt->channels == slv->channels &&
(!plug->ttable || !plug->ttable_last))
return 0; if (clt->rate != slv->rate && clt->channels > slv->channels)(!plug->ttable || plug->ttable_ok))
@@ -485,13 +485,15 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p /* No conversion is needed */ if (clt->format == slv->format && clt->rate == slv->rate &&
clt->channels == slv->channels)
clt->channels == slv->channels &&
(!plug->ttable || plug->ttable_ok))
return 0;
if (snd_pcm_format_linear(slv->format)) { /* Conversion is done in another plugin */ if (clt->rate != slv->rate ||
clt->channels != slv->channels)
clt->channels != slv->channels ||
cfmt = clt->format; switch (clt->format) {(plug->ttable && !plug->ttable_ok)) return 0;
@@ -525,7 +527,8 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p if (snd_pcm_format_linear(clt->format)) { cfmt = clt->format; f = snd_pcm_lfloat_open;
} else if (clt->rate != slv->rate || clt->channels != slv->channels) {
} else if (clt->rate != slv->rate || clt->channels != slv->channels ||
} else(plug->ttable && !plug->ttable_ok)) { cfmt = SND_PCM_FORMAT_S16; f = snd_pcm_lfloat_open;
@@ -641,11 +644,12 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm, }; snd_pcm_plug_params_t p = *slave; unsigned int k = 0;
- plug->ttable_ok = plug->ttable_last = 0;
- plug->ttable_ok = 0; while (client->format != p.format || client->channels != p.channels || client->rate != p.rate ||
client->access != p.access) {
client->access != p.access ||
snd_pcm_t *new; int err; if (k >= sizeof(funcs)/sizeof(*funcs))(plug->ttable && !plug->ttable_ok)) {
@@ -660,24 +664,6 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm, } k++; } -#ifdef BUILD_PCM_PLUGIN_ROUTE
- /* it's exception, user specified ttable, but no reduction/expand */
- if (plug->ttable && !plug->ttable_ok) {
snd_pcm_t *new;
int err;
plug->ttable_last = 1;
err = snd_pcm_plug_change_channels(pcm, &new, client, &p);
if (err < 0) {
snd_pcm_plug_clear(pcm);
return err;
}
assert(err);
assert(plug->ttable_ok);
plug->gen.slave = new;
pcm->fast_ops = new->fast_ops;
pcm->fast_op_arg = new->fast_op_arg;
- }
-#endif return 0; }
Thanks. Looks good. Applied.
Jaroslav
participants (3)
-
Jaroslav Kysela
-
Raymond Yau
-
Sergey