0

This is my first question on stackoverflow and my englsich is unfortunately poor. But I want to try it.

A customized routine of twotonetest of kissfft brings on two different systems very different results.

The under ubuntu translated with gcc on x86 program brings the correct values. That with the openWRT SDK translated for the Arduino YUN (Atheros AR9331) program displays incorrect values​​. It seems as if since the definition of FIXED_POINT is ignored.

Defined is:

#define FIXED_POINT 32

the function:

double GetFreqBuf( tBuf * io_pBuf, int nfft)
{
    kiss_fftr_cfg cfg   = NULL;
    kiss_fft_cpx *kout  = NULL;
    kiss_fft_scalar *tbuf = NULL;
    uint32_t ptr;
    int i;
    double sigpow=0;
    double noisepow=0;
    long maxrange = SHRT_MAX;

    cfg = kiss_fftr_alloc(nfft , 0, NULL, NULL);
    tbuf    = KISS_FFT_MALLOC(nfft * sizeof(kiss_fft_scalar));
    kout    = KISS_FFT_MALLOC(nfft * sizeof(kiss_fft_cpx));

    /* generate the array from samples*/
    for (i = 0; i < nfft; i++) {

        //nur einen Kanal, eine Krücke, würde nun auch mit 2 kanälen gehen, aber so ist schneller
        if (io_pBuf->IndexNextValue >= (i*2))
            ptr = io_pBuf->IndexNextValue - (i*2);
        else
            ptr = io_pBuf->bufSize  - ((i*2) - io_pBuf->IndexNextValue);
         tbuf[i] = io_pBuf->aData[ptr] ;
    }

    kiss_fftr(cfg, tbuf, kout);

    for (i=0;i < (nfft/2+1);++i) {
        double tmpr = (double)kout[i].r / (double)maxrange;
        double tmpi = (double)kout[i].i / (double)maxrange;
        double mag2 = tmpr*tmpr + tmpi*tmpi;
        if (i!=0 && i!= nfft/2)
            mag2 *= 2; /* all bins except DC and Nyquist have symmetric counterparts implied*/

        /* if there is power between the frq's, it is signal, otherwise noise*/
        if ( i > nfft/96 && i < nfft/32 )
            noisepow += mag2;
        else
            sigpow += mag2;
    }

    kiss_fft_cleanup();
    //printf("TEST %d Werte, noisepow: %f sigpow: %f noise @ %fdB\n",nfft,noisepow,sigpow,10*log10(noisepow/sigpow +1e-30) );
   free(cfg);
   free(tbuf);
   free(kout);
    return 10*log10(noisepow/sigpow +1e-30);
}

As input samples of 16-bit sound from the same file be used. Results differ for example from-3dB to-15dB. AWhere could you start troubleshooting?

  • now i define as FIXED_POINT 16 (for the 16-bit Sound ok) and the results are the same ... vg jens – user3432859 Mar 18 '14 at 16:45
  • the actual cause would be a fixed data type assignment I had seen in the code above when writing the post and corrected ... tbuf [i] = (double) io_pBuf-> aData [ptr]; correctly tbuf [i] = io_pBuf-> aData [ptr]; – user3432859 Mar 18 '14 at 16:54

1 Answers1

0

Possibility #1 (most likely)

You are compiling kissfft.c or kiss_fftr.c differently than the calling code. This happens to a lot of people.

An easy way to force the same FIXED_POINT is to edit the kiss_fft.h directly. Another option: verify with some printf debugging. i.e. place the following in various places:

printf( __FILE__ " sees sizeof(kiss_fft_scalar)=%d\n" , sizeof(kiss_fft_scalar) )

Possibility #2

Perhaps the FIXED_POINT=16 code works but the FIXED_POINT=32 code does not because something is being handled incorrectly either inside kissfft or on the platform. The 32 bit fixed code relies on int64_t being implemented correctly.

Is that Atheros a 16 bit processor? I know kissfft has been used successfully on 16 bit platforms, but I'm not sure if FIXED_POINT=32 real FFTs on a 16 bit fixed point has been used.

viel Glück, Mark

Mark Borgerding
  • 8,117
  • 4
  • 30
  • 51
  • danke für die Anmerkung. Der Fehler lag hier tatsächlich in einem falschen Cast. Konnte es leider nicht als Antwort posten weil ich dafür hier noch zu 'jung' bin. – user3432859 Mar 22 '14 at 09:50