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_C_SC32.c 17 * OpenMAX DL: v1.0.2 18 * Last Modified Revision: 7769 19 * Last Modified Date: Thu, 27 Sep 2007 20 * 21 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. 22 * 23 * 24 * Description: 25 * Initializes the specification structures required 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_C_SC32 37 * 38 * Description: 39 * Initializes the specification structures required for the 40 * complex FFT and IFFT functions. 41 * 42 * Remarks: 43 * Desired block length is specified as an input. The function is used to 44 * initialize the specification structures for functions <FFTFwd_CToC_SC32_Sfs> 45 * and <FFTInv_CToC_SC32_Sfs>. Memory for the specification structure *pFFTSpec 46 * must be allocated prior to calling this function. The space required for 47 * *pFFTSpec, in bytes, can be determined using <FFTGetBufSize_C_SC32>. 48 * 49 * Parameters: 50 * [in] order base-2 logarithm of the desired block length; 51 * valid in the range [0,12]. 52 * [out] pFFTSpec pointer to initialized specification structure. 53 * 54 * Return Value: 55 * Standard omxError result. See enumeration for possible result codes. 56 * 57 */ 58 59 OMXResult omxSP_FFTInit_C_SC32( 60 OMXFFTSpec_C_SC32* pFFTSpec, 61 OMX_INT order 62 ) 63 { 64 OMX_INT i,j; 65 OMX_SC32 *pTwiddle, *pBuf; 66 OMX_U16 *pBitRev; 67 OMX_U32 pTmp; 68 OMX_INT Nby2,N,M,diff, step; 69 ARMsFFTSpec_SC32 *pFFTStruct = 0; 70 OMX_S32 x,y,xNeg; 71 72 pFFTStruct = (ARMsFFTSpec_SC32 *) pFFTSpec; 73 74 /* if order zero no init is needed */ 75 if (order == 0) 76 { 77 pFFTStruct->N = 1; 78 return OMX_Sts_NoErr; 79 } 80 81 /* Do the initializations */ 82 Nby2 = 1 << (order - 1); 83 N = Nby2 << 1; 84 M = N>>3; 85 86 87 pBitRev = NULL ; /* optimized implementations don't use bitreversal */ 88 89 pTwiddle = (OMX_SC32 *) 90 (sizeof(ARMsFFTSpec_SC32) + (OMX_S8*) pFFTSpec); 91 92 /* Align to 32 byte boundary */ 93 pTmp = ((uintptr_t)pTwiddle)&31; /* (uintptr_t)pTwiddle % 32 */ 94 if(pTmp != 0) 95 pTwiddle = (OMX_SC32*) ((OMX_S8*)pTwiddle + (32-pTmp)); 96 97 pBuf = (OMX_SC32*) 98 (sizeof(OMX_SC32) * (3*N/4) + (OMX_S8*) pTwiddle); 99 100 /* Align to 32 byte boundary */ 101 pTmp = ((OMX_U32)pBuf)&31; /* (OMX_U32)pBuf % 32 */ 102 if(pTmp != 0) 103 pBuf = (OMX_SC32*) ((OMX_S8*)pBuf + (32-pTmp)); 104 105 106 107 108 /* 109 * Filling Twiddle factors : 110 * The original twiddle table "armSP_FFT_S32TwiddleTable" is of size (MaxSize/8 + 1) 111 * Rest of the values i.e., upto MaxSize are calculated using the symmetries of sin and cos 112 * The max size of the twiddle table needed is 3N/4 for a radix-4 stage 113 * 114 * W = (-2 * PI) / N 115 * N = 1 << order 116 * W = -PI >> (order - 1) 117 */ 118 119 120 diff = 12 - order; 121 step = 1<<diff; /* step into the twiddle table for the current order */ 122 123 x = armSP_FFT_S32TwiddleTable[0]; 124 y = armSP_FFT_S32TwiddleTable[1]; 125 xNeg = 0x7FFFFFFF; 126 127 if(order >=3) 128 { 129 /* i = 0 case */ 130 pTwiddle[0].Re = x; 131 pTwiddle[0].Im = y; 132 pTwiddle[2*M].Re = -y; 133 pTwiddle[2*M].Im = xNeg; 134 pTwiddle[4*M].Re = xNeg; 135 pTwiddle[4*M].Im = y; 136 137 138 for (i=1; i<=M; i++) 139 { 140 j = i*step; 141 142 x = armSP_FFT_S32TwiddleTable[2*j]; 143 y = armSP_FFT_S32TwiddleTable[2*j+1]; 144 145 pTwiddle[i].Re = x; 146 pTwiddle[i].Im = y; 147 pTwiddle[2*M-i].Re = -y; 148 pTwiddle[2*M-i].Im = -x; 149 pTwiddle[2*M+i].Re = y; 150 pTwiddle[2*M+i].Im = -x; 151 pTwiddle[4*M-i].Re = -x; 152 pTwiddle[4*M-i].Im = y; 153 pTwiddle[4*M+i].Re = -x; 154 pTwiddle[4*M+i].Im = -y; 155 pTwiddle[6*M-i].Re = y; 156 pTwiddle[6*M-i].Im = x; 157 } 158 159 160 } 161 else 162 { 163 if (order == 2) 164 { 165 pTwiddle[0].Re = x; 166 pTwiddle[0].Im = y; 167 pTwiddle[1].Re = -y; 168 pTwiddle[1].Im = xNeg; 169 pTwiddle[2].Re = xNeg; 170 pTwiddle[2].Im = y; 171 172 } 173 if (order == 1) 174 { 175 pTwiddle[0].Re = x; 176 pTwiddle[0].Im = y; 177 178 } 179 180 181 } 182 183 184 185 /* Update the structure */ 186 pFFTStruct->N = N; 187 pFFTStruct->pTwiddle = pTwiddle; 188 pFFTStruct->pBitRev = pBitRev; 189 pFFTStruct->pBuf = pBuf; 190 191 return OMX_Sts_NoErr; 192 } 193 194 /***************************************************************************** 195 * END OF FILE 196 *****************************************************************************/ 197 198