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

Gabriel M. Beddingfield gabrbedd at gmail.com
Fri Jan 28 03:00:51 UTC 2011


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;


More information about the Linux-audio-user mailing list