c++vectorkissfft

How to use kissFFT with C++ vector correctly?


I want to use kissFFT in a C++ project with std::vector to easily handle a signal of arbitrary length. To achieve this I edited this SO answer from the author of kissFFT. I replaced

std::complex<float> x[nfft]; with

vector<std::complex<float>> x(nfft, 0.0);

and replaced the function call

kiss_fft(fwd,(kiss_fft_cpx*)x,(kiss_fft_cpx*)fx) with

kiss_fft(fwd,(kiss_fft_cpx*)&x[0],(kiss_fft_cpx*)&fx[0]);

This seems to work pretty well, but is this the right way to do it? In the "test" folder of kissFFT, I found "testcpp.cc" which seems to use some fancy C++ template features (unfortunately, too fancy for me; I could not make it compile). Does my solution have any drawbacks?


Complete Code

#include "kiss_fft.h"
#include <complex>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    const int nfft=256;
    kiss_fft_cfg fwd = kiss_fft_alloc(nfft,0,NULL,NULL);
    kiss_fft_cfg inv = kiss_fft_alloc(nfft,1,NULL,NULL);

    vector<std::complex<float>> x(nfft, 0.0);
    vector<std::complex<float>> fx(nfft, 0.0);

    x[0] = 1;
    x[1] = std::complex<float>(0,3);

    kiss_fft(fwd,(kiss_fft_cpx*)&x[0],(kiss_fft_cpx*)&fx[0]);
    for (int k=0;k<nfft;++k) {
        fx[k] = fx[k] * conj(fx[k]);
        fx[k] *= 1./nfft;
    }
    kiss_fft(inv,(kiss_fft_cpx*)&fx[0],(kiss_fft_cpx*)&x[0]);
    cout << "the circular correlation of [1, 3i, 0 0 ....] with itself = ";
    cout
        << x[0] << ","
        << x[1] << ","
        << x[2] << ","
        << x[3] << " ... " << endl;
    kiss_fft_free(fwd);
    kiss_fft_free(inv);
    return 0;
}

Solution

  • I tend to use std::vector<kiss_fft_cpx> myself, but otherwise my code is pretty much the same as yours. (Well, kiss_fft_alloc and kiss_fft_free go in ctor/dtor to avoid memory leaks, but that's a style thing.)

    Slightly further down, fx[k] * conj(fx[k]) is a typical math expression. It's more efficient to use fx[k].norm().