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_C_SC32.c to support 11 * complex float instead of SC32. 12 */ 13 14#include <stdint.h> 15 16#include "dl/api/arm/armOMX.h" 17#include "dl/api/omxtypes.h" 18#include "dl/sp/api/armSP.h" 19#include "dl/sp/api/omxSP.h" 20 21/** 22 * Function: omxSP_FFTInit_C_FC32 23 * 24 * Description: 25 * Initializes the specification structures required for the 26 * complex FFT and IFFT functions. 27 * 28 * Remarks: 29 * Desired block length is specified as an input. The function is used to 30 * initialize the specification structures for functions <FFTFwd_CToC_FC32_Sfs> 31 * and <FFTInv_CToC_FC32_Sfs>. Memory for the specification structure *pFFTSpec 32 * must be allocated prior to calling this function. The space required for 33 * *pFFTSpec, in bytes, can be determined using <FFTGetBufSize_C_FC32>. 34 * 35 * Parameters: 36 * [in] order base-2 logarithm of the desired block length; 37 * valid in the range [1,12]. ([1,15] if 38 * BIG_FFT_TABLE is defined.) 39 * [out] pFFTSpec pointer to initialized specification structure. 40 * 41 * Return Value: 42 * Standard omxError result. See enumeration for possible result codes. 43 * 44 */ 45 46OMXResult omxSP_FFTInit_C_FC32(OMXFFTSpec_C_FC32* pFFTSpec, OMX_INT order) { 47 OMX_INT i; 48 OMX_INT j; 49 OMX_FC32* pTwiddle; 50 OMX_FC32* pBuf; 51 OMX_U16* pBitRev; 52 OMX_U32 pTmp; 53 OMX_INT Nby2; 54 OMX_INT N; 55 OMX_INT M; 56 OMX_INT diff; 57 OMX_INT step; 58 ARMsFFTSpec_FC32* pFFTStruct = 0; 59 OMX_F32 x; 60 OMX_F32 y; 61 OMX_F32 xNeg; 62 63 pFFTStruct = (ARMsFFTSpec_FC32 *) pFFTSpec; 64 65 /* Validate args */ 66 if (!pFFTSpec || (order < 1) || (order > TWIDDLE_TABLE_ORDER)) 67 return OMX_Sts_BadArgErr; 68 69 /* Do the initializations */ 70 Nby2 = 1 << (order - 1); 71 N = Nby2 << 1; 72 M = N >> 3; 73 74 /* optimized implementations don't use bitreversal */ 75 pBitRev = NULL; 76 77 pTwiddle = (OMX_FC32 *) (sizeof(ARMsFFTSpec_FC32) + (OMX_S8*) pFFTSpec); 78 79 /* Align to 32 byte boundary */ 80 pTmp = ((uintptr_t) pTwiddle) & 31; 81 if (pTmp) 82 pTwiddle = (OMX_FC32*) ((OMX_S8*)pTwiddle + (32 - pTmp)); 83 84 pBuf = (OMX_FC32*) (sizeof(OMX_FC32) * (3 * N / 4) + (OMX_S8*) pTwiddle); 85 86 /* Align to 32 byte boundary */ 87 pTmp = ((uintptr_t)pBuf) & 31; 88 if (pTmp) 89 pBuf = (OMX_FC32*) ((OMX_S8*)pBuf + (32 - pTmp)); 90 91 /* 92 * Filling Twiddle factors : 93 * 94 * The original twiddle table "armSP_FFT_S32TwiddleTable" is of size 95 * (MaxSize/8 + 1) Rest of the values i.e., upto MaxSize are 96 * calculated using the symmetries of sin and cos The max size of 97 * the twiddle table needed is 3N/4 for a radix-4 stage 98 * 99 * W = (-2 * PI) / N 100 * N = 1 << order 101 * W = -PI >> (order - 1) 102 */ 103 104 diff = TWIDDLE_TABLE_ORDER - order; 105 /* step into the twiddle table for the current order */ 106 step = 1 << diff; 107 108 x = armSP_FFT_F32TwiddleTable[0]; 109 y = armSP_FFT_F32TwiddleTable[1]; 110 xNeg = 1; 111 112 if (order >= 3) { 113 /* i = 0 case */ 114 pTwiddle[0].Re = x; 115 pTwiddle[0].Im = y; 116 pTwiddle[2 * M].Re = -y; 117 pTwiddle[2 * M].Im = xNeg; 118 pTwiddle[4 * M].Re = xNeg; 119 pTwiddle[4 * M].Im = y; 120 121 for (i = 1; i <= M; i++) { 122 j = i * step; 123 124 x = armSP_FFT_F32TwiddleTable[2 * j]; 125 y = armSP_FFT_F32TwiddleTable[2 * j + 1]; 126 127 pTwiddle[i].Re = x; 128 pTwiddle[i].Im = y; 129 pTwiddle[2 * M - i].Re = -y; 130 pTwiddle[2 * M - i].Im = -x; 131 pTwiddle[2 * M + i].Re = y; 132 pTwiddle[2 * M + i].Im = -x; 133 pTwiddle[4 * M - i].Re = -x; 134 pTwiddle[4 * M - i].Im = y; 135 pTwiddle[4 * M + i].Re = -x; 136 pTwiddle[4 * M + i].Im = -y; 137 pTwiddle[6 * M - i].Re = y; 138 pTwiddle[6 * M - i].Im = x; 139 } 140 } else if (order == 2) { 141 pTwiddle[0].Re = x; 142 pTwiddle[0].Im = y; 143 pTwiddle[1].Re = -y; 144 pTwiddle[1].Im = xNeg; 145 pTwiddle[2].Re = xNeg; 146 pTwiddle[2].Im = y; 147 } else if (order == 1) { 148 pTwiddle[0].Re = x; 149 pTwiddle[0].Im = y; 150 } 151 152 /* Update the structure */ 153 pFFTStruct->N = N; 154 pFFTStruct->pTwiddle = pTwiddle; 155 pFFTStruct->pBitRev = pBitRev; 156 pFFTStruct->pBuf = pBuf; 157 158 return OMX_Sts_NoErr; 159} 160 161/***************************************************************************** 162 * END OF FILE 163 *****************************************************************************/ 164