I’m using libresample at program. After some time (about 50 min) it crashes in lib’s function lrsFilterUD() at one workstation.
float lrsFilterUD(float Imp[], /* impulse response */
float ImpD[], /* impulse response deltas */
UWORD Nwing, /* len of one wing of filter */
BOOL Interp, /* Interpolate coefs using deltas? */
float *Xp, /* Current sample */
double Ph, /* Phase */
int Inc, /* increment (1 for right wing or -1 for left) */
double dhb)
{
float a;
float *Hp, *Hdp, *End;
float v, t;
double Ho;
v = 0.0; /* The output value */
Ho = Ph*dhb;
End = &Imp[Nwing];
if (Inc == 1) /* If doing right wing... */
{ /* ...drop extra coeff, so when Ph is */
End--; /* 0.5, we don't do too many mult's */
if (Ph == 0) /* If the phase is zero... */
Ho += dhb; /* ...then we've already skipped the */
} /* first sample, so we must also */
/* skip ahead in Imp[] and ImpD[] */
if (Interp)
while ((Hp = &Imp[(int)Ho]) < End) {
t = *Hp; /* Get IR sample */
Hdp = &ImpD[(int)Ho]; /* get interp bits from diff table*/
a = Ho - floor(Ho); /* a is logically between 0 and 1 */
t += (*Hdp)*a; /* t is now interp'd filter coeff */
t *= *Xp; /* Mult coeff by input sample */
v += t; /* The filter output */
Ho += dhb; /* IR step */
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
}
else
while ((Hp = &Imp[(int)Ho]) < End) {
dprintf("while begin: Hp = %p, *Hp = %a, (int)Ho = %d, Imp[(int)Ho] = %a, &Imp[(int)Ho] = %p", Hp, *Hp, (int)Ho, Imp[(int)Ho], &Imp[(int)Ho]);
t = *Hp; /* Get IR sample */
dprintf("before t = %a, *Xp = %a, Xp = %p", t, *Xp, Xp);
t *= *Xp; /* Mult coeff by input sample */
dprintf("after2 t = %a, v = %a", t, v);
v += t; /* The filter output */
dprintf("v = %a", v);
Ho += dhb; /* IR step */
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
}
return v;
}
I logged values of t, *Xp, Xp before and after multiplication:
while begin: Hp = 0xaf5daa8, *Hp = -0.009034, (int)Ho = 16384, Imp[(int)Ho] = -0.009034, &Imp[(int)Ho] = 0xaf5daa8
before multiplication t = -0.009034, *Xp = 0.000000, Xp = 0xaebe9b8
after multiplication t = nan
This code run many times, there are the same t and Xp values before crash:
before multiplication t = -0.009034, *Xp = 0.000000, Xp = 0xaebe9c8
after multiplication t = -0.000000, v = 282.423676
Or another case with addition:
before addition t = -460.799988, v = 0.000000
after addition v = nan
What could be causing nan? This is compiled with gcc 4.1.2 on Linux.
Update: Print variables as %a. Result:
//t = 0x1.2806bap+2
//Hp = 0xb3bb870
t = *Hp;
//t = nan
Update 2: There is no such issue if code is compiled by icpc. So is there compiler specific issue?
Clearly, -0.009034•0.000000 should not produce NaN. Therefore, either the code and data presented in the problem is not an accurate representation of the actual computation, or the computing implementation is defective.
If we assume the hardware and basic computing implementation is not defective, then some possibilities to investigate include:
tand*Xpfailed to log the correct values oftand*Xpimmediately before the multiplication or the correct value oftimmediately after the multiplication.tor*Xpare incorrect. E.g., the formatting used to display*Xpshowed “0.000000” even though*Xphad some other value, such as NaN.Xppoints somewhere inappropriate, resulting in*Xpbeing unreliable (e.g., changed by external operations).Note: When debugging with floating-point objects, you should not print with formats such as “%f”, especially not with default values for numbers of digits. You should print with “%a”, which prints the exact value of a floating-point value, using a hexadecimal representation. You may also use “%.99g” in many situations, provided your C implementation provides a good conversion of the floating-point value to decimal.