コード例 #1
0
ファイル: AccelerateFFT.cpp プロジェクト: adamstark/Gist
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];
    }
}
コード例 #2
0
ファイル: fftlibvdsp_op.cpp プロジェクト: kellydunn/libofa
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;

}
コード例 #3
0
ファイル: vector.c プロジェクト: sairashaheen/LibXtract
int xtract_spectrum(const double *data, const int N, const void *argv, double *result)
{

    int vector     = 0;
    int withDC     = 0;
    int normalise  = 0;
    double q        = 0.0;
    double temp     = 0.0;
    double max      = 0.0;
    double NxN      = XTRACT_SQ(N);
    double *marker  = NULL;
    double real = 0.0;
    double imag = 0.0;
    unsigned int n = 0;
    unsigned int m = 0;
    unsigned int M = N >> 1;
#ifndef USE_OOURA
    DSPDoubleSplitComplex *fft = NULL;
#endif

    q = *(double *)argv;
    vector = (int)*((double *)argv+1);
    withDC = (int)*((double *)argv+2);
    normalise = (int)*((double *)argv+3);

    XTRACT_CHECK_q;
#ifdef USE_OOURA
    if(!ooura_data_spectrum.initialised)
#else
    if(!vdsp_data_spectrum.initialised)
#endif
    {
        fprintf(stderr,
                "libxtract: error: xtract_spectrum() failed, "
                "fft data unitialised.\n");
        return XTRACT_NO_RESULT;
    }

#ifdef USE_OOURA
    /* ooura is in-place
     * the output format is
     * a[0] - DC, a[1] - nyquist, a[2...N-1] - remaining bins
     */
    rdft(N, 1, data, ooura_data_spectrum.ooura_ip, 
            ooura_data_spectrum.ooura_w);
#else
    fft = &vdsp_data_spectrum.fft;
    vDSP_ctozD((DSPDoubleComplex *)data, 2, fft, 1, N >> 1);
    vDSP_fft_zripD(vdsp_data_spectrum.setup, fft, 1, 
            vdsp_data_spectrum.log2N, FFT_FORWARD);
#endif

    switch(vector)
    {

        case XTRACT_LOG_MAGNITUDE_SPECTRUM:
        for(n = 0, m = 0; m < M; ++n, ++m)
        {
            marker = &result[m];

            if(n==0 && !withDC) /* discard DC and keep Nyquist */
            {
                ++n;
#ifdef USE_OOURA
                marker = &result[M-1];
#endif
            }
#ifdef USE_OOURA
            if(n==1 && withDC) /* discard Nyquist */
            {
                ++n;
            }

            real = data[n*2];
            imag = data[n*2+1];
#else
            real = fft->realp[n];
            imag = fft->realp[n];
#endif

            temp = XTRACT_SQ(real) + XTRACT_SQ(imag);
            if (temp > XTRACT_LOG_LIMIT)
            {
                temp = log(sqrt(temp) / (double)N);
            }
            else
            {
                temp = XTRACT_LOG_LIMIT_DB;
            }
            result[m] =
                /* Scaling */
                (temp + XTRACT_DB_SCALE_OFFSET) /
                XTRACT_DB_SCALE_OFFSET;

            XTRACT_SET_FREQUENCY;
            XTRACT_GET_MAX;
        }
        break;

    case XTRACT_POWER_SPECTRUM:
        for(n = 0, m = 0; m < M; ++n, ++m)
        {

            marker = &result[m];

            if(n==0 && !withDC) /* discard DC and keep Nyquist */
            {
                ++n;
#ifdef USE_OOURA
                marker = &result[M-1];
#endif
            }
#ifdef USE_OOURA
            if(n==1 && withDC) /* discard Nyquist */
            {
                ++n;
            }

            real = data[n*2];
            imag = data[n*2+1];
#else
            real = fft->realp[n];
            imag = fft->realp[n];
#endif

            result[m] = (XTRACT_SQ(real) + XTRACT_SQ(imag)) / NxN;
            XTRACT_SET_FREQUENCY;
            XTRACT_GET_MAX;
        }
        break;

    case XTRACT_LOG_POWER_SPECTRUM:
        for(n = 0, m = 0; m < M; ++n, ++m)
        {
            marker = &result[m];

            if(n==0 && !withDC) /* discard DC and keep Nyquist */
            {
                ++n;
#ifdef USE_OOURA
                marker = &result[M-1];
#endif
            }
#ifdef USE_OOURA
            if(n==1 && withDC) /* discard Nyquist */
            {
                ++n;
            }

            real = data[n*2];
            imag = data[n*2+1];
#else
            real = fft->realp[n];
            imag = fft->realp[n];
#endif

            if ((temp = XTRACT_SQ(real) + XTRACT_SQ(imag)) >
                    XTRACT_LOG_LIMIT)
                temp = log(temp / NxN);
            else
                temp = XTRACT_LOG_LIMIT_DB;

            result[m] = (temp + XTRACT_DB_SCALE_OFFSET) /
                        XTRACT_DB_SCALE_OFFSET;
            XTRACT_SET_FREQUENCY;
            XTRACT_GET_MAX;
        }
        break;

    default:
        /* MAGNITUDE_SPECTRUM */
        for(n = 0, m = 0; m < M; ++n, ++m)
        {
            marker = &result[m];

            if(n==0 && !withDC) /* discard DC and keep Nyquist */
            {
                ++n;
#ifdef USE_OOURA
                marker = &result[M-1];
#endif
            }
#ifdef USE_OOURA
            if(n==1 && withDC) /* discard Nyquist */
            {
                ++n;
            }
            real = data[n*2];
            imag = data[n*2+1];
#else
            real = fft->realp[n];
            imag = fft->realp[n];
#endif
            *marker = sqrt(XTRACT_SQ(real) + XTRACT_SQ(imag)) / (double)N;

            XTRACT_SET_FREQUENCY;
            XTRACT_GET_MAX;
        }
        break;
    }

    if(normalise)
    {
        for(n = 0; n < M; n++)
            result[n] /= max;
    }

    return XTRACT_SUCCESS;
}
コード例 #4
0
ファイル: vector.c プロジェクト: sairashaheen/LibXtract
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;
}