Aded CMSIS5 DSP and NN folder. Needs some work

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_cfft_f32.c Source File

arm_cfft_f32.c

00001 /* ----------------------------------------------------------------------
00002  * Project:      CMSIS DSP Library
00003  * Title:        arm_cfft_f32.c
00004  * Description:  Combined Radix Decimation in Frequency CFFT Floating 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 #include "arm_common_tables.h"
00031 
00032 extern void arm_radix8_butterfly_f32(
00033     float32_t * pSrc,
00034     uint16_t fftLen,
00035     const float32_t * pCoef,
00036     uint16_t twidCoefModifier);
00037 
00038 extern void arm_bitreversal_32(
00039     uint32_t * pSrc,
00040     const uint16_t bitRevLen,
00041     const uint16_t * pBitRevTable);
00042 
00043 /**
00044 * @ingroup groupTransforms
00045 */
00046 
00047 /**
00048 * @defgroup ComplexFFT Complex FFT Functions
00049 *
00050 * \par
00051 * The Fast Fourier Transform (FFT) is an efficient algorithm for computing the
00052 * Discrete Fourier Transform (DFT).  The FFT can be orders of magnitude faster
00053 * than the DFT, especially for long lengths.
00054 * The algorithms described in this section
00055 * operate on complex data.  A separate set of functions is devoted to handling
00056 * of real sequences.
00057 * \par
00058 * There are separate algorithms for handling floating-point, Q15, and Q31 data
00059 * types.  The algorithms available for each data type are described next.
00060 * \par
00061 * The FFT functions operate in-place.  That is, the array holding the input data
00062 * will also be used to hold the corresponding result.  The input data is complex
00063 * and contains <code>2*fftLen</code> interleaved values as shown below.
00064 * <pre> {real[0], imag[0], real[1], imag[1],..} </pre>
00065 * The FFT result will be contained in the same array and the frequency domain
00066 * values will have the same interleaving.
00067 *
00068 * \par Floating-point
00069 * The floating-point complex FFT uses a mixed-radix algorithm.  Multiple radix-8
00070 * stages are performed along with a single radix-2 or radix-4 stage, as needed.
00071 * The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses
00072 * a different twiddle factor table.
00073 * \par
00074 * The function uses the standard FFT definition and output values may grow by a
00075 * factor of <code>fftLen</code> when computing the forward transform.  The
00076 * inverse transform includes a scale of <code>1/fftLen</code> as part of the
00077 * calculation and this matches the textbook definition of the inverse FFT.
00078 * \par
00079 * Pre-initialized data structures containing twiddle factors and bit reversal
00080 * tables are provided and defined in <code>arm_const_structs.h</code>.  Include
00081 * this header in your function and then pass one of the constant structures as
00082 * an argument to arm_cfft_f32.  For example:
00083 * \par
00084 * <code>arm_cfft_f32(arm_cfft_sR_f32_len64, pSrc, 1, 1)</code>
00085 * \par
00086 * computes a 64-point inverse complex FFT including bit reversal.
00087 * The data structures are treated as constant data and not modified during the
00088 * calculation.  The same data structure can be reused for multiple transforms
00089 * including mixing forward and inverse transforms.
00090 * \par
00091 * Earlier releases of the library provided separate radix-2 and radix-4
00092 * algorithms that operated on floating-point data.  These functions are still
00093 * provided but are deprecated.  The older functions are slower and less general
00094 * than the new functions.
00095 * \par
00096 * An example of initialization of the constants for the arm_cfft_f32 function follows:
00097 * \code
00098 * const static arm_cfft_instance_f32 *S;
00099 * ...
00100 *   switch (length) {
00101 *     case 16:
00102 *       S = &arm_cfft_sR_f32_len16;
00103 *       break;
00104 *     case 32:
00105 *       S = &arm_cfft_sR_f32_len32;
00106 *       break;
00107 *     case 64:
00108 *       S = &arm_cfft_sR_f32_len64;
00109 *       break;
00110 *     case 128:
00111 *       S = &arm_cfft_sR_f32_len128;
00112 *       break;
00113 *     case 256:
00114 *       S = &arm_cfft_sR_f32_len256;
00115 *       break;
00116 *     case 512:
00117 *       S = &arm_cfft_sR_f32_len512;
00118 *       break;
00119 *     case 1024:
00120 *       S = &arm_cfft_sR_f32_len1024;
00121 *       break;
00122 *     case 2048:
00123 *       S = &arm_cfft_sR_f32_len2048;
00124 *       break;
00125 *     case 4096:
00126 *       S = &arm_cfft_sR_f32_len4096;
00127 *       break;
00128 *   }
00129 * \endcode
00130 * \par Q15 and Q31
00131 * The floating-point complex FFT uses a mixed-radix algorithm.  Multiple radix-4
00132 * stages are performed along with a single radix-2 stage, as needed.
00133 * The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses
00134 * a different twiddle factor table.
00135 * \par
00136 * The function uses the standard FFT definition and output values may grow by a
00137 * factor of <code>fftLen</code> when computing the forward transform.  The
00138 * inverse transform includes a scale of <code>1/fftLen</code> as part of the
00139 * calculation and this matches the textbook definition of the inverse FFT.
00140 * \par
00141 * Pre-initialized data structures containing twiddle factors and bit reversal
00142 * tables are provided and defined in <code>arm_const_structs.h</code>.  Include
00143 * this header in your function and then pass one of the constant structures as
00144 * an argument to arm_cfft_q31.  For example:
00145 * \par
00146 * <code>arm_cfft_q31(arm_cfft_sR_q31_len64, pSrc, 1, 1)</code>
00147 * \par
00148 * computes a 64-point inverse complex FFT including bit reversal.
00149 * The data structures are treated as constant data and not modified during the
00150 * calculation.  The same data structure can be reused for multiple transforms
00151 * including mixing forward and inverse transforms.
00152 * \par
00153 * Earlier releases of the library provided separate radix-2 and radix-4
00154 * algorithms that operated on floating-point data.  These functions are still
00155 * provided but are deprecated.  The older functions are slower and less general
00156 * than the new functions.
00157 * \par
00158 * An example of initialization of the constants for the arm_cfft_q31 function follows:
00159 * \code
00160 * const static arm_cfft_instance_q31 *S;
00161 * ...
00162 *   switch (length) {
00163 *     case 16:
00164 *       S = &arm_cfft_sR_q31_len16;
00165 *       break;
00166 *     case 32:
00167 *       S = &arm_cfft_sR_q31_len32;
00168 *       break;
00169 *     case 64:
00170 *       S = &arm_cfft_sR_q31_len64;
00171 *       break;
00172 *     case 128:
00173 *       S = &arm_cfft_sR_q31_len128;
00174 *       break;
00175 *     case 256:
00176 *       S = &arm_cfft_sR_q31_len256;
00177 *       break;
00178 *     case 512:
00179 *       S = &arm_cfft_sR_q31_len512;
00180 *       break;
00181 *     case 1024:
00182 *       S = &arm_cfft_sR_q31_len1024;
00183 *       break;
00184 *     case 2048:
00185 *       S = &arm_cfft_sR_q31_len2048;
00186 *       break;
00187 *     case 4096:
00188 *       S = &arm_cfft_sR_q31_len4096;
00189 *       break;
00190 *   }
00191 * \endcode
00192 *
00193 */
00194 
00195 void arm_cfft_radix8by2_f32( arm_cfft_instance_f32 * S, float32_t * p1)
00196 {
00197     uint32_t    L  = S->fftLen;
00198     float32_t * pCol1, * pCol2, * pMid1, * pMid2;
00199     float32_t * p2 = p1 + L;
00200     const float32_t * tw = (float32_t *) S->pTwiddle;
00201     float32_t t1[4], t2[4], t3[4], t4[4], twR, twI;
00202     float32_t m0, m1, m2, m3;
00203     uint32_t l;
00204 
00205     pCol1 = p1;
00206     pCol2 = p2;
00207 
00208     //    Define new length
00209     L >>= 1;
00210     //    Initialize mid pointers
00211     pMid1 = p1 + L;
00212     pMid2 = p2 + L;
00213 
00214     // do two dot Fourier transform
00215     for ( l = L >> 2; l > 0; l-- )
00216     {
00217         t1[0] = p1[0];
00218         t1[1] = p1[1];
00219         t1[2] = p1[2];
00220         t1[3] = p1[3];
00221 
00222         t2[0] = p2[0];
00223         t2[1] = p2[1];
00224         t2[2] = p2[2];
00225         t2[3] = p2[3];
00226 
00227         t3[0] = pMid1[0];
00228         t3[1] = pMid1[1];
00229         t3[2] = pMid1[2];
00230         t3[3] = pMid1[3];
00231 
00232         t4[0] = pMid2[0];
00233         t4[1] = pMid2[1];
00234         t4[2] = pMid2[2];
00235         t4[3] = pMid2[3];
00236 
00237         *p1++ = t1[0] + t2[0];
00238         *p1++ = t1[1] + t2[1];
00239         *p1++ = t1[2] + t2[2];
00240         *p1++ = t1[3] + t2[3];    // col 1
00241 
00242         t2[0] = t1[0] - t2[0];
00243         t2[1] = t1[1] - t2[1];
00244         t2[2] = t1[2] - t2[2];
00245         t2[3] = t1[3] - t2[3];    // for col 2
00246 
00247         *pMid1++ = t3[0] + t4[0];
00248         *pMid1++ = t3[1] + t4[1];
00249         *pMid1++ = t3[2] + t4[2];
00250         *pMid1++ = t3[3] + t4[3]; // col 1
00251 
00252         t4[0] = t4[0] - t3[0];
00253         t4[1] = t4[1] - t3[1];
00254         t4[2] = t4[2] - t3[2];
00255         t4[3] = t4[3] - t3[3];    // for col 2
00256 
00257         twR = *tw++;
00258         twI = *tw++;
00259 
00260         // multiply by twiddle factors
00261         m0 = t2[0] * twR;
00262         m1 = t2[1] * twI;
00263         m2 = t2[1] * twR;
00264         m3 = t2[0] * twI;
00265 
00266         // R  =  R  *  Tr - I * Ti
00267         *p2++ = m0 + m1;
00268         // I  =  I  *  Tr + R * Ti
00269         *p2++ = m2 - m3;
00270 
00271         // use vertical symmetry
00272         //  0.9988 - 0.0491i <==> -0.0491 - 0.9988i
00273         m0 = t4[0] * twI;
00274         m1 = t4[1] * twR;
00275         m2 = t4[1] * twI;
00276         m3 = t4[0] * twR;
00277 
00278         *pMid2++ = m0 - m1;
00279         *pMid2++ = m2 + m3;
00280 
00281         twR = *tw++;
00282         twI = *tw++;
00283 
00284         m0 = t2[2] * twR;
00285         m1 = t2[3] * twI;
00286         m2 = t2[3] * twR;
00287         m3 = t2[2] * twI;
00288 
00289         *p2++ = m0 + m1;
00290         *p2++ = m2 - m3;
00291 
00292         m0 = t4[2] * twI;
00293         m1 = t4[3] * twR;
00294         m2 = t4[3] * twI;
00295         m3 = t4[2] * twR;
00296 
00297         *pMid2++ = m0 - m1;
00298         *pMid2++ = m2 + m3;
00299     }
00300 
00301     // first col
00302     arm_radix8_butterfly_f32( pCol1, L, (float32_t *) S->pTwiddle, 2U);
00303     // second col
00304     arm_radix8_butterfly_f32( pCol2, L, (float32_t *) S->pTwiddle, 2U);
00305 }
00306 
00307 void arm_cfft_radix8by4_f32( arm_cfft_instance_f32 * S, float32_t * p1)
00308 {
00309     uint32_t    L  = S->fftLen >> 1;
00310     float32_t * pCol1, *pCol2, *pCol3, *pCol4, *pEnd1, *pEnd2, *pEnd3, *pEnd4;
00311     const float32_t *tw2, *tw3, *tw4;
00312     float32_t * p2 = p1 + L;
00313     float32_t * p3 = p2 + L;
00314     float32_t * p4 = p3 + L;
00315     float32_t t2[4], t3[4], t4[4], twR, twI;
00316     float32_t p1ap3_0, p1sp3_0, p1ap3_1, p1sp3_1;
00317     float32_t m0, m1, m2, m3;
00318     uint32_t l, twMod2, twMod3, twMod4;
00319 
00320     pCol1 = p1;         // points to real values by default
00321     pCol2 = p2;
00322     pCol3 = p3;
00323     pCol4 = p4;
00324     pEnd1 = p2 - 1;     // points to imaginary values by default
00325     pEnd2 = p3 - 1;
00326     pEnd3 = p4 - 1;
00327     pEnd4 = pEnd3 + L;
00328 
00329     tw2 = tw3 = tw4 = (float32_t *) S->pTwiddle;
00330 
00331     L >>= 1;
00332 
00333     // do four dot Fourier transform
00334 
00335     twMod2 = 2;
00336     twMod3 = 4;
00337     twMod4 = 6;
00338 
00339     // TOP
00340     p1ap3_0 = p1[0] + p3[0];
00341     p1sp3_0 = p1[0] - p3[0];
00342     p1ap3_1 = p1[1] + p3[1];
00343     p1sp3_1 = p1[1] - p3[1];
00344 
00345     // col 2
00346     t2[0] = p1sp3_0 + p2[1] - p4[1];
00347     t2[1] = p1sp3_1 - p2[0] + p4[0];
00348     // col 3
00349     t3[0] = p1ap3_0 - p2[0] - p4[0];
00350     t3[1] = p1ap3_1 - p2[1] - p4[1];
00351     // col 4
00352     t4[0] = p1sp3_0 - p2[1] + p4[1];
00353     t4[1] = p1sp3_1 + p2[0] - p4[0];
00354     // col 1
00355     *p1++ = p1ap3_0 + p2[0] + p4[0];
00356     *p1++ = p1ap3_1 + p2[1] + p4[1];
00357 
00358     // Twiddle factors are ones
00359     *p2++ = t2[0];
00360     *p2++ = t2[1];
00361     *p3++ = t3[0];
00362     *p3++ = t3[1];
00363     *p4++ = t4[0];
00364     *p4++ = t4[1];
00365 
00366     tw2 += twMod2;
00367     tw3 += twMod3;
00368     tw4 += twMod4;
00369 
00370     for (l = (L - 2) >> 1; l > 0; l-- )
00371     {
00372         // TOP
00373         p1ap3_0 = p1[0] + p3[0];
00374         p1sp3_0 = p1[0] - p3[0];
00375         p1ap3_1 = p1[1] + p3[1];
00376         p1sp3_1 = p1[1] - p3[1];
00377         // col 2
00378         t2[0] = p1sp3_0 + p2[1] - p4[1];
00379         t2[1] = p1sp3_1 - p2[0] + p4[0];
00380         // col 3
00381         t3[0] = p1ap3_0 - p2[0] - p4[0];
00382         t3[1] = p1ap3_1 - p2[1] - p4[1];
00383         // col 4
00384         t4[0] = p1sp3_0 - p2[1] + p4[1];
00385         t4[1] = p1sp3_1 + p2[0] - p4[0];
00386         // col 1 - top
00387         *p1++ = p1ap3_0 + p2[0] + p4[0];
00388         *p1++ = p1ap3_1 + p2[1] + p4[1];
00389 
00390         // BOTTOM
00391         p1ap3_1 = pEnd1[-1] + pEnd3[-1];
00392         p1sp3_1 = pEnd1[-1] - pEnd3[-1];
00393         p1ap3_0 = pEnd1[0] + pEnd3[0];
00394         p1sp3_0 = pEnd1[0] - pEnd3[0];
00395         // col 2
00396         t2[2] = pEnd2[0]  - pEnd4[0] + p1sp3_1;
00397         t2[3] = pEnd1[0] - pEnd3[0] - pEnd2[-1] + pEnd4[-1];
00398         // col 3
00399         t3[2] = p1ap3_1 - pEnd2[-1] - pEnd4[-1];
00400         t3[3] = p1ap3_0 - pEnd2[0]  - pEnd4[0];
00401         // col 4
00402         t4[2] = pEnd2[0]  - pEnd4[0]  - p1sp3_1;
00403         t4[3] = pEnd4[-1] - pEnd2[-1] - p1sp3_0;
00404         // col 1 - Bottom
00405         *pEnd1-- = p1ap3_0 + pEnd2[0] + pEnd4[0];
00406         *pEnd1-- = p1ap3_1 + pEnd2[-1] + pEnd4[-1];
00407 
00408         // COL 2
00409         // read twiddle factors
00410         twR = *tw2++;
00411         twI = *tw2++;
00412         // multiply by twiddle factors
00413         //  let    Z1 = a + i(b),   Z2 = c + i(d)
00414         //   =>  Z1 * Z2  =  (a*c - b*d) + i(b*c + a*d)
00415 
00416         // Top
00417         m0 = t2[0] * twR;
00418         m1 = t2[1] * twI;
00419         m2 = t2[1] * twR;
00420         m3 = t2[0] * twI;
00421 
00422         *p2++ = m0 + m1;
00423         *p2++ = m2 - m3;
00424         // use vertical symmetry col 2
00425         // 0.9997 - 0.0245i  <==>  0.0245 - 0.9997i
00426         // Bottom
00427         m0 = t2[3] * twI;
00428         m1 = t2[2] * twR;
00429         m2 = t2[2] * twI;
00430         m3 = t2[3] * twR;
00431 
00432         *pEnd2-- = m0 - m1;
00433         *pEnd2-- = m2 + m3;
00434 
00435         // COL 3
00436         twR = tw3[0];
00437         twI = tw3[1];
00438         tw3 += twMod3;
00439         // Top
00440         m0 = t3[0] * twR;
00441         m1 = t3[1] * twI;
00442         m2 = t3[1] * twR;
00443         m3 = t3[0] * twI;
00444 
00445         *p3++ = m0 + m1;
00446         *p3++ = m2 - m3;
00447         // use vertical symmetry col 3
00448         // 0.9988 - 0.0491i  <==>  -0.9988 - 0.0491i
00449         // Bottom
00450         m0 = -t3[3] * twR;
00451         m1 = t3[2] * twI;
00452         m2 = t3[2] * twR;
00453         m3 = t3[3] * twI;
00454 
00455         *pEnd3-- = m0 - m1;
00456         *pEnd3-- = m3 - m2;
00457 
00458         // COL 4
00459         twR = tw4[0];
00460         twI = tw4[1];
00461         tw4 += twMod4;
00462         // Top
00463         m0 = t4[0] * twR;
00464         m1 = t4[1] * twI;
00465         m2 = t4[1] * twR;
00466         m3 = t4[0] * twI;
00467 
00468         *p4++ = m0 + m1;
00469         *p4++ = m2 - m3;
00470         // use vertical symmetry col 4
00471         // 0.9973 - 0.0736i  <==>  -0.0736 + 0.9973i
00472         // Bottom
00473         m0 = t4[3] * twI;
00474         m1 = t4[2] * twR;
00475         m2 = t4[2] * twI;
00476         m3 = t4[3] * twR;
00477 
00478         *pEnd4-- = m0 - m1;
00479         *pEnd4-- = m2 + m3;
00480     }
00481 
00482     //MIDDLE
00483     // Twiddle factors are
00484     //  1.0000  0.7071-0.7071i  -1.0000i  -0.7071-0.7071i
00485     p1ap3_0 = p1[0] + p3[0];
00486     p1sp3_0 = p1[0] - p3[0];
00487     p1ap3_1 = p1[1] + p3[1];
00488     p1sp3_1 = p1[1] - p3[1];
00489 
00490     // col 2
00491     t2[0] = p1sp3_0 + p2[1] - p4[1];
00492     t2[1] = p1sp3_1 - p2[0] + p4[0];
00493     // col 3
00494     t3[0] = p1ap3_0 - p2[0] - p4[0];
00495     t3[1] = p1ap3_1 - p2[1] - p4[1];
00496     // col 4
00497     t4[0] = p1sp3_0 - p2[1] + p4[1];
00498     t4[1] = p1sp3_1 + p2[0] - p4[0];
00499     // col 1 - Top
00500     *p1++ = p1ap3_0 + p2[0] + p4[0];
00501     *p1++ = p1ap3_1 + p2[1] + p4[1];
00502 
00503     // COL 2
00504     twR = tw2[0];
00505     twI = tw2[1];
00506 
00507     m0 = t2[0] * twR;
00508     m1 = t2[1] * twI;
00509     m2 = t2[1] * twR;
00510     m3 = t2[0] * twI;
00511 
00512     *p2++ = m0 + m1;
00513     *p2++ = m2 - m3;
00514     // COL 3
00515     twR = tw3[0];
00516     twI = tw3[1];
00517 
00518     m0 = t3[0] * twR;
00519     m1 = t3[1] * twI;
00520     m2 = t3[1] * twR;
00521     m3 = t3[0] * twI;
00522 
00523     *p3++ = m0 + m1;
00524     *p3++ = m2 - m3;
00525     // COL 4
00526     twR = tw4[0];
00527     twI = tw4[1];
00528 
00529     m0 = t4[0] * twR;
00530     m1 = t4[1] * twI;
00531     m2 = t4[1] * twR;
00532     m3 = t4[0] * twI;
00533 
00534     *p4++ = m0 + m1;
00535     *p4++ = m2 - m3;
00536 
00537     // first col
00538     arm_radix8_butterfly_f32( pCol1, L, (float32_t *) S->pTwiddle, 4U);
00539     // second col
00540     arm_radix8_butterfly_f32( pCol2, L, (float32_t *) S->pTwiddle, 4U);
00541     // third col
00542     arm_radix8_butterfly_f32( pCol3, L, (float32_t *) S->pTwiddle, 4U);
00543     // fourth col
00544     arm_radix8_butterfly_f32( pCol4, L, (float32_t *) S->pTwiddle, 4U);
00545 }
00546 
00547 /**
00548 * @addtogroup ComplexFFT
00549 * @{
00550 */
00551 
00552 /**
00553 * @details
00554 * @brief       Processing function for the floating-point complex FFT.
00555 * @param[in]      *S    points to an instance of the floating-point CFFT structure.
00556 * @param[in, out] *p1   points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
00557 * @param[in]     ifftFlag       flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
00558 * @param[in]     bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
00559 * @return none.
00560 */
00561 
00562 void arm_cfft_f32(
00563     const arm_cfft_instance_f32 * S,
00564     float32_t * p1,
00565     uint8_t ifftFlag,
00566     uint8_t bitReverseFlag)
00567 {
00568     uint32_t  L = S->fftLen, l;
00569     float32_t invL, * pSrc;
00570 
00571     if (ifftFlag == 1U)
00572     {
00573         /*  Conjugate input data  */
00574         pSrc = p1 + 1;
00575         for(l=0; l<L; l++)
00576         {
00577             *pSrc = -*pSrc;
00578             pSrc += 2;
00579         }
00580     }
00581 
00582     switch (L)
00583     {
00584     case 16:
00585     case 128:
00586     case 1024:
00587         arm_cfft_radix8by2_f32  ( (arm_cfft_instance_f32 *) S, p1);
00588         break;
00589     case 32:
00590     case 256:
00591     case 2048:
00592         arm_cfft_radix8by4_f32  ( (arm_cfft_instance_f32 *) S, p1);
00593         break;
00594     case 64:
00595     case 512:
00596     case 4096:
00597         arm_radix8_butterfly_f32( p1, L, (float32_t *) S->pTwiddle, 1);
00598         break;
00599     }
00600 
00601     if ( bitReverseFlag )
00602         arm_bitreversal_32((uint32_t*)p1,S->bitRevLength,S->pBitRevTable);
00603 
00604     if (ifftFlag == 1U)
00605     {
00606         invL = 1.0f/(float32_t)L;
00607         /*  Conjugate and scale output data */
00608         pSrc = p1;
00609         for(l=0; l<L; l++)
00610         {
00611             *pSrc++ *=   invL ;
00612             *pSrc  = -(*pSrc) * invL;
00613             pSrc++;
00614         }
00615     }
00616 }
00617 
00618 /**
00619 * @} end of ComplexFFT group
00620 */
00621