OLD | NEW |
(Empty) | |
| 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 "dl/api/armOMX.h" |
| 15 #include "dl/api/omxtypes.h" |
| 16 #include "dl/sp/api/armSP.h" |
| 17 #include "dl/sp/api/omxSP.h" |
| 18 |
| 19 /** |
| 20 * Function: omxSP_FFTInit_R_F32 |
| 21 * |
| 22 * Description: |
| 23 * Initialize the real forward-FFT specification information struct. |
| 24 * |
| 25 * Remarks: |
| 26 * This function is used to initialize the specification structures |
| 27 * for functions <ippsFFTFwd_RToCCS_F32_Sfs> and |
| 28 * <ippsFFTInv_CCSToR_F32_Sfs>. Memory for *pFFTSpec must be |
| 29 * allocated prior to calling this function. The number of bytes |
| 30 * required for *pFFTSpec can be determined using |
| 31 * <FFTGetBufSize_R_F32>. |
| 32 * |
| 33 * Parameters: |
| 34 * [in] order base-2 logarithm of the desired block length; |
| 35 * valid in the range [1,12]. ([1,15] if |
| 36 * BIG_FFT_TABLE is defined.) |
| 37 * [out] pFFTFwdSpec pointer to the initialized specification structure. |
| 38 * |
| 39 * Return Value: |
| 40 * Standard omxError result. See enumeration for possible result codes. |
| 41 * |
| 42 */ |
| 43 OMXResult omxSP_FFTInit_R_F32(OMXFFTSpec_R_F32* pFFTSpec, OMX_INT order) { |
| 44 OMX_INT i; |
| 45 OMX_INT j; |
| 46 OMX_FC32* pTwiddle; |
| 47 OMX_FC32* pTwiddle1; |
| 48 OMX_FC32* pTwiddle2; |
| 49 OMX_FC32* pTwiddle3; |
| 50 OMX_FC32* pTwiddle4; |
| 51 OMX_F32* pBuf; |
| 52 OMX_U16* pBitRev; |
| 53 OMX_U32 pTmp; |
| 54 OMX_INT Nby2; |
| 55 OMX_INT N; |
| 56 OMX_INT M; |
| 57 OMX_INT diff; |
| 58 OMX_INT step; |
| 59 OMX_F32 x; |
| 60 OMX_F32 y; |
| 61 OMX_F32 xNeg; |
| 62 ARMsFFTSpec_R_FC32* pFFTStruct = 0; |
| 63 |
| 64 pFFTStruct = (ARMsFFTSpec_R_FC32 *) pFFTSpec; |
| 65 |
| 66 /* Validate args */ |
| 67 if (!pFFTSpec || (order < 1) || (order > TWIDDLE_TABLE_ORDER)) |
| 68 return OMX_Sts_BadArgErr; |
| 69 |
| 70 /* Do the initializations */ |
| 71 Nby2 = 1 << (order - 1); |
| 72 N = Nby2 << 1; |
| 73 |
| 74 /* optimized implementations don't use bitreversal */ |
| 75 pBitRev = NULL; |
| 76 |
| 77 pTwiddle = (OMX_FC32 *) (sizeof(ARMsFFTSpec_R_SC32) + (OMX_S8*) pFFTSpec); |
| 78 |
| 79 /* Align to 32 byte boundary */ |
| 80 pTmp = ((OMX_U32)pTwiddle) & 31; |
| 81 if (pTmp) |
| 82 pTwiddle = (OMX_FC32*) ((OMX_S8*)pTwiddle + (32 - pTmp)); |
| 83 |
| 84 pBuf = (OMX_F32*) (sizeof(OMX_FC32)*(5*N/8) + (OMX_S8*) pTwiddle); |
| 85 |
| 86 /* Align to 32 byte boundary */ |
| 87 pTmp = ((OMX_U32)pBuf)&31; /* (OMX_U32)pBuf % 32 */ |
| 88 if (pTmp) |
| 89 pBuf = (OMX_F32*) ((OMX_S8*)pBuf + (32 - pTmp)); |
| 90 |
| 91 /* |
| 92 * Filling Twiddle factors : |
| 93 * |
| 94 * exp^(-j*2*PI*k/ (N/2) ) ; k=0,1,2,...,3/4(N/2) |
| 95 * |
| 96 * N/2 point complex FFT is used to compute N point real FFT The |
| 97 * original twiddle table "armSP_FFT_F32TwiddleTable" is of size |
| 98 * (MaxSize/8 + 1) Rest of the values i.e., upto MaxSize are |
| 99 * calculated using the symmetries of sin and cos The max size of |
| 100 * the twiddle table needed is 3/4(N/2) for a radix-4 stage |
| 101 * |
| 102 * W = (-2 * PI) / N |
| 103 * N = 1 << order |
| 104 * W = -PI >> (order - 1) |
| 105 */ |
| 106 |
| 107 M = Nby2 >> 3; |
| 108 diff = TWIDDLE_TABLE_ORDER - (order - 1); |
| 109 /* step into the twiddle table for the current order */ |
| 110 step = 1 << diff; |
| 111 |
| 112 x = armSP_FFT_F32TwiddleTable[0]; |
| 113 y = armSP_FFT_F32TwiddleTable[1]; |
| 114 xNeg = 1; |
| 115 |
| 116 if ((order - 1) >= 3) { |
| 117 /* i = 0 case */ |
| 118 pTwiddle[0].Re = x; |
| 119 pTwiddle[0].Im = y; |
| 120 pTwiddle[2*M].Re = -y; |
| 121 pTwiddle[2*M].Im = xNeg; |
| 122 pTwiddle[4*M].Re = xNeg; |
| 123 pTwiddle[4*M].Im = y; |
| 124 |
| 125 for (i = 1; i <= M; i++) { |
| 126 j = i*step; |
| 127 |
| 128 x = armSP_FFT_F32TwiddleTable[2*j]; |
| 129 y = armSP_FFT_F32TwiddleTable[2*j+1]; |
| 130 |
| 131 pTwiddle[i].Re = x; |
| 132 pTwiddle[i].Im = y; |
| 133 pTwiddle[2*M-i].Re = -y; |
| 134 pTwiddle[2*M-i].Im = -x; |
| 135 pTwiddle[2*M+i].Re = y; |
| 136 pTwiddle[2*M+i].Im = -x; |
| 137 pTwiddle[4*M-i].Re = -x; |
| 138 pTwiddle[4*M-i].Im = y; |
| 139 pTwiddle[4*M+i].Re = -x; |
| 140 pTwiddle[4*M+i].Im = -y; |
| 141 pTwiddle[6*M-i].Re = y; |
| 142 pTwiddle[6*M-i].Im = x; |
| 143 } |
| 144 } else if ((order - 1) == 2) { |
| 145 pTwiddle[0].Re = x; |
| 146 pTwiddle[0].Im = y; |
| 147 pTwiddle[1].Re = -y; |
| 148 pTwiddle[1].Im = xNeg; |
| 149 pTwiddle[2].Re = xNeg; |
| 150 pTwiddle[2].Im = y; |
| 151 } else if ((order-1) == 1) { |
| 152 pTwiddle[0].Re = x; |
| 153 pTwiddle[0].Im = y; |
| 154 } |
| 155 |
| 156 /* |
| 157 * Now fill the last N/4 values : exp^(-j*2*PI*k/N) ; |
| 158 * k=1,3,5,...,N/2-1 These are used for the final twiddle fix-up for |
| 159 * converting complex to real FFT |
| 160 */ |
| 161 |
| 162 M = N >> 3; |
| 163 diff = TWIDDLE_TABLE_ORDER - order; |
| 164 step = 1 << diff; |
| 165 |
| 166 pTwiddle1 = pTwiddle + 3*N/8; |
| 167 pTwiddle4 = pTwiddle1 + (N/4 - 1); |
| 168 pTwiddle3 = pTwiddle1 + N/8; |
| 169 pTwiddle2 = pTwiddle1 + (N/8 - 1); |
| 170 |
| 171 x = armSP_FFT_F32TwiddleTable[0]; |
| 172 y = armSP_FFT_F32TwiddleTable[1]; |
| 173 xNeg = 1; |
| 174 |
| 175 if (order >=3) { |
| 176 for (i = 1; i <= M; i += 2) { |
| 177 j = i*step; |
| 178 |
| 179 x = armSP_FFT_F32TwiddleTable[2*j]; |
| 180 y = armSP_FFT_F32TwiddleTable[2*j+1]; |
| 181 |
| 182 pTwiddle1[0].Re = x; |
| 183 pTwiddle1[0].Im = y; |
| 184 pTwiddle1 += 1; |
| 185 pTwiddle2[0].Re = -y; |
| 186 pTwiddle2[0].Im = -x; |
| 187 pTwiddle2 -= 1; |
| 188 pTwiddle3[0].Re = y; |
| 189 pTwiddle3[0].Im = -x; |
| 190 pTwiddle3 += 1; |
| 191 pTwiddle4[0].Re = -x; |
| 192 pTwiddle4[0].Im = y; |
| 193 pTwiddle4 -= 1; |
| 194 } |
| 195 } else { |
| 196 if (order == 2) { |
| 197 pTwiddle1[0].Re = -y; |
| 198 pTwiddle1[0].Im = xNeg; |
| 199 } |
| 200 } |
| 201 |
| 202 |
| 203 /* Update the structure */ |
| 204 pFFTStruct->N = N; |
| 205 pFFTStruct->pTwiddle = pTwiddle; |
| 206 pFFTStruct->pBitRev = pBitRev; |
| 207 pFFTStruct->pBuf = pBuf; |
| 208 |
| 209 return OMX_Sts_NoErr; |
| 210 } |
OLD | NEW |