Home | History | Annotate | Download | only in arm64
      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 
     15 extern 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 
     22 extern 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 
     29 extern 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 
     36 extern 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 
     43 extern 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 
     50 extern 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 
     57 extern 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 
    101 OMXResult 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