Package: swh-plugins Version: 0.4.15+1-6+fh1 Severity: normal Tags: upstream patch
The analogueOsc plugin produces NaN under some conditions. The attached test program (linking directly to the plugin for simplicity, but it's the same when loading it dynamically), running on amd64, shows the bug: % gcc osc-test.c /usr/lib/ladspa/analogue_osc_1416.so -Wl,-R/usr/lib/ladspa && ./a.out NaN 45602 The bug is due to a 0.0/0.0 division. Ironically, the code checks for "the case where x ~= q", but misses the case where x == q exactly, since nan, unlike inf, is not greater than anything. Of course, according to Murphy's law, FP numbers are never equal, unless you want them to be unequal. ;) I had used the plugin for years on x86 and never seen this problem. The difference might be due to the extended precision of the x87 vs. XMM registers. The attached patch fixes this particular problem. I'm not sure if checking isnan() is really the best solution, but it's least invasive and won't break anything else.
#include <stdio.h> #include <ladspa.h> int main () { int n; const LADSPA_Descriptor *d = ladspa_descriptor (0); LADSPA_Handle h = d->instantiate (d, 44100); LADSPA_Data w = 2, f = 440, a = 0.2, i = 0.2, b[512]; d->connect_port (h, 0, &w); d->connect_port (h, 1, &f); d->connect_port (h, 2, &a); d->connect_port (h, 3, &i); d->connect_port (h, 4, b); if (d->activate) d->activate (h); for (n = 0; n < 50000; n++) { d->run (h, 512); if (isnan (b[0])) { printf ("NaN %i\n", n); return 1; } } printf ("OK\n"); }
--- analogue_osc_1416.xml 2009-07-28 23:18:16.000000000 +0400 +++ analogue_osc_1416.xml 2015-03-31 17:02:57.345738899 +0300 @@ -62,7 +62,7 @@ y = (x - q) / (1.0f - f_exp(-1.2f * (x - q))) + q / (1.0f - f_exp(1.2f * q)); /* Catch the case where x ~= q */ - if (fabs(y) > 1.0f) { + if (isnan(y) || fabs(y) > 1.0f) { y = 0.83333f + q / (1.0f - f_exp(1.2f * q)); } otm2 = otm1;