0

The real inverse FFT gives me an array full of NaNs instead of floats.

kiss_fftri(conf,complex_array,output);

The complex_array is normal, nothing wrong with the values i guess.

kiss_fftr_cfg conf = kiss_fftr_alloc(size,1,NULL,NULL);

The conf should be fine too as far as I know.

Anything wrong with the size? I know that the output size of the forward FFT must be N/2 + 1 and the size above should be N.

I've already made an simple working example with audio convolution in the frequency domain and everything, but I've no idea whats happening here.


enter image description here enter image description here

NaNs and some samples of the , complex_array above.

The size parameter in my example is always 18750. Thats the number of samples. N / 2 + 1 is therefore 7876.

First I'm having a mono channel with 450k samples. Then I'm splitting it on 24 parts. Every part is now 18750 samples. With each of those samples I'm making an convolution with an impulse response. So basically the numbers I'm printing above are lets say the first 20 samples in each of the 24 rounds the for loop is going. Nothing wrong here I guess.

I even did on kiss_fftr_next_fast_size_real(size) and it stays the same so the size should be optimal.


Here's my convolution:

kiss_fft_cpx convolution(kiss_fft_cpx *a, kiss_fft_cpx *b, int size)
{
    kiss_fft_cpx r[size];
    memset(r,0,size*sizeof(kiss_fft_cpx));
    int skalar = size * 2; // for the normalisation
    for (int i = 0; i < size; ++i){
        r[i].r = ((a[i].r/skalar) * (b[i].r)/skalar) - ((a[i].i/skalar) * (b[i].i)/skalar);
        r[i].i = ((a[i].r/skalar) * (b[i].i)/skalar) + ((a[i].i/skalar) * (b[i].r)/skalar);
    }
    return r;
}

The size I input here via the argument is the N/2 + 1.

Rok
  • 787
  • 9
  • 17
  • 1
    Guess you need to show a little more of your code for use to be helpful. Did you init output array you pass to the fftri function? – BitTickler May 09 '15 at 17:02
  • @BitTickler Yup. `kiss_fft_scalar output[size];` `memset(output,0,size*sizeof(kiss_fft_scalar));` – Rok May 09 '15 at 17:05
  • The `complex_array` here is the output of a convolution of some sound data and an impulse response. It seems fine as I mentioned already. – Rok May 09 '15 at 17:13
  • I believe the author of KissFFT is an active user here on StackOverflow so it might be worth pinging him if you can find his user ID. – Paul R May 09 '15 at 18:53
  • See also: http://stackoverflow.com/questions/14536950/applying-kiss-fft-on-audio-samples-and-getting-nan-output – Paul R May 09 '15 at 18:55
  • @PaulR I've been learning how to use **KissFFT** from that link you pasted. – Rok May 09 '15 at 19:05
  • 1
    Ping @MarkBorgerding - http://stackoverflow.com/users/3343/mark-borgerding – Paul R May 09 '15 at 19:38
  • Hm... the inverse fft need not necessarily be a real valued series. Is also complex in general. – BitTickler May 10 '15 at 08:43
  • ``kiss_fft_cpx r[size];`` Does not work and should not even compile, though. size is an argument not a const. – BitTickler May 10 '15 at 08:45
  • 2
    ``return r;`` returning an array on the stack which will be cleaned up once the scope of the function is left. – BitTickler May 10 '15 at 08:47

1 Answers1

3

It's not kiss which causes the problem here. It is how the result array is (mis)handled.

To really "keep it simple and stupid" (KISS), I recommend to use STL containers for your data instead of raw c++ arrays. This way, you can avoid the mistakes you did in the code. Namely returning the array you created on the stack.

kiss_fft_cpx convolution(kiss_fft_cpx *a, kiss_fft_cpx *b, int size)

... bears various problems. The return type is just a complex number, not a series.

I would change the signature of the function to:

#include <vector>
typedef std::vector<kiss_fft_cpx> complex_vector;
void 
convolution
( const kiss_fft_cpxy *a
, const kiss_Fft_cpx *b
, int size
, complex_vector& result 
);

Then, in the code, you can indeed resize the result vector to the necessary size and use it just like a fixed size array as far as your convolution computation is concerned.

{
    result.resize(size);
    // ... use as you did in your code: result[i] etc..
}
BitTickler
  • 10,905
  • 5
  • 32
  • 53