Aded CMSIS5 DSP and NN folder. Needs some work

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_cfft_q31.c Source File

arm_cfft_q31.c

00001 /* ----------------------------------------------------------------------
00002  * Project:      CMSIS DSP Library
00003  * Title:        arm_cfft_q31.c
00004  * Description:  Combined Radix Decimation in Frequency CFFT fixed point processing function
00005  *
00006  * $Date:        27. January 2017
00007  * $Revision:    V.1.5.1
00008  *
00009  * Target Processor: Cortex-M cores
00010  * -------------------------------------------------------------------- */
00011 /*
00012  * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
00013  *
00014  * SPDX-License-Identifier: Apache-2.0
00015  *
00016  * Licensed under the Apache License, Version 2.0 (the License); you may
00017  * not use this file except in compliance with the License.
00018  * You may obtain a copy of the License at
00019  *
00020  * www.apache.org/licenses/LICENSE-2.0
00021  *
00022  * Unless required by applicable law or agreed to in writing, software
00023  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00024  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00025  * See the License for the specific language governing permissions and
00026  * limitations under the License.
00027  */
00028 
00029 #include "arm_math.h"
00030 
00031 extern void arm_radix4_butterfly_q31(
00032     q31_t * pSrc,
00033     uint32_t fftLen,
00034     q31_t * pCoef,
00035     uint32_t twidCoefModifier);
00036 
00037 extern void arm_radix4_butterfly_inverse_q31(
00038     q31_t * pSrc,
00039     uint32_t fftLen,
00040     q31_t * pCoef,
00041     uint32_t twidCoefModifier);
00042 
00043 extern void arm_bitreversal_32(
00044     uint32_t * pSrc,
00045     const uint16_t bitRevLen,
00046     const uint16_t * pBitRevTable);
00047 
00048 void arm_cfft_radix4by2_q31(
00049     q31_t * pSrc,
00050     uint32_t fftLen,
00051     const q31_t * pCoef);
00052 
00053 void arm_cfft_radix4by2_inverse_q31(
00054     q31_t * pSrc,
00055     uint32_t fftLen,
00056     const q31_t * pCoef);
00057 
00058 /**
00059 * @ingroup groupTransforms
00060 */
00061 
00062 /**
00063 * @addtogroup ComplexFFT
00064 * @{
00065 */
00066 
00067 /**
00068 * @details
00069 * @brief       Processing function for the fixed-point complex FFT in Q31 format.
00070 * @param[in]      *S    points to an instance of the fixed-point CFFT structure.
00071 * @param[in, out] *p1   points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
00072 * @param[in]     ifftFlag       flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
00073 * @param[in]     bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
00074 * @return none.
00075 */
00076 
00077 void arm_cfft_q31(
00078     const arm_cfft_instance_q31 * S,
00079     q31_t * p1,
00080     uint8_t ifftFlag,
00081     uint8_t bitReverseFlag)
00082 {
00083     uint32_t L = S->fftLen;
00084 
00085     if (ifftFlag == 1U)
00086     {
00087         switch (L)
00088         {
00089         case 16:
00090         case 64:
00091         case 256:
00092         case 1024:
00093         case 4096:
00094             arm_radix4_butterfly_inverse_q31  ( p1, L, (q31_t*)S->pTwiddle, 1 );
00095             break;
00096 
00097         case 32:
00098         case 128:
00099         case 512:
00100         case 2048:
00101             arm_cfft_radix4by2_inverse_q31  ( p1, L, S->pTwiddle );
00102             break;
00103         }
00104     }
00105     else
00106     {
00107         switch (L)
00108         {
00109         case 16:
00110         case 64:
00111         case 256:
00112         case 1024:
00113         case 4096:
00114             arm_radix4_butterfly_q31  ( p1, L, (q31_t*)S->pTwiddle, 1 );
00115             break;
00116 
00117         case 32:
00118         case 128:
00119         case 512:
00120         case 2048:
00121             arm_cfft_radix4by2_q31  ( p1, L, S->pTwiddle );
00122             break;
00123         }
00124     }
00125 
00126     if ( bitReverseFlag )
00127         arm_bitreversal_32((uint32_t*)p1,S->bitRevLength,S->pBitRevTable);
00128 }
00129 
00130 /**
00131 * @} end of ComplexFFT group
00132 */
00133 
00134 void arm_cfft_radix4by2_q31(
00135     q31_t * pSrc,
00136     uint32_t fftLen,
00137     const q31_t * pCoef)
00138 {
00139     uint32_t i, l;
00140     uint32_t n2, ia;
00141     q31_t xt, yt, cosVal, sinVal;
00142     q31_t p0, p1;
00143 
00144     n2 = fftLen >> 1;
00145     ia = 0;
00146     for (i = 0; i < n2; i++)
00147     {
00148         cosVal = pCoef[2*ia];
00149         sinVal = pCoef[2*ia + 1];
00150         ia++;
00151 
00152         l = i + n2;
00153         xt = (pSrc[2 * i] >> 2) - (pSrc[2 * l] >> 2);
00154         pSrc[2 * i] = (pSrc[2 * i] >> 2) + (pSrc[2 * l] >> 2);
00155 
00156         yt = (pSrc[2 * i + 1] >> 2) - (pSrc[2 * l + 1] >> 2);
00157         pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2) + (pSrc[2 * i + 1] >> 2);
00158 
00159         mult_32x32_keep32_R(p0, xt, cosVal);
00160         mult_32x32_keep32_R(p1, yt, cosVal);
00161         multAcc_32x32_keep32_R(p0, yt, sinVal);
00162         multSub_32x32_keep32_R(p1, xt, sinVal);
00163 
00164         pSrc[2U * l] = p0 << 1;
00165         pSrc[2U * l + 1U] = p1 << 1;
00166 
00167     }
00168 
00169     // first col
00170     arm_radix4_butterfly_q31( pSrc, n2, (q31_t*)pCoef, 2U);
00171     // second col
00172     arm_radix4_butterfly_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2U);
00173 
00174     for (i = 0; i < fftLen >> 1; i++)
00175     {
00176         p0 = pSrc[4*i+0];
00177         p1 = pSrc[4*i+1];
00178         xt = pSrc[4*i+2];
00179         yt = pSrc[4*i+3];
00180 
00181         p0 <<= 1;
00182         p1 <<= 1;
00183         xt <<= 1;
00184         yt <<= 1;
00185 
00186         pSrc[4*i+0] = p0;
00187         pSrc[4*i+1] = p1;
00188         pSrc[4*i+2] = xt;
00189         pSrc[4*i+3] = yt;
00190     }
00191 
00192 }
00193 
00194 void arm_cfft_radix4by2_inverse_q31(
00195     q31_t * pSrc,
00196     uint32_t fftLen,
00197     const q31_t * pCoef)
00198 {
00199     uint32_t i, l;
00200     uint32_t n2, ia;
00201     q31_t xt, yt, cosVal, sinVal;
00202     q31_t p0, p1;
00203 
00204     n2 = fftLen >> 1;
00205     ia = 0;
00206     for (i = 0; i < n2; i++)
00207     {
00208         cosVal = pCoef[2*ia];
00209         sinVal = pCoef[2*ia + 1];
00210         ia++;
00211 
00212         l = i + n2;
00213         xt = (pSrc[2 * i] >> 2) - (pSrc[2 * l] >> 2);
00214         pSrc[2 * i] = (pSrc[2 * i] >> 2) + (pSrc[2 * l] >> 2);
00215 
00216         yt = (pSrc[2 * i + 1] >> 2) - (pSrc[2 * l + 1] >> 2);
00217         pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2) + (pSrc[2 * i + 1] >> 2);
00218 
00219         mult_32x32_keep32_R(p0, xt, cosVal);
00220         mult_32x32_keep32_R(p1, yt, cosVal);
00221         multSub_32x32_keep32_R(p0, yt, sinVal);
00222         multAcc_32x32_keep32_R(p1, xt, sinVal);
00223 
00224         pSrc[2U * l] = p0 << 1;
00225         pSrc[2U * l + 1U] = p1 << 1;
00226 
00227     }
00228 
00229     // first col
00230     arm_radix4_butterfly_inverse_q31( pSrc, n2, (q31_t*)pCoef, 2U);
00231     // second col
00232     arm_radix4_butterfly_inverse_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2U);
00233 
00234     for (i = 0; i < fftLen >> 1; i++)
00235     {
00236         p0 = pSrc[4*i+0];
00237         p1 = pSrc[4*i+1];
00238         xt = pSrc[4*i+2];
00239         yt = pSrc[4*i+3];
00240 
00241         p0 <<= 1;
00242         p1 <<= 1;
00243         xt <<= 1;
00244         yt <<= 1;
00245 
00246         pSrc[4*i+0] = p0;
00247         pSrc[4*i+1] = p1;
00248         pSrc[4*i+2] = xt;
00249         pSrc[4*i+3] = yt;
00250     }
00251 }
00252 
00253