Re: [LAU] OT(ish): Strange coding problem (audio related)

From: Gabriel M. Beddingfield <gabrbedd@email-addr-hidden>
Date: Fri Jan 28 2011 - 05:00:51 EET

Hi James,

You always know how to nerd snipe me!

On Thursday, January 27, 2011 06:35:08 pm James Stone wrote:
> I have been working on the Neil tracker program recently,
> and hit a weird bug that seems to affect only my
> computer! I get a segfault when trying to use fft.h

Not just you. It segfaults for me, too. Ubuntu 10.04 with Core Duo
processor.

With the patch below (to fft.h) I detect that p2r and p2i overrun the
buffer when k==11, j==0, i==0. However, k was supposed to STOP when
it reached 11 = log(2048)/log(2).

My guess is that is that the integer k is promoted to a float and the
comparison is performed. When I replace:

   for (k = 0, le = 2; k < log(fftFrameSize)/log(2.); k++) {

with:

   long ITERS = log(fftFrameSize)/log(2.0) + 0.5;
   for (k = 0, le = 2; k < ITERS; k++) {

...the code doesn't crash on me. Here's a sample program that
illustrates what's happening.

/* BEGIN */
#include <cmath>
#include <iostream>
using namespace std;

#define ITERS (log(2048)/log(2.0))

int main(void)
{
    long k;

    for( k=0 ; k < ITERS ; ++k ) {
        cout << "k = " << k
             << " ITERS = " << ITERS
             << " diff = " << (ITERS - k)
             << endl;
    }

    return 0;
}
/* END */

Output on my machine:

k = 0 ITERS = 11 diff = 11
k = 1 ITERS = 11 diff = 10
k = 2 ITERS = 11 diff = 9
k = 3 ITERS = 11 diff = 8
k = 4 ITERS = 11 diff = 7
k = 5 ITERS = 11 diff = 6
k = 6 ITERS = 11 diff = 5
k = 7 ITERS = 11 diff = 4
k = 8 ITERS = 11 diff = 3
k = 9 ITERS = 11 diff = 2
k = 10 ITERS = 11 diff = 1
k = 11 ITERS = 11 diff = 4.80518e-16

Thanks,
Gabriel

Here's the testing patch....

--- a/fft.h
+++ b/fft.h
@@ -1,5 +1,7 @@
 #define M_PI 3.14159265358979323846
 
+#include <assert.h>
+
 void IFFT(float *fftBuffer, long fftFrameSize, long sign)
 /*
     FFT routine, (C)1996 S.M.Sprenger. Sign = -1 is FFT, 1 is iFFT
(inverse)
@@ -17,6 +19,7 @@ void IFFT(float *fftBuffer, long fftFrameSize, long
sign)
    float tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
    long i, bitm, j, le, le2, k;
 
+
    for (i = 2; i < 2 * fftFrameSize - 2; i += 2) {
      for (bitm = 2, j = 0; bitm < 2 * fftFrameSize; bitm <<= 1) {
        if (i & bitm) j++;
@@ -48,6 +51,10 @@ void IFFT(float *fftBuffer, long fftFrameSize, long
sign)
        p2r = p1r+le2;
        p2i = p2r+1;
        for (i = j; i < 2 * fftFrameSize; i += le) {
+ assert(p1r < (fftBuffer + 2 * fftFrameSize));
+ assert(p1i < (fftBuffer + 2 * fftFrameSize));
+ assert(p2r < (fftBuffer + 2 * fftFrameSize));
+ assert(p2i < (fftBuffer + 2 * fftFrameSize));
          tr = *p2r * ur - *p2i * ui;
          ti = *p2r * ui + *p2i * ur;
          *p2r = *p1r - tr;
_______________________________________________
Linux-audio-user mailing list
Linux-audio-user@email-addr-hidden
http://lists.linuxaudio.org/listinfo/linux-audio-user
Received on Fri Jan 28 08:15:02 2011

This archive was generated by hypermail 2.1.8 : Fri Jan 28 2011 - 08:15:02 EET