/* * Like TestFFT, but do just the inverse FFT */ float RunOneInverseTest(int fft_log_size, int signal_type, float signal_value, struct SnrResult* snr) { OMX_SC32* x; OMX_SC32* y; OMX_SC32* z; struct AlignedPtr* x_aligned; struct AlignedPtr* y_aligned; struct AlignedPtr* z_aligned; OMX_INT n, fft_spec_buffer_size; OMXResult status; OMXFFTSpec_C_SC32 * fft_fwd_spec = NULL; OMXFFTSpec_C_SC32 * fft_inv_spec = NULL; int fft_size; fft_size = 1 << fft_log_size; status = omxSP_FFTGetBufSize_C_SC32(fft_log_size, &fft_spec_buffer_size); if (verbose > 3) { printf("fft_spec_buffer_size = %d\n", fft_spec_buffer_size); } fft_inv_spec = (OMXFFTSpec_C_SC32*)malloc(fft_spec_buffer_size); status = omxSP_FFTInit_C_SC32(fft_inv_spec, fft_log_size); if (status) { fprintf(stderr, "Failed to init backward FFT: status = %d\n", status); exit(1); } x_aligned = AllocAlignedPointer(32, sizeof(*x) * fft_size); y_aligned = AllocAlignedPointer(32, sizeof(*y) * (fft_size + 2)); z_aligned = AllocAlignedPointer(32, sizeof(*z) * fft_size); x = x_aligned->aligned_pointer_; y = y_aligned->aligned_pointer_; z = z_aligned->aligned_pointer_; GenerateSignal(x, y, fft_size, signal_type); if (verbose > 63) { printf("Inverse FFT Input Signal\n"); printf("n\tx[n]\n"); DumpArrayComplex32("x", fft_size, y); printf("Expected Inverse FFT output\n"); DumpArrayComplex32("y", fft_size, x); } status = omxSP_FFTInv_CToC_SC32_Sfs(y, z, fft_inv_spec, 0); if (status) { fprintf(stderr, "Inverse FFT failed: status = %d\n", status); exit(1); } if (verbose > 63) { printf("Actual Inverse FFT Output\n"); DumpArrayComplex32("y", fft_size, z); } CompareComplex32(snr, z, x, fft_size); FreeAlignedPointer(x_aligned); FreeAlignedPointer(y_aligned); FreeAlignedPointer(z_aligned); free(fft_inv_spec); return snr->complex_snr_; }
void TimeOneSC32FFT(int count, int fft_log_size, float signal_value, int signal_type) { OMX_SC32* x; OMX_SC32* y; OMX_SC32* z; OMX_SC32* y_true; struct AlignedPtr* x_aligned; struct AlignedPtr* y_aligned; struct AlignedPtr* z_aligned; struct AlignedPtr* y_true_aligned; OMX_SC32* temp32a; OMX_SC32* temp32b; OMX_INT n, fft_spec_buffer_size; OMXResult status; OMXFFTSpec_C_SC32 * fft_fwd_spec = NULL; OMXFFTSpec_C_SC32 * fft_inv_spec = NULL; 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) * fft_size); z_aligned = AllocAlignedPointer(32, sizeof(*z) * fft_size); y_true_aligned = AllocAlignedPointer(32, sizeof(*y_true) * fft_size); temp32a = (OMX_SC32*) malloc(sizeof(*temp32a) * fft_size); temp32b = (OMX_SC32*) malloc(sizeof(*temp32b) * fft_size); x = x_aligned->aligned_pointer_; y = y_aligned->aligned_pointer_; z = z_aligned->aligned_pointer_; y_true = y_true_aligned->aligned_pointer_; generateSC32Signal(x, y_true, fft_size, signal_type, signal_value); status = omxSP_FFTGetBufSize_C_SC32(fft_log_size, &fft_spec_buffer_size); fft_fwd_spec = (OMXFFTSpec_C_SC32*) malloc(fft_spec_buffer_size); fft_inv_spec = (OMXFFTSpec_C_SC32*) malloc(fft_spec_buffer_size); status = omxSP_FFTInit_C_SC32(fft_fwd_spec, fft_log_size); status = omxSP_FFTInit_C_SC32(fft_inv_spec, fft_log_size); if (do_forward_test) { if (include_conversion) { int k; float factor = -1; GetUserTime(&start_time); for (k = 0; k < count; ++k) { for (n = 0; n < fft_size; ++n) { if (abs(x[n].Re) > factor) { factor = abs(x[n].Re); } if (abs(x[n].Im) > factor) { factor = abs(x[n].Im); } } factor = ((1 << 18) - 1) / factor; for (n = 0; n < fft_size; ++n) { temp32a[n].Re = factor * x[n].Re; temp32a[n].Im = factor * x[n].Im; } omxSP_FFTFwd_CToC_SC32_Sfs(x, y, fft_fwd_spec, 0); factor = 1 / factor; for (n = 0; n < fft_size; ++n) { temp32b[n].Re = y[n].Re * factor; temp32b[n].Im = y[n].Im * factor; } } GetUserTime(&end_time); } else { GetUserTime(&start_time); for (n = 0; n < count; ++n) { omxSP_FFTFwd_CToC_SC32_Sfs(x, y, fft_fwd_spec, 0); } GetUserTime(&end_time); } elapsed_time = TimeDifference(&start_time, &end_time); CompareComplex32(&snr_forward, y, y_true, fft_size); PrintResult("Forward SC32 FFT", fft_log_size, elapsed_time, count, snr_forward.complex_snr_); } if (do_inverse_test) { if (include_conversion) { int k; float factor = -1; GetUserTime(&start_time); for (k = 0; k < count; ++k) { for (n = 0; n < fft_size; ++n) { if (abs(x[n].Re) > factor) { factor = abs(x[n].Re); } if (abs(x[n].Im) > factor) { factor = abs(x[n].Im); } } factor = ((1 << 18) - 1) / factor; for (n = 0; n < fft_size; ++n) { temp32a[n].Re = factor * x[n].Re; temp32a[n].Im = factor * x[n].Im; } status = omxSP_FFTInv_CToC_SC32_Sfs(y_true, z, fft_inv_spec, 0); factor = 1 / factor; for (n = 0; n < fft_size; ++n) { temp32b[n].Re = y[n].Re * factor; temp32b[n].Im = y[n].Im * factor; } } GetUserTime(&end_time); } else { GetUserTime(&start_time); for (n = 0; n < count; ++n) { status = omxSP_FFTInv_CToC_SC32_Sfs(y_true, z, fft_inv_spec, 0); } GetUserTime(&end_time); } elapsed_time = TimeDifference(&start_time, &end_time); CompareComplex32(&snr_inverse, z, x, fft_size); PrintResult("Inverse SC32 FFT", fft_log_size, elapsed_time, count, snr_inverse.complex_snr_); } FreeAlignedPointer(x_aligned); FreeAlignedPointer(y_aligned); FreeAlignedPointer(z_aligned); free(temp32a); free(temp32b); free(fft_fwd_spec); free(fft_inv_spec); }