void AccelerateFFT<double>::performFFT (double* buffer, double* real, double* imag) { vDSP_ctozD ((DOUBLE_COMPLEX*)buffer, 2, &doubleComplexSplit, 1, fftSizeOver2); vDSP_fft_zripD (fftSetupDouble, &doubleComplexSplit, 1, log2n, FFT_FORWARD); doubleComplexSplit.realp[fftSizeOver2] = doubleComplexSplit.imagp[0]; doubleComplexSplit.imagp[fftSizeOver2] = 0.0; doubleComplexSplit.imagp[0] = 0.0; for (size_t i = 0; i <= fftSizeOver2; i++) { doubleComplexSplit.realp[i] *= 0.5; doubleComplexSplit.imagp[i] *= 0.5; } for (size_t i = fftSizeOver2 - 1; i > 0; --i) { doubleComplexSplit.realp[2 * fftSizeOver2 - i] = doubleComplexSplit.realp[i]; doubleComplexSplit.imagp[2 * fftSizeOver2 - i] = -1 * doubleComplexSplit.imagp[i]; } for (size_t i = 0; i < fftSize; i++) { real[i] = doubleComplexSplit.realp[i]; imag[i] = doubleComplexSplit.imagp[i]; } }
void FFTLib_op::ComputeFrame(int N, double *in, double *out) { vDSP_ctozD ((DSPDoubleComplex*) in, 2, &A, 1, N/2 ); vDSP_fft_zripD(SetupReal, &A, 1, Exp, FFT_FORWARD); int i,j; for (i=0; i<N/2; i++) out[i] = A.realp[i]*0.5; out[N/2] = A.imagp[0]*0.5; for (i=1, j=N-1; i<N/2; i++, j--) out[j] = A.imagp[i]*0.5; }
int xtract_autocorrelation_fft(const double *data, const int N, const void *argv, double *result) { double *rfft = NULL; int n = 0; int M = 0; #ifndef USE_OOURA DSPDoubleSplitComplex *fft = NULL; double M_double = 0.0; #endif M = N << 1; /* Zero pad the input vector */ rfft = (double *)calloc(M, sizeof(double)); memcpy(rfft, data, N * sizeof(double)); #ifdef USE_OOURA rdft(M, 1, rfft, ooura_data_autocorrelation_fft.ooura_ip, ooura_data_autocorrelation_fft.ooura_w); for(n = 2; n < M; ++n) { rfft[n*2] = XTRACT_SQ(rfft[n*2]) + XTRACT_SQ(rfft[n*2+1]); rfft[n*2+1] = 0.0; } rfft[0] = XTRACT_SQ(rfft[0]); rfft[1] = XTRACT_SQ(rfft[1]); rdft(M, -1, rfft, ooura_data_autocorrelation_fft.ooura_ip, ooura_data_autocorrelation_fft.ooura_w); #else /* vDSP has its own autocorrelation function, but it doesn't fit the * LibXtract model, e.g. we can't guarantee it's going to use * an FFT for all values of N */ fft = &vdsp_data_autocorrelation_fft.fft; vDSP_ctozD((DSPDoubleComplex *)data, 2, fft, 1, N); vDSP_fft_zripD(vdsp_data_autocorrelation_fft.setup, fft, 1, vdsp_data_autocorrelation_fft.log2N, FFT_FORWARD); for(n = 0; n < N; ++n) { fft->realp[n] = XTRACT_SQ(fft->realp[n]) + XTRACT_SQ(fft->imagp[n]); fft->imagp[n] = 0.0; } vDSP_fft_zripD(vdsp_data_autocorrelation_fft.setup, fft, 1, vdsp_data_autocorrelation_fft.log2N, FFT_INVERSE); #endif /* Normalisation factor */ M = M * N; #ifdef USE_OOURA for(n = 0; n < N; n++) result[n] = rfft[n] / (double)M; free(rfft); #else M_double = (double)M; vDSP_ztocD(fft, 1, (DOUBLE_COMPLEX *)result, 2, N); vDSP_vsdivD(result, 1, &M_double, result, 1, N); #endif return XTRACT_SUCCESS; }