/**
 * @brief Mixed radix-2/4 IFFT (complex to real) of float(32-bit) data.
 * @param[out]  *fout            point to the output buffer
 * @param[in]   *fin             point to the input buffer
 * @param[in]   cfg              point to the config struct
 * @return none.
 * The function implements a mixed radix-2/4 FFT (complex to real). The length of 2^N(N is 2, 3, 4, 5, 6 ....etc) is supported.
 * Otherwise, we alloc a temp buffer(the size is same as input buffer) for storing intermedia.
 * For the usage of this function, please check test/test_suite_fft_float32.c
 */
void ne10_fft_c2r_1d_float32_neon (ne10_float32_t *fout,
                                   ne10_fft_cpx_float32_t *fin,
                                   ne10_fft_r2c_cfg_float32_t cfg)
{
    ne10_fft_cpx_float32_t * tmpbuf1 = cfg->buffer;
    ne10_fft_cpx_float32_t * tmpbuf2 = cfg->buffer + cfg->ncfft;
    ne10_fft_state_float32_t c2c_state;

    c2c_state.nfft = cfg->ncfft;
    c2c_state.factors = cfg->factors;
    c2c_state.twiddles = cfg->twiddles;
    c2c_state.buffer = tmpbuf2;

    ne10_fft_split_c2r_1d_float32_neon (tmpbuf1, fin, cfg->super_twiddles, cfg->ncfft);
    ne10_fft_c2c_1d_float32_neon ( (ne10_fft_cpx_float32_t*) fout, tmpbuf1, &c2c_state, 1);
}
Beispiel #2
0
void TimeOneNE10FFT(int count, int fft_log_size, float signal_value,
                    int signal_type) {
    struct AlignedPtr* x_aligned;
    struct AlignedPtr* y_aligned;
    struct AlignedPtr* z_aligned;

    struct ComplexFloat* x;
    struct ComplexFloat* y;
    OMX_FC32* z;

    struct ComplexFloat* y_true;

    int n;
    ne10_result_t status;
    ne10_fft_cfg_float32_t fft_fwd_spec;
    int fft_size;
    struct timeval start_time;
    struct timeval end_time;
    double elapsed_time;
    struct SnrResult snr_forward;
    struct SnrResult snr_inverse;

    fft_size = 1 << fft_log_size;

    x_aligned = AllocAlignedPointer(32, sizeof(*x) * fft_size);
    y_aligned = AllocAlignedPointer(32, sizeof(*y) * 2 * fft_size);
    z_aligned = AllocAlignedPointer(32, sizeof(*z) * 2 * fft_size);

    y_true = (struct ComplexFloat*) malloc(sizeof(*y_true) * fft_size);

    x = x_aligned->aligned_pointer_;
    y = y_aligned->aligned_pointer_;
    z = z_aligned->aligned_pointer_;

    GenerateTestSignalAndFFT(x, y_true, fft_size, signal_type, signal_value, 0);

    fft_fwd_spec = ne10_fft_alloc_c2c_float32(fft_size);
    if (!fft_fwd_spec) {
        fprintf(stderr, "NE10 FFT: Cannot initialize FFT structure for order %d\n", fft_log_size);
        return;
    }

    if (do_forward_test) {
        GetUserTime(&start_time);
        for (n = 0; n < count; ++n) {
            ne10_fft_c2c_1d_float32_neon((ne10_fft_cpx_float32_t *) y,
                                         (ne10_fft_cpx_float32_t *) x,
                                         fft_fwd_spec,
                                         0);
        }
        GetUserTime(&end_time);

        elapsed_time = TimeDifference(&start_time, &end_time);

        CompareComplexFloat(&snr_forward, (OMX_FC32*) y, (OMX_FC32*) y_true, fft_size);

        PrintResult("Forward NE10 FFT", fft_log_size, elapsed_time, count, snr_forward.complex_snr_);

        if (verbose >= 255) {
            printf("Input data:\n");
            DumpArrayComplexFloat("x", fft_size, (OMX_FC32*) x);
            printf("FFT Actual:\n");
            DumpArrayComplexFloat("y", fft_size, (OMX_FC32*) y);
            printf("FFT Expected:\n");
            DumpArrayComplexFloat("true", fft_size, (OMX_FC32*) y_true);
        }
    }

    if (do_inverse_test) {
        GetUserTime(&start_time);
        for (n = 0; n < count; ++n) {
            ne10_fft_c2c_1d_float32_neon((ne10_fft_cpx_float32_t *) z,
                                         (ne10_fft_cpx_float32_t *) y_true,
                                         fft_fwd_spec,
                                         1);
        }
        GetUserTime(&end_time);

        elapsed_time = TimeDifference(&start_time, &end_time);

        CompareComplexFloat(&snr_inverse, (OMX_FC32*) z, (OMX_FC32*) x, fft_size);

        PrintResult("Inverse NE10 FFT", fft_log_size, elapsed_time, count, snr_inverse.complex_snr_);

        if (verbose >= 255) {
            printf("Input data:\n");
            DumpArrayComplexFloat("y", fft_size, (OMX_FC32*) y_true);
            printf("IFFT Actual:\n");
            DumpArrayComplexFloat("z", fft_size, z);
            printf("IFFT Expected:\n");
            DumpArrayComplexFloat("x", fft_size, (OMX_FC32*) x);
        }
    }

    ne10_fft_destroy_c2c_float32(fft_fwd_spec);
    FreeAlignedPointer(x_aligned);
    FreeAlignedPointer(y_aligned);
    FreeAlignedPointer(z_aligned);
    free(y_true);
}