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 extern void ComplexToRealFixup(OMX_FC32* pSrc,
     65                                OMX_F32* pDst,
     66                                const OMX_FC32* pTwiddle,
     67                                OMX_F32* pBuf,
     68                                long N);
     69 
     70 /**
     71  * Function:  omxSP_FFTFwd_CToC_FC32_Sfs   (2.2.4.2.2)
     72  *
     73  * Description:
     74  * Compute an FFT for a complex signal of length of 2^order,
     75  * where 0 <= order <= 15.
     76  * Transform length is determined by the specification structure, which
     77  * must be initialized prior to calling the FFT function using the appropriate
     78  * helper, i.e., <FFTInit_C_sc32> or <FFTInit_C_SC16>. The relationship
     79  * between the input and output sequences can be expressed in terms of the
     80  * DFT, i.e.,
     81  *
     82  *      X[k] = SUM[n=0...N-1]x[n].e^(-jnk.2.pi/N)
     83  *      k = 0,1,2,..., N-1
     84  *      N = 2^order
     85  *
     86  * Input Arguments:
     87  *   pSrc - pointer to the input signal, a complex-valued vector of length
     88  *            2^order; must be aligned on a 32 byte boundary.
     89  *   pFFTSpec - pointer to the preallocated and initialized specification
     90  *            structure
     91  *
     92  * Output Arguments:
     93  *   pDst - pointer to the complex-valued output vector, of length 2^order;
     94  *            must be aligned on an 32-byte boundary.
     95  *
     96  * Return Value:
     97  *
     98  *    OMX_Sts_NoErr - no error
     99  *    OMX_Sts_BadArgErr - returned if one or more of the following conditions
    100  *              is true:
    101  *    -   one or more of the following pointers is NULL: pSrc, pDst, or
    102  *              pFFTSpec.
    103  *    -    pSrc or pDst is not 32-byte aligned
    104  *
    105  */
    106 
    107 OMXResult omxSP_FFTFwd_RToCCS_F32_Sfs(const OMX_F32* pSrc,
    108                                       OMX_F32* pDst,
    109                                       const OMXFFTSpec_R_F32* pFFTSpec) {
    110   ARMsFFTSpec_R_FC32* spec = (ARMsFFTSpec_R_FC32*)pFFTSpec;
    111   int order;
    112   long subFFTSize;
    113   long subFFTNum;
    114   OMX_FC32* pTwiddle;
    115   OMX_FC32* pOut;
    116   OMX_FC32* pComplexSrc = (OMX_FC32*) pSrc;
    117   OMX_FC32* pComplexDst = (OMX_FC32*) pDst;
    118 
    119   /*
    120    * Check args are not NULL and the source and destination pointers
    121    * are properly aligned.
    122    */
    123   if (!validateParametersF32(pSrc, pDst, spec))
    124     return OMX_Sts_BadArgErr;
    125 
    126   /*
    127    * Compute the RFFT using a complex FFT of one less order, so set
    128    * order to be the order of the complex FFT.
    129    */
    130   order = fastlog2(spec->N) - 1;
    131 
    132   subFFTSize = 1;
    133   subFFTNum = spec->N >> 1;
    134   pTwiddle = spec->pTwiddle;
    135   pOut = (OMX_FC32*) spec->pBuf;
    136 
    137   if (order > 3) {
    138     OMX_FC32* argDst;
    139     OMX_FC32* pComplexDst = (OMX_FC32*) pDst;
    140 
    141     /*
    142      * Set up argDst and pOut appropriately so that pOut = pDst for
    143      * ComplexToRealFixup.
    144      */
    145     if ((order & 2) != 0) {
    146       argDst = pOut;
    147       pOut = pComplexDst;
    148     } else {
    149       argDst = pComplexDst;
    150     }
    151 
    152     /*
    153      * Odd order uses a radix 8 first stage; even order, a radix 4
    154      * first stage.
    155      */
    156     if (order & 1) {
    157       armSP_FFTFwd_CToC_FC32_Radix8_fs_OutOfPlace(
    158           pComplexSrc, argDst, pTwiddle, &subFFTNum, &subFFTSize);
    159     } else {
    160       armSP_FFTFwd_CToC_FC32_Radix4_fs_OutOfPlace(
    161           pComplexSrc, argDst, pTwiddle, &subFFTNum, &subFFTSize);
    162     }
    163 
    164     /*
    165      * Now use radix 4 stages to finish rest of the FFT
    166      */
    167     if (subFFTNum >= 4) {
    168       while (subFFTNum > 4) {
    169         OMX_FC32* tmp;
    170 
    171         armSP_FFTFwd_CToC_FC32_Radix4_OutOfPlace(
    172             argDst, pOut, pTwiddle, &subFFTNum, &subFFTSize);
    173         /*
    174          * Swap argDst and pOut
    175          */
    176         tmp = pOut;
    177         pOut = argDst;
    178         argDst = tmp;
    179       }
    180 
    181       armSP_FFTFwd_CToC_FC32_Radix4_ls_OutOfPlace(
    182           argDst, pOut, pTwiddle, &subFFTNum, &subFFTSize);
    183     }
    184   } else if (order == 3) {
    185     armSP_FFTFwd_CToC_FC32_Radix2_fs_OutOfPlace(
    186         pComplexSrc, pOut, pTwiddle, &subFFTNum, &subFFTSize);
    187     armSP_FFTFwd_CToC_FC32_Radix2_OutOfPlace(
    188         pOut, pComplexDst, pTwiddle, &subFFTNum, &subFFTSize);
    189     armSP_FFTFwd_CToC_FC32_Radix2_ls_OutOfPlace(
    190         pComplexDst, pOut, pTwiddle, &subFFTNum, &subFFTSize);
    191   } else if (order == 2) {
    192     armSP_FFTFwd_CToC_FC32_Radix2_fs_OutOfPlace(
    193         pComplexSrc, pComplexDst, pTwiddle, &subFFTNum, &subFFTSize);
    194     armSP_FFTFwd_CToC_FC32_Radix2_ls_OutOfPlace(
    195         pComplexDst, pOut, pTwiddle, &subFFTNum, &subFFTSize);
    196   } else if (order == 1) {
    197     armSP_FFTFwd_CToC_FC32_Radix2_fs_OutOfPlace(
    198         pComplexSrc, pOut, pTwiddle, &subFFTNum, &subFFTSize);
    199   } else {
    200     /* Handle complex order 0 specially */
    201     pOut->Re = pSrc[0];
    202     pOut->Im = pSrc[1];
    203   }
    204 
    205   /*
    206    * Complex FFT done. Fix up the complex result to give the correct
    207    * RFFT.
    208    */
    209 
    210   ComplexToRealFixup(pOut, pDst, pTwiddle, spec->pBuf, spec->N);
    211 
    212   return OMX_Sts_NoErr;
    213 }
    214