FFT with iOS vDSP not symmetric

I am using Apples vDSP API to compute FFT audio. However my results (c amp[]

) are not symmetrical around N / 2, what should they be from, from my understanding of FFT on real inputs?

The following frame

is an array [128] of floats containing audio samples.

        int numSamples = 128;
        vDSP_Length log2n = log2f(numSamples);
        FFTSetup fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
        int nOver2 = numSamples/2;

        COMPLEX_SPLIT A;
        A.realp = (float *) malloc(nOver2*sizeof(float));
        A.imagp = (float *) malloc(nOver2*sizeof(float));

        vDSP_ctoz((COMPLEX*)frame, 2, &A, 1, nOver2);

        //Perform FFT using fftSetup and A
        //Results are returned in A
        vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD);

        //Convert COMPLEX_SPLIT A result to float array to be returned
        float amp[numSamples];
        amp[0] = A.realp[0]/(numSamples*2);
        for(int i=1;i<numSamples;i++) {
            amp[i]=A.realp[i]*A.realp[i]+A.imagp[i]*A.imagp[i];
            printf("%f ",amp[i]);
        }

      

If I put the same float array into an online FFT calculator, I get symmetric output. Am I doing something wrong above?

For some reason, most of the values ​​in amp[]

are between 0 and 1e-5, but I also get one huge value around 1e23. I am not doing any windows here, just trying to run the basic FFT first.

I have attached a picture of the two FFT outputs using the same data. You can see that they are similar up to 64, although not at a constant scaling factor, so I'm not sure if they are different. Then over 64 they are completely different.

enter image description here

+3


source to share


2 answers


To get symmetric results from strictly real inout to basic FFT, your complex input and output data arrays must be the same length as your FFT. You seem to be allocating and copying only half of your data to the FFT input, which can result in unnecessary memory garbage being ejected into the FFT.



0


source


Since the mathematical output of the real-complex FFT is symmetric, there is no value when returning the second half. There is also no room in the array for the array being passed to vDSP_fft_zrip

. So vDSP_fft_zrip

only returns the first half (except for the special N / 2 point discussed below). The second half is usually not needed explicitly, and if so, you can easily compute it from the first half.

The output vDSP_fft_zrip

when used for direct (real to complex) conversion has an output H 0(which is purely real, its imaginary part is zero) c A.realp[0]

. Outlet H N / 2(which is also purely real) is preserved in A.imagp[0]

. Other values ​​of H i, for 0 <i <N / 2, are usually stored in A.realp[i]

u A.imagp[i]

.



Documentation explaining this is here under "Data Package for Real FFTs".

+4


source







All Articles