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 file was originally licensed as follows. It has been 11 * relicensed with permission from the copyright holders. 12 */ 13 14 /** 15 * 16 * File Name: omxSP_FFTInit_R_S16S32.c 17 * OpenMAX DL: v1.0.2 18 * Last Modified Revision: 7777 19 * Last Modified Date: Thu, 27 Sep 2007 20 * 21 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. 22 * 23 * 24 * Description: 25 * Initialize the real forward-FFT specification information struct. 26 */ 27 28 #include <stdint.h> 29 30 #include "dl/api/arm/armOMX.h" 31 #include "dl/api/omxtypes.h" 32 #include "dl/sp/api/armSP.h" 33 #include "dl/sp/api/omxSP.h" 34 35 /** 36 * Function: omxSP_FFTInit_R_S16_S32 37 * 38 * Description: 39 * Initialize the real forward-FFT specification information struct. 40 * 41 * Remarks: 42 * This function is used to initialize the specification structures 43 * for functions <ippsFFTFwd_RToCCS_S16_S32_Sfs> and 44 * <ippsFFTInv_CCSToR_S32_S16_Sfs>. Memory for *pFFTSpec must be 45 * allocated prior to calling this function. The number of bytes 46 * required for *pFFTSpec can be determined using 47 * <FFTGetBufSize_R_S16_S32>. 48 * 49 * Parameters: 50 * [in] order base-2 logarithm of the desired block length; 51 * valid in the range [0,12]. 52 * [out] pFFTFwdSpec pointer to the initialized specification structure. 53 * 54 * Return Value: 55 * Standard omxError result. See enumeration for possible result codes. 56 * 57 */ 58 59 OMXResult omxSP_FFTInit_R_S16S32( 60 OMXFFTSpec_R_S16S32* pFFTSpec, 61 OMX_INT order 62 ) 63 { 64 OMX_INT i,j; 65 OMX_SC32 *pTwiddle,*pTwiddle1,*pTwiddle2,*pTwiddle3,*pTwiddle4; 66 OMX_S32 *pBuf; 67 OMX_U16 *pBitRev; 68 OMX_U32 pTmp; 69 OMX_INT Nby2,N,M,diff, step; 70 OMX_S32 x,y,xNeg; 71 ARMsFFTSpec_R_SC32 *pFFTStruct = 0; 72 73 74 pFFTStruct = (ARMsFFTSpec_R_SC32 *) pFFTSpec; 75 76 /* if order zero no init is needed */ 77 if (order == 0) 78 { 79 pFFTStruct->N = 1; 80 pFFTStruct->pTwiddle = NULL; 81 pFFTStruct->pBuf = (OMX_S32 *) 82 (sizeof(ARMsFFTSpec_R_SC32) + (OMX_S8*) pFFTSpec); 83 84 return OMX_Sts_NoErr; 85 } 86 87 /* Do the initializations */ 88 Nby2 = 1 << (order - 1); 89 N = Nby2 << 1; 90 91 92 93 pBitRev = NULL ; /* optimized implementations don't use bitreversal */ 94 95 pTwiddle = (OMX_SC32 *) 96 (sizeof(ARMsFFTSpec_R_SC32) + (OMX_S8*) pFFTSpec); 97 98 /* Align to 32 byte boundary */ 99 pTmp = ((uintptr_t)pTwiddle)&31; /* (OMX_U32)pTwiddle % 32 */ 100 if(pTmp != 0) 101 pTwiddle = (OMX_SC32*) ((OMX_S8*)pTwiddle + (32-pTmp)); 102 103 104 pBuf = (OMX_S32*) 105 (sizeof(OMX_SC32) * (5*N/8) + (OMX_S8*) pTwiddle); 106 107 /* Align to 32 byte boundary */ 108 pTmp = ((uintptr_t)pBuf)&31; /* (OMX_U32)pBuf % 32 */ 109 if(pTmp != 0) 110 pBuf = (OMX_S32*) ((OMX_S8*)pBuf + (32-pTmp)); 111 112 113 114 115 /* 116 * Filling Twiddle factors : exp^(-j*2*PI*k/ (N/2) ) ; k=0,1,2,...,3/4(N/2) 117 * N/2 point complex FFT is used to compute N point real FFT 118 * The original twiddle table "armSP_FFT_S32TwiddleTable" is of size (MaxSize/8 + 1) 119 * Rest of the values i.e., upto MaxSize are calculated using the symmetries of sin and cos 120 * The max size of the twiddle table needed is 3/4(N/2) for a radix-4 stage 121 * 122 * W = (-2 * PI) / N 123 * N = 1 << order 124 * W = -PI >> (order - 1) 125 */ 126 127 M = Nby2>>3; 128 diff = 12 - (order-1); 129 step = 1<<diff; /* step into the twiddle table for the current order */ 130 131 x = armSP_FFT_S32TwiddleTable[0]; 132 y = armSP_FFT_S32TwiddleTable[1]; 133 xNeg = 0x7FFFFFFF; 134 135 if((order-1) >=3) 136 { 137 /* i = 0 case */ 138 pTwiddle[0].Re = x; 139 pTwiddle[0].Im = y; 140 pTwiddle[2*M].Re = -y; 141 pTwiddle[2*M].Im = xNeg; 142 pTwiddle[4*M].Re = xNeg; 143 pTwiddle[4*M].Im = y; 144 145 146 for (i=1; i<=M; i++) 147 { 148 j = i*step; 149 150 x = armSP_FFT_S32TwiddleTable[2*j]; 151 y = armSP_FFT_S32TwiddleTable[2*j+1]; 152 153 pTwiddle[i].Re = x; 154 pTwiddle[i].Im = y; 155 pTwiddle[2*M-i].Re = -y; 156 pTwiddle[2*M-i].Im = -x; 157 pTwiddle[2*M+i].Re = y; 158 pTwiddle[2*M+i].Im = -x; 159 pTwiddle[4*M-i].Re = -x; 160 pTwiddle[4*M-i].Im = y; 161 pTwiddle[4*M+i].Re = -x; 162 pTwiddle[4*M+i].Im = -y; 163 pTwiddle[6*M-i].Re = y; 164 pTwiddle[6*M-i].Im = x; 165 } 166 167 168 } 169 else 170 { 171 if ((order-1) == 2) 172 { 173 pTwiddle[0].Re = x; 174 pTwiddle[0].Im = y; 175 pTwiddle[1].Re = -y; 176 pTwiddle[1].Im = xNeg; 177 pTwiddle[2].Re = xNeg; 178 pTwiddle[2].Im = y; 179 180 } 181 if ((order-1) == 1) 182 { 183 pTwiddle[0].Re = x; 184 pTwiddle[0].Im = y; 185 186 } 187 188 189 } 190 191 192 /* 193 * Now fill the last N/4 values : exp^(-j*2*PI*k/N) ; k=1,3,5,...,N/2-1 194 * These are used for the final twiddle fix-up for converting complex to real FFT 195 */ 196 197 M = N>>3; 198 diff = 12 - order; 199 step = 1<<diff; 200 201 pTwiddle1 = pTwiddle + 3*N/8; 202 pTwiddle4 = pTwiddle1 + (N/4-1); 203 pTwiddle3 = pTwiddle1 + N/8; 204 pTwiddle2 = pTwiddle1 + (N/8-1); 205 206 x = armSP_FFT_S32TwiddleTable[0]; 207 y = armSP_FFT_S32TwiddleTable[1]; 208 xNeg = 0x7FFFFFFF; 209 210 if((order) >=3) 211 { 212 213 214 for (i=1; i<=M; i+=2 ) 215 { 216 j = i*step; 217 218 x = armSP_FFT_S32TwiddleTable[2*j]; 219 y = armSP_FFT_S32TwiddleTable[2*j+1]; 220 221 pTwiddle1[0].Re = x; 222 pTwiddle1[0].Im = y; 223 pTwiddle1 += 1; 224 pTwiddle2[0].Re = -y; 225 pTwiddle2[0].Im = -x; 226 pTwiddle2 -= 1; 227 pTwiddle3[0].Re = y; 228 pTwiddle3[0].Im = -x; 229 pTwiddle3 += 1; 230 pTwiddle4[0].Re = -x; 231 pTwiddle4[0].Im = y; 232 pTwiddle4 -= 1; 233 234 } 235 236 237 } 238 else 239 { 240 if (order == 2) 241 { 242 243 pTwiddle1[0].Re = -y; 244 pTwiddle1[0].Im = xNeg; 245 246 } 247 248 249 } 250 251 252 /* Update the structure */ 253 pFFTStruct->N = N; 254 pFFTStruct->pTwiddle = pTwiddle; 255 pFFTStruct->pBitRev = pBitRev; 256 pFFTStruct->pBuf = pBuf; 257 258 return OMX_Sts_NoErr; 259 } 260 /***************************************************************************** 261 * END OF FILE 262 *****************************************************************************/ 263 264