Question

I am trying to get a list of frequencies present in an input audio sample. It seems I need to do an FFT to get this result, but I get odd answers when I FFT it (using FFTW): I get arrays containing mostly zeros with a few impossibly large elements (300+ digits!) - and these large numbers are always in the same place (5 places from the end, 46 places from the end and a few others that show up sporadically) whether I change the frequency of the input tone or even if I change the sample length for the FFT. What am I doing wrong? Here is my code:

#include <fftw3.h>
#include <sndfile.h>
#include <math.h>
#include <algorithm>    

int main (int argc, char * argv []) {
    char        *infilename ;
    SNDFILE     *infile = NULL ;
    FILE        *outfile = NULL ;
    SF_INFO     sfinfo ;

    infile = sf_open("test.wav", SFM_READ, &sfinfo);

    int N = pow(2, 10);
    double samples[N];

    sf_read_double(infile, samples, 1);

    fftw_complex out[N];
    fftw_plan p;
    p = fftw_plan_dft_r2c_1d(N, samples, out, FFTW_ESTIMATE);

    fftw_execute(p);
    fftw_destroy_plan(p); 

    for (int i=0; i<N; i++) {
        printf("%f %f\n", out[i][0], out[i][1]);
    }

    sf_close (infile) ;

    return 0 ;
}
Was it helpful?

Solution

The problem was twofold: firstly, I wasn't loading all the sound data, and secondly, I was just taking the real component of the result. Also, I was still getting the unusable part of the FFT (above the Nyquist frequency). Changing sf_read_double(infile, samples, 1) to sf_read_double(infile, samples, N), changing for (int i=0; i<N; i++) { to for (int i=0; i<N/2; i++) { and changing

printf("%f %f\n", out[i][0], out[i][1]);

to

printf("%i %f\n", i*21, sqrt(out[i][0]*out[i][0] + out[i][1]*out[i][1]));

gave me the good results I wanted.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top