1 /* 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 * 10 * This is a modification of omxSP_FFTInit_R_S32.c to support float 11 * instead of S32. 12 */ 13 14 #include <stdint.h> 15 16 #include "dl/api/omxtypes.h" 17 #include "dl/sp/api/omxSP.h" 18 #include "dl/sp/api/x86SP.h" 19 20 /** 21 * Function: omxSP_FFTInit_R_F32 22 * 23 * Description: 24 * Initialize the real forward-FFT specification information struct. 25 * 26 * Remarks: 27 * This function is used to initialize the specification structures 28 * for functions |omxSP_FFTFwd_RToCCS_F32_Sfs| and 29 * |omxSP_FFTInv_CCSToR_F32_Sfs|. Memory for *pFFTSpec must be 30 * allocated prior to calling this function. The number of bytes 31 * required for *pFFTSpec can be determined using 32 * |omxSP_FFTGetBufSize_R_F32|. 33 * 34 * Parameters: 35 * [in] order base-2 logarithm of the desired block length; 36 * valid in the range [1,12]. ([1,15] if 37 * BIG_FFT_TABLE is defined.) 38 * [out] pFFTFwdSpec pointer to the initialized specification structure. 39 * 40 * Return Value: 41 * Standard omxError result. See enumeration for possible result codes. 42 * 43 */ 44 45 OMXResult omxSP_FFTInit_R_F32(OMXFFTSpec_R_F32 *pFFTSpec, OMX_INT order) 46 { 47 OMX_F32 *pTwiddle; 48 OMX_F32 *pBuf; 49 OMX_INT i; 50 OMX_INT j; 51 OMX_INT N; 52 OMX_INT NBy2; 53 OMX_INT NBy4; 54 OMX_INT diff; 55 OMX_U32 pTmp; 56 X86FFTSpec_R_FC32 *pFFTStruct = (X86FFTSpec_R_FC32 *) pFFTSpec; 57 OMX_F32 real; 58 OMX_F32 imag; 59 60 if (!pFFTSpec || (order < 1) || (order > TWIDDLE_TABLE_ORDER)) 61 return OMX_Sts_BadArgErr; 62 63 N = 1 << order; 64 NBy2 = N >> 1; 65 66 pTwiddle = (OMX_F32*) (sizeof(X86FFTSpec_R_FC32) + (OMX_S8*) pFFTSpec); 67 68 // Align to 32 byte boundary. 69 pTmp = ((uintptr_t)pTwiddle) & 31; 70 if (pTmp) 71 pTwiddle = (OMX_F32*) ((OMX_S8*)pTwiddle + (32 - pTmp)); 72 73 pBuf = (OMX_F32*) (sizeof(OMX_F32) * (N << 1) + (OMX_S8*) pTwiddle); 74 75 // Align to 32 byte boundary. 76 pTmp = ((uintptr_t)pBuf) & 31; 77 if (pTmp) 78 pBuf = (OMX_F32*) ((OMX_S8*)pBuf + (32 - pTmp)); 79 80 // Calculating Twiddle Factors. 81 diff = 1 << (TWIDDLE_TABLE_ORDER - order + 1); 82 83 // For SSE optimization, using twiddle with split format by which the real and 84 // imag data are stored into first and last halves of the buffer separately 85 // The negatives are moved when generating pTwiddle table. 86 if (order > 1) { 87 NBy4 = N >> 2; 88 for (i = 0, j = 0; i <= NBy4 >> 1; ++i, j += diff) { 89 real = armSP_FFT_F32TwiddleTable[j]; 90 imag = armSP_FFT_F32TwiddleTable[j + 1]; 91 92 pTwiddle[i] = -real; 93 pTwiddle[i + N] = -imag; 94 95 pTwiddle[NBy4 - i] = imag; 96 pTwiddle[NBy4 - i + N] = real; 97 98 pTwiddle[NBy4 + i] = -imag; 99 pTwiddle[NBy4 + i + N] = real; 100 101 pTwiddle[NBy2 - i] = real; 102 pTwiddle[NBy2 - i + N] = -imag; 103 104 pTwiddle[NBy2 + i] = real; 105 pTwiddle[NBy2 + i + N] = imag; 106 107 pTwiddle[NBy4 * 3 - i] = -imag; 108 pTwiddle[NBy4 * 3 - i + N] = -real; 109 110 pTwiddle[NBy4 * 3 + i] = imag; 111 pTwiddle[NBy4 * 3 + i + N] = -real; 112 113 pTwiddle[N - i - 1] = -real; 114 pTwiddle[(N << 1) - i - 1] = imag; 115 } 116 } else { 117 pTwiddle[0] = armSP_FFT_F32TwiddleTable[0]; 118 pTwiddle[2] = armSP_FFT_F32TwiddleTable[1]; 119 pTwiddle[1] = -pTwiddle[0]; 120 pTwiddle[3] = pTwiddle[2]; 121 } 122 pFFTStruct->N = N; 123 pFFTStruct->pTwiddle = pTwiddle; 124 pFFTStruct->pBuf1 = pBuf; 125 pFFTStruct->pBuf2 = pBuf + N + 4; 126 127 return OMX_Sts_NoErr; 128 } 129