2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
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.
10 * This file was originally licensed as follows. It has been
11 * relicensed with permission from the copyright holders.
16 * File Name: omxSP_FFTInit_R_S16S32.c
18 * Last Modified Revision: 7777
19 * Last Modified Date: Thu, 27 Sep 2007
21 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
25 * Initialize the real forward-FFT specification information struct.
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"
36 * Function: omxSP_FFTInit_R_S16_S32
39 * Initialize the real forward-FFT specification information struct.
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>.
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.
55 * Standard omxError result. See enumeration for possible result codes.
59 OMXResult omxSP_FFTInit_R_S16S32(
60 OMXFFTSpec_R_S16S32* pFFTSpec,
65 OMX_SC32 *pTwiddle,*pTwiddle1,*pTwiddle2,*pTwiddle3,*pTwiddle4;
69 OMX_INT Nby2,N,M,diff, step;
71 ARMsFFTSpec_R_SC32 *pFFTStruct = 0;
74 pFFTStruct = (ARMsFFTSpec_R_SC32 *) pFFTSpec;
76 /* if order zero no init is needed */
80 pFFTStruct->pTwiddle = NULL;
81 pFFTStruct->pBuf = (OMX_S32 *)
82 (sizeof(ARMsFFTSpec_R_SC32) + (OMX_S8*) pFFTSpec);
87 /* Do the initializations */
88 Nby2 = 1 << (order - 1);
93 pBitRev = NULL ; /* optimized implementations don't use bitreversal */
95 pTwiddle = (OMX_SC32 *)
96 (sizeof(ARMsFFTSpec_R_SC32) + (OMX_S8*) pFFTSpec);
98 /* Align to 32 byte boundary */
99 pTmp = ((uintptr_t)pTwiddle)&31; /* (OMX_U32)pTwiddle % 32 */
101 pTwiddle = (OMX_SC32*) ((OMX_S8*)pTwiddle + (32-pTmp));
105 (sizeof(OMX_SC32) * (5*N/8) + (OMX_S8*) pTwiddle);
107 /* Align to 32 byte boundary */
108 pTmp = ((uintptr_t)pBuf)&31; /* (OMX_U32)pBuf % 32 */
110 pBuf = (OMX_S32*) ((OMX_S8*)pBuf + (32-pTmp));
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
124 * W = -PI >> (order - 1)
128 diff = 12 - (order-1);
129 step = 1<<diff; /* step into the twiddle table for the current order */
131 x = armSP_FFT_S32TwiddleTable[0];
132 y = armSP_FFT_S32TwiddleTable[1];
140 pTwiddle[2*M].Re = -y;
141 pTwiddle[2*M].Im = xNeg;
142 pTwiddle[4*M].Re = xNeg;
143 pTwiddle[4*M].Im = y;
150 x = armSP_FFT_S32TwiddleTable[2*j];
151 y = armSP_FFT_S32TwiddleTable[2*j+1];
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;
176 pTwiddle[1].Im = xNeg;
177 pTwiddle[2].Re = xNeg;
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
201 pTwiddle1 = pTwiddle + 3*N/8;
202 pTwiddle4 = pTwiddle1 + (N/4-1);
203 pTwiddle3 = pTwiddle1 + N/8;
204 pTwiddle2 = pTwiddle1 + (N/8-1);
206 x = armSP_FFT_S32TwiddleTable[0];
207 y = armSP_FFT_S32TwiddleTable[1];
214 for (i=1; i<=M; i+=2 )
218 x = armSP_FFT_S32TwiddleTable[2*j];
219 y = armSP_FFT_S32TwiddleTable[2*j+1];
224 pTwiddle2[0].Re = -y;
225 pTwiddle2[0].Im = -x;
228 pTwiddle3[0].Im = -x;
230 pTwiddle4[0].Re = -x;
243 pTwiddle1[0].Re = -y;
244 pTwiddle1[0].Im = xNeg;
252 /* Update the structure */
254 pFFTStruct->pTwiddle = pTwiddle;
255 pFFTStruct->pBitRev = pBitRev;
256 pFFTStruct->pBuf = pBuf;
258 return OMX_Sts_NoErr;
260 /*****************************************************************************
262 *****************************************************************************/