0
votes

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 hereenter 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.

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
@BitTickler Yup. kiss_fft_scalar output[size]; memset(output,0,size*sizeof(kiss_fft_scalar));Rok
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
return r; returning an array on the stack which will be cleaned up once the scope of the function is left.BitTickler

1 Answers

3
votes

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..
}