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_SC16.c 17 * OpenMAX DL: v1.0.2 18 * Last Modified Revision: 15322 19 * Last Modified Date: Wed, 15 Oct 2008 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_SC16 37 * 38 * Description: 39 * These functions initialize 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_SC16_Sfs> 45 * and <FFTInv_CToC_SC16_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_SC16>. 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_SC16( 60 OMXFFTSpec_C_SC16* pFFTSpec, 61 OMX_INT order 62 ) 63 { 64 OMX_INT i,j; 65 OMX_SC16 *pTwiddle, *pBuf; 66 OMX_U16 *pBitRev; 67 OMX_INT Nby2,N,M,diff,step; 68 OMX_U32 pTmp; 69 ARMsFFTSpec_SC16 *pFFTStruct = 0; 70 OMX_S16 x,y,xNeg; 71 OMX_S32 xS32,yS32; 72 73 74 pFFTStruct = (ARMsFFTSpec_SC16 *) pFFTSpec; 75 76 /* if order zero no init is needed */ 77 if (order == 0) 78 { 79 pFFTStruct->N = 1; 80 return OMX_Sts_NoErr; 81 } 82 83 /* Do the initializations */ 84 Nby2 = 1 << (order - 1); 85 N = Nby2 << 1; 86 M = N>>3; 87 88 pBitRev = NULL ; 89 90 pTwiddle = (OMX_SC16 *) 91 (sizeof(ARMsFFTSpec_SC16) + (OMX_S8*) pFFTSpec); 92 93 /* Align to 32 byte boundary */ 94 pTmp = ((uintptr_t)pTwiddle)&31; /* (uintptr_t)pTwiddle % 32 */ 95 if(pTmp != 0) 96 pTwiddle = (OMX_SC16*) ((OMX_S8*)pTwiddle + (32-pTmp)); 97 98 pBuf = (OMX_SC16 *) 99 (sizeof(OMX_SC16) * (3*N/4) + (OMX_S8*) pTwiddle); 100 101 /* Align to 32 byte boundary */ 102 pTmp = ((uintptr_t)pBuf)&31; /* (uintptr_t)pBuf % 32 */ 103 if(pTmp != 0) 104 pBuf = (OMX_SC16*) ((OMX_S8*)pBuf + (32-pTmp)); 105 106 107 108 /* 109 * Filling Twiddle factors : 110 * The original twiddle table "armSP_FFT_S16TwiddleTable" 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 121 diff = 12 - order; 122 step = 1<<diff; /* step into the twiddle table for the current order */ 123 124 xS32 = armSP_FFT_S32TwiddleTable[0]; 125 yS32 = armSP_FFT_S32TwiddleTable[1]; 126 x = (xS32+0x8000)>>16; 127 y = (yS32+0x8000)>>16; 128 129 xNeg = 0x7FFF; 130 131 if(order >=3) 132 { 133 /* i = 0 case */ 134 pTwiddle[0].Re = x; 135 pTwiddle[0].Im = y; 136 pTwiddle[2*M].Re = -y; 137 pTwiddle[2*M].Im = xNeg; 138 pTwiddle[4*M].Re = xNeg; 139 pTwiddle[4*M].Im = y; 140 141 142 for (i=1; i<=M; i++) 143 { 144 j = i*step; 145 146 xS32 = armSP_FFT_S32TwiddleTable[2*j]; 147 yS32 = armSP_FFT_S32TwiddleTable[2*j+1]; 148 x = (xS32+0x8000)>>16; 149 y = (yS32+0x8000)>>16; 150 151 pTwiddle[i].Re = x; 152 pTwiddle[i].Im = y; 153 pTwiddle[2*M-i].Re = -y; 154 pTwiddle[2*M-i].Im = -x; 155 pTwiddle[2*M+i].Re = y; 156 pTwiddle[2*M+i].Im = -x; 157 pTwiddle[4*M-i].Re = -x; 158 pTwiddle[4*M-i].Im = y; 159 pTwiddle[4*M+i].Re = -x; 160 pTwiddle[4*M+i].Im = -y; 161 pTwiddle[6*M-i].Re = y; 162 pTwiddle[6*M-i].Im = x; 163 } 164 165 166 } 167 else 168 { 169 if (order == 2) 170 { 171 pTwiddle[0].Re = x; 172 pTwiddle[0].Im = y; 173 pTwiddle[1].Re = -y; 174 pTwiddle[1].Im = xNeg; 175 pTwiddle[2].Re = xNeg; 176 pTwiddle[2].Im = y; 177 178 } 179 if (order == 1) 180 { 181 pTwiddle[0].Re = x; 182 pTwiddle[0].Im = y; 183 184 } 185 186 187 } 188 189 190 /* Update the structure */ 191 pFFTStruct->N = N; 192 pFFTStruct->pTwiddle = pTwiddle; 193 pFFTStruct->pBitRev = pBitRev; 194 pFFTStruct->pBuf = pBuf; 195 196 return OMX_Sts_NoErr; 197 } 198 199 /***************************************************************************** 200 * END OF FILE 201 *****************************************************************************/ 202 203