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

James Stone jamesmstone at gmail.com
Fri Jan 28 00:35:08 UTC 2011


Hi All,

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 (which is used by the oomek 303 emulator, which has 
incidentally now been released as open source - a really good sound 
IMHO, but I digress). The following test code results in a segfault on 
my computer - an AMD XP2500+ (but no-one elses as far as I can tell).

bt:

Program received signal SIGSEGV, Segmentation fault.
0x080486d7 in IFFT (fftBuffer=0x8049b00, fftFrameSize=2048, sign=1) at 
fft.h:51
51              tr = *p2r * ur - *p2i * ui;

Any thoughts as to what might be happening?

James

test.cpp:

#include <cstdio>
#include <cmath>
#include "fft.h"

float a[4096];

int main ()
{
for(int i=0; i<4096; i++)
{
a[i]=0;
}
IFFT(a,2048,1);
printf("%f",a[1]);
}

fft.h:
#define M_PI 3.14159265358979323846

void IFFT(float *fftBuffer, long fftFrameSize, long sign)
/*
    FFT routine, (C)1996 S.M.Sprenger. Sign = -1 is FFT, 1 is iFFT (inverse)
    Fills fftBuffer[0...2*fftFrameSize-1] with the Fourier transform of the
    time domain data in fftBuffer[0...2*fftFrameSize-1]. The FFT array takes
    and returns the cosine and sine parts in an interleaved manner, ie.
    fftBuffer[0] = cosPart[0], fftBuffer[1] = sinPart[0], asf. fftFrameSize
    must be a power of 2. It expects a complex input signal (see 
footnote 2),
    ie. when working with 'common' audio signals our input signal has to be
    passed as {in[0],0.,in[1],0.,in[2],0.,...} asf. In that case, the 
transform
    of the frequencies of interest is in fftBuffer[0...fftFrameSize].
*/
{
   float wr, wi, arg, *p1, *p2, temp;
   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++;
       j <<= 1;
     }
     if (i < j)
       {
         p1 = fftBuffer + i;
         p2 = fftBuffer + j;
         temp = *p1;
         *(p1++) = *p2;
         *(p2++) = temp;
         temp = *p1;
         *p1 = *p2;
         *p2 = temp;
       }
   }
   for (k = 0, le = 2; k < log(fftFrameSize)/log(2.); k++) {
     le <<= 1;
     le2 = le>>1;
     ur = 1.0;
     ui = 0.0;
     arg = (float)M_PI / (le2>>1);
     wr = (float)cos(arg);
     wi = sign*(float)sin(arg);
     for (j = 0; j < le2; j += 2) {
       p1r = fftBuffer+j;
       p1i = p1r+1;
       p2r = p1r+le2;
       p2i = p2r+1;
       for (i = j; i < 2 * fftFrameSize; i += le) {
         tr = *p2r * ur - *p2i * ui;
         ti = *p2r * ui + *p2i * ur;
         *p2r = *p1r - tr;
         *p2i = *p1i - ti;
         *p1r += tr;
         *p1i += ti;
         p1r += le;
         p1i += le;
         p2r += le;
         p2i += le;
       }
       tr = ur*wr - ui*wi;
       ui = ur*wi + ui*wr;
       ur = tr;
     }
   }
}




More information about the Linux-audio-user mailing list