1/* 2 * Copyright (c) 2014 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 11#include "dl/api/omxtypes.h" 12#include "dl/sp/api/armSP.h" 13#include "dl/sp/api/omxSP.h" 14 15extern void armSP_FFTFwd_CToC_FC32_Radix2_fs_OutOfPlace( 16 const OMX_FC32* pSrc, 17 OMX_FC32* pDst, 18 OMX_FC32* pTwiddle, 19 long* subFFTNum, 20 long* subFFTSize); 21 22extern void armSP_FFTFwd_CToC_FC32_Radix2_ls_OutOfPlace( 23 const OMX_FC32* pSrc, 24 OMX_FC32* pDst, 25 OMX_FC32* pTwiddle, 26 long* subFFTNum, 27 long* subFFTSize); 28 29extern void armSP_FFTFwd_CToC_FC32_Radix2_OutOfPlace( 30 const OMX_FC32* pSrc, 31 OMX_FC32* pDst, 32 OMX_FC32* pTwiddle, 33 long* subFFTNum, 34 long* subFFTSize); 35 36extern void armSP_FFTFwd_CToC_FC32_Radix4_fs_OutOfPlace( 37 const OMX_FC32* pSrc, 38 OMX_FC32* pDst, 39 OMX_FC32* pTwiddle, 40 long* subFFTNum, 41 long* subFFTSize); 42 43extern void armSP_FFTFwd_CToC_FC32_Radix4_OutOfPlace( 44 const OMX_FC32* pSrc, 45 OMX_FC32* pDst, 46 OMX_FC32* pTwiddle, 47 long* subFFTNum, 48 long* subFFTSize); 49 50extern void armSP_FFTFwd_CToC_FC32_Radix4_ls_OutOfPlace( 51 const OMX_FC32* pSrc, 52 OMX_FC32* pDst, 53 OMX_FC32* pTwiddle, 54 long* subFFTNum, 55 long* subFFTSize); 56 57extern void armSP_FFTFwd_CToC_FC32_Radix8_fs_OutOfPlace( 58 const OMX_FC32* pSrc, 59 OMX_FC32* pDst, 60 OMX_FC32* pTwiddle, 61 long* subFFTNum, 62 long* subFFTSize); 63 64/** 65 * Function: omxSP_FFTFwd_CToC_FC32_Sfs (2.2.4.2.2) 66 * 67 * Description: 68 * Compute an FFT for a complex signal of length of 2^order, 69 * where 0 <= order <= 15. 70 * Transform length is determined by the specification structure, which 71 * must be initialized prior to calling the FFT function using the appropriate 72 * helper, i.e., <FFTInit_C_sc32> or <FFTInit_C_SC16>. The relationship 73 * between the input and output sequences can be expressed in terms of the 74 * DFT, i.e., 75 * 76 * X[k] = SUM[n=0...N-1]x[n].e^(-jnk.2.pi/N) 77 * k = 0,1,2,..., N-1 78 * N = 2^order 79 * 80 * Input Arguments: 81 * pSrc - pointer to the input signal, a complex-valued vector of length 82 * 2^order; must be aligned on a 32 byte boundary. 83 * pFFTSpec - pointer to the preallocated and initialized specification 84 * structure 85 * 86 * Output Arguments: 87 * pDst - pointer to the complex-valued output vector, of length 2^order; 88 * must be aligned on an 32-byte boundary. 89 * 90 * Return Value: 91 * 92 * OMX_Sts_NoErr - no error 93 * OMX_Sts_BadArgErr - returned if one or more of the following conditions 94 * is true: 95 * - one or more of the following pointers is NULL: pSrc, pDst, or 96 * pFFTSpec. 97 * - pSrc or pDst is not 32-byte aligned 98 * 99 */ 100 101OMXResult omxSP_FFTFwd_CToC_FC32_Sfs(const OMX_FC32* pSrc, 102 OMX_FC32* pDst, 103 const OMXFFTSpec_C_FC32* pFFTSpec) { 104 ARMsFFTSpec_FC32* spec = (ARMsFFTSpec_FC32*)pFFTSpec; 105 int order; 106 long subFFTSize; 107 long subFFTNum; 108 OMX_FC32* pTwiddle; 109 OMX_FC32* pOut; 110 111 /* 112 * Check args are not NULL and the source and destination pointers 113 * are properly aligned. 114 */ 115 if (!validateParametersFC32(pSrc, pDst, spec)) 116 return OMX_Sts_BadArgErr; 117 118 order = fastlog2(spec->N); 119 120 subFFTSize = 1; 121 subFFTNum = spec->N; 122 pTwiddle = spec->pTwiddle; 123 pOut = spec->pBuf; 124 125 if (order > 3) { 126 OMX_FC32* argDst; 127 128 /* 129 * Set up argDst and pOut appropriately so that pOut = pDst for 130 * the very last FFT stage. 131 */ 132 if ((order & 2) == 0) { 133 argDst = pOut; 134 pOut = pDst; 135 } else { 136 argDst = pDst; 137 } 138 139 /* 140 * Odd order uses a radix 8 first stage; even order, a radix 4 141 * first stage. 142 */ 143 if (order & 1) { 144 armSP_FFTFwd_CToC_FC32_Radix8_fs_OutOfPlace( 145 pSrc, argDst, pTwiddle, &subFFTNum, &subFFTSize); 146 } else { 147 armSP_FFTFwd_CToC_FC32_Radix4_fs_OutOfPlace( 148 pSrc, argDst, pTwiddle, &subFFTNum, &subFFTSize); 149 } 150 151 /* 152 * Now use radix 4 stages to finish rest of the FFT 153 */ 154 if (subFFTNum >= 4) { 155 while (subFFTNum > 4) { 156 OMX_FC32* tmp; 157 158 armSP_FFTFwd_CToC_FC32_Radix4_OutOfPlace( 159 argDst, pOut, pTwiddle, &subFFTNum, &subFFTSize); 160 /* 161 * Swap argDst and pOut 162 */ 163 tmp = pOut; 164 pOut = argDst; 165 argDst = tmp; 166 } 167 168 armSP_FFTFwd_CToC_FC32_Radix4_ls_OutOfPlace( 169 argDst, pOut, pTwiddle, &subFFTNum, &subFFTSize); 170 } 171 } else if (order == 3) { 172 armSP_FFTFwd_CToC_FC32_Radix2_fs_OutOfPlace( 173 pSrc, pDst, pTwiddle, &subFFTNum, &subFFTSize); 174 armSP_FFTFwd_CToC_FC32_Radix2_OutOfPlace( 175 pDst, pOut, pTwiddle, &subFFTNum, &subFFTSize); 176 armSP_FFTFwd_CToC_FC32_Radix2_ls_OutOfPlace( 177 pOut, pDst, pTwiddle, &subFFTNum, &subFFTSize); 178 } else if (order == 2) { 179 armSP_FFTFwd_CToC_FC32_Radix2_fs_OutOfPlace( 180 pSrc, pOut, pTwiddle, &subFFTNum, &subFFTSize); 181 armSP_FFTFwd_CToC_FC32_Radix2_ls_OutOfPlace( 182 pOut, pDst, pTwiddle, &subFFTNum, &subFFTSize); 183 } else { 184 /* Order = 1 */ 185 armSP_FFTFwd_CToC_FC32_Radix2_fs_OutOfPlace( 186 pSrc, pDst, pTwiddle, &subFFTNum, &subFFTSize); 187 } 188 189 return OMX_Sts_NoErr; 190} 191