Ura

Dependencies:   CMSIS_DSP_401 mbed

Committer:
Sergeev
Date:
Sat Nov 29 16:36:16 2014 +0000
Revision:
9:748d94f021f6
Parent:
3:1f56b8f439a1
??????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergeev 1:9b1df0b2507d 1 /* ----------------------------------------------------------------------
Sergeev 1:9b1df0b2507d 2 * Copyright (C) 2010-2013 ARM Limited. All rights reserved.
Sergeev 1:9b1df0b2507d 3 *
Sergeev 1:9b1df0b2507d 4 * $Date: 17. January 2013
Sergeev 1:9b1df0b2507d 5 * $Revision: V1.4.1
Sergeev 1:9b1df0b2507d 6 *
Sergeev 1:9b1df0b2507d 7 * Project: CMSIS DSP Library
Sergeev 1:9b1df0b2507d 8 * Title: arm_cfft_f32.c
Sergeev 1:9b1df0b2507d 9 *
Sergeev 1:9b1df0b2507d 10 * Description: Combined Radix Decimation in Frequency CFFT Floating point processing function
Sergeev 1:9b1df0b2507d 11 *
Sergeev 1:9b1df0b2507d 12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
Sergeev 1:9b1df0b2507d 13 *
Sergeev 1:9b1df0b2507d 14 * Redistribution and use in source and binary forms, with or without
Sergeev 1:9b1df0b2507d 15 * modification, are permitted provided that the following conditions
Sergeev 1:9b1df0b2507d 16 * are met:
Sergeev 1:9b1df0b2507d 17 * - Redistributions of source code must retain the above copyright
Sergeev 1:9b1df0b2507d 18 * notice, this list of conditions and the following disclaimer.
Sergeev 1:9b1df0b2507d 19 * - Redistributions in binary form must reproduce the above copyright
Sergeev 1:9b1df0b2507d 20 * notice, this list of conditions and the following disclaimer in
Sergeev 1:9b1df0b2507d 21 * the documentation and/or other materials provided with the
Sergeev 1:9b1df0b2507d 22 * distribution.
Sergeev 1:9b1df0b2507d 23 * - Neither the name of ARM LIMITED nor the names of its contributors
Sergeev 1:9b1df0b2507d 24 * may be used to endorse or promote products derived from this
Sergeev 1:9b1df0b2507d 25 * software without specific prior written permission.
Sergeev 1:9b1df0b2507d 26 *
Sergeev 1:9b1df0b2507d 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Sergeev 1:9b1df0b2507d 28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Sergeev 1:9b1df0b2507d 29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
Sergeev 1:9b1df0b2507d 30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
Sergeev 1:9b1df0b2507d 31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
Sergeev 1:9b1df0b2507d 32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
Sergeev 1:9b1df0b2507d 33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Sergeev 1:9b1df0b2507d 34 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Sergeev 1:9b1df0b2507d 35 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Sergeev 1:9b1df0b2507d 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
Sergeev 1:9b1df0b2507d 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Sergeev 1:9b1df0b2507d 38 * POSSIBILITY OF SUCH DAMAGE.
Sergeev 1:9b1df0b2507d 39 * -------------------------------------------------------------------- */
Sergeev 1:9b1df0b2507d 40
Sergeev 1:9b1df0b2507d 41
Sergeev 1:9b1df0b2507d 42 #include "arm_math.h"
Sergeev 1:9b1df0b2507d 43 #include "arm_common_tables.h"
Sergeev 1:9b1df0b2507d 44
Sergeev 1:9b1df0b2507d 45 extern void arm_radix8_butterfly_f32(
Sergeev 1:9b1df0b2507d 46 float32_t * pSrc,
Sergeev 1:9b1df0b2507d 47 uint16_t fftLen,
Sergeev 1:9b1df0b2507d 48 const float32_t * pCoef,
Sergeev 1:9b1df0b2507d 49 uint16_t twidCoefModifier);
Sergeev 1:9b1df0b2507d 50
Sergeev 1:9b1df0b2507d 51
Sergeev 1:9b1df0b2507d 52 void arm_bitreversal_32(
Sergeev 1:9b1df0b2507d 53 uint32_t * pSrc,
Sergeev 1:9b1df0b2507d 54 const uint16_t bitRevLen,
Sergeev 1:9b1df0b2507d 55 const uint16_t * pBitRevTable){
Sergeev 1:9b1df0b2507d 56 float32_t pSrc1[1024];
Sergeev 1:9b1df0b2507d 57 for (int i =0; i<bitRevLen; i++)
Sergeev 1:9b1df0b2507d 58 {
Sergeev 3:1f56b8f439a1 59 pSrc1[i]=(float32_t)pSrc[i]/4095;
Sergeev 1:9b1df0b2507d 60 }
Sergeev 1:9b1df0b2507d 61 arm_bitreversal_f32(pSrc1, bitRevLen, 1, pBitRevTable);
Sergeev 1:9b1df0b2507d 62 }
Sergeev 1:9b1df0b2507d 63
Sergeev 1:9b1df0b2507d 64 /**
Sergeev 1:9b1df0b2507d 65 * @ingroup groupTransforms
Sergeev 1:9b1df0b2507d 66 */
Sergeev 1:9b1df0b2507d 67
Sergeev 1:9b1df0b2507d 68 /**
Sergeev 1:9b1df0b2507d 69 * @defgroup ComplexFFT Complex FFT Functions
Sergeev 1:9b1df0b2507d 70 *
Sergeev 1:9b1df0b2507d 71 * \par
Sergeev 1:9b1df0b2507d 72 * The Fast Fourier Transform (FFT) is an efficient algorithm for computing the
Sergeev 1:9b1df0b2507d 73 * Discrete Fourier Transform (DFT). The FFT can be orders of magnitude faster
Sergeev 1:9b1df0b2507d 74 * than the DFT, especially for long lengths.
Sergeev 1:9b1df0b2507d 75 * The algorithms described in this section
Sergeev 1:9b1df0b2507d 76 * operate on complex data. A separate set of functions is devoted to handling
Sergeev 1:9b1df0b2507d 77 * of real sequences.
Sergeev 1:9b1df0b2507d 78 * \par
Sergeev 1:9b1df0b2507d 79 * There are separate algorithms for handling floating-point, Q15, and Q31 data
Sergeev 1:9b1df0b2507d 80 * types. The algorithms available for each data type are described next.
Sergeev 1:9b1df0b2507d 81 * \par
Sergeev 1:9b1df0b2507d 82 * The FFT functions operate in-place. That is, the array holding the input data
Sergeev 1:9b1df0b2507d 83 * will also be used to hold the corresponding result. The input data is complex
Sergeev 1:9b1df0b2507d 84 * and contains <code>2*fftLen</code> interleaved values as shown below.
Sergeev 1:9b1df0b2507d 85 * <pre> {real[0], imag[0], real[1], imag[1],..} </pre>
Sergeev 1:9b1df0b2507d 86 * The FFT result will be contained in the same array and the frequency domain
Sergeev 1:9b1df0b2507d 87 * values will have the same interleaving.
Sergeev 1:9b1df0b2507d 88 *
Sergeev 1:9b1df0b2507d 89 * \par Floating-point
Sergeev 1:9b1df0b2507d 90 * The floating-point complex FFT uses a mixed-radix algorithm. Multiple radix-8
Sergeev 1:9b1df0b2507d 91 * stages are performed along with a single radix-2 or radix-4 stage, as needed.
Sergeev 1:9b1df0b2507d 92 * The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses
Sergeev 1:9b1df0b2507d 93 * a different twiddle factor table.
Sergeev 1:9b1df0b2507d 94 * \par
Sergeev 1:9b1df0b2507d 95 * The function uses the standard FFT definition and output values may grow by a
Sergeev 1:9b1df0b2507d 96 * factor of <code>fftLen</code> when computing the forward transform. The
Sergeev 1:9b1df0b2507d 97 * inverse transform includes a scale of <code>1/fftLen</code> as part of the
Sergeev 1:9b1df0b2507d 98 * calculation and this matches the textbook definition of the inverse FFT.
Sergeev 1:9b1df0b2507d 99 * \par
Sergeev 1:9b1df0b2507d 100 * Preinitialized data structures containing twiddle factors and bit reversal
Sergeev 1:9b1df0b2507d 101 * tables are provided and defined in <code>arm_const_structs.h</code>. Include
Sergeev 1:9b1df0b2507d 102 * this header in your function and then pass one of the constant structures as
Sergeev 1:9b1df0b2507d 103 * an argument to arm_cfft_f32. For example:
Sergeev 1:9b1df0b2507d 104 * \par
Sergeev 1:9b1df0b2507d 105 * <code>arm_cfft_f32(arm_cfft_sR_f32_len64, pSrc, 1, 1)</code>
Sergeev 1:9b1df0b2507d 106 * \par
Sergeev 1:9b1df0b2507d 107 * computes a 64-point inverse complex FFT including bit reversal.
Sergeev 1:9b1df0b2507d 108 * The data structures are treated as constant data and not modified during the
Sergeev 1:9b1df0b2507d 109 * calculation. The same data structure can be reused for multiple transforms
Sergeev 1:9b1df0b2507d 110 * including mixing forward and inverse transforms.
Sergeev 1:9b1df0b2507d 111 * \par
Sergeev 1:9b1df0b2507d 112 * Earlier releases of the library provided separate radix-2 and radix-4
Sergeev 1:9b1df0b2507d 113 * algorithms that operated on floating-point data. These functions are still
Sergeev 1:9b1df0b2507d 114 * provided but are deprecated. The older functions are slower and less general
Sergeev 1:9b1df0b2507d 115 * than the new functions.
Sergeev 1:9b1df0b2507d 116 * \par
Sergeev 1:9b1df0b2507d 117 * An example of initialization of the constants for the arm_cfft_f32 function follows:
Sergeev 1:9b1df0b2507d 118 * \par
Sergeev 1:9b1df0b2507d 119 * const static arm_cfft_instance_f32 *S;
Sergeev 1:9b1df0b2507d 120 * ...
Sergeev 1:9b1df0b2507d 121 * switch (length) {
Sergeev 1:9b1df0b2507d 122 * case 16:
Sergeev 1:9b1df0b2507d 123 * S = & arm_cfft_sR_f32_len16;
Sergeev 1:9b1df0b2507d 124 * break;
Sergeev 1:9b1df0b2507d 125 * case 32:
Sergeev 1:9b1df0b2507d 126 * S = & arm_cfft_sR_f32_len32;
Sergeev 1:9b1df0b2507d 127 * break;
Sergeev 1:9b1df0b2507d 128 * case 64:
Sergeev 1:9b1df0b2507d 129 * S = & arm_cfft_sR_f32_len64;
Sergeev 1:9b1df0b2507d 130 * break;
Sergeev 1:9b1df0b2507d 131 * case 128:
Sergeev 1:9b1df0b2507d 132 * S = & arm_cfft_sR_f32_len128;
Sergeev 1:9b1df0b2507d 133 * break;
Sergeev 1:9b1df0b2507d 134 * case 256:
Sergeev 1:9b1df0b2507d 135 * S = & arm_cfft_sR_f32_len256;
Sergeev 1:9b1df0b2507d 136 * break;
Sergeev 1:9b1df0b2507d 137 * case 512:
Sergeev 1:9b1df0b2507d 138 * S = & arm_cfft_sR_f32_len512;
Sergeev 1:9b1df0b2507d 139 * break;
Sergeev 1:9b1df0b2507d 140 * case 1024:
Sergeev 1:9b1df0b2507d 141 * S = & arm_cfft_sR_f32_len1024;
Sergeev 1:9b1df0b2507d 142 * break;
Sergeev 1:9b1df0b2507d 143 * case 2048:
Sergeev 1:9b1df0b2507d 144 * S = & arm_cfft_sR_f32_len2048;
Sergeev 1:9b1df0b2507d 145 * break;
Sergeev 1:9b1df0b2507d 146 * case 4096:
Sergeev 1:9b1df0b2507d 147 * S = & arm_cfft_sR_f32_len4096;
Sergeev 1:9b1df0b2507d 148 * break;
Sergeev 1:9b1df0b2507d 149 * }
Sergeev 1:9b1df0b2507d 150 * \par Q15 and Q31
Sergeev 1:9b1df0b2507d 151 * The library provides radix-2 and radix-4 FFT algorithms for fixed-point data. The
Sergeev 1:9b1df0b2507d 152 * radix-2 algorithm supports lengths of [16, 32, 64, ..., 4096]. The radix-4
Sergeev 1:9b1df0b2507d 153 * algorithm supports lengths of [16, 64, 256, ..., 4096]. When possible, you
Sergeev 1:9b1df0b2507d 154 * should use the radix-4 algorithm since it is faster than the radix-2 of the
Sergeev 1:9b1df0b2507d 155 * same length.
Sergeev 1:9b1df0b2507d 156 * \par
Sergeev 1:9b1df0b2507d 157 * The forward FFTs include scaling in order to prevent results from overflowing.
Sergeev 1:9b1df0b2507d 158 * Intermediate results are scaled down during each butterfly stage. In the
Sergeev 1:9b1df0b2507d 159 * radix-2 algorithm, a scale of 0.5 is applied during each butterfly. In the
Sergeev 1:9b1df0b2507d 160 * radix-4 algorithm, a scale of 0.25 is applied. The scaling applies to both
Sergeev 1:9b1df0b2507d 161 * the forward and the inverse FFTs. Thus the forward FFT contains an additional
Sergeev 1:9b1df0b2507d 162 * scale factor of <code>1/fftLen</code> as compared to the standard textbook
Sergeev 1:9b1df0b2507d 163 * definition of the FFT. The inverse FFT also scales down during each butterfly
Sergeev 1:9b1df0b2507d 164 * stage and this corresponds to the standard textbook definition.
Sergeev 1:9b1df0b2507d 165 * \par
Sergeev 1:9b1df0b2507d 166 * A separate instance structure must be defined for each transform used but
Sergeev 1:9b1df0b2507d 167 * twiddle factor and bit reversal tables can be reused.
Sergeev 1:9b1df0b2507d 168 * \par
Sergeev 1:9b1df0b2507d 169 * There is also an associated initialization function for each data type.
Sergeev 1:9b1df0b2507d 170 * The initialization function performs the following operations:
Sergeev 1:9b1df0b2507d 171 * - Sets the values of the internal structure fields.
Sergeev 1:9b1df0b2507d 172 * - Initializes twiddle factor table and bit reversal table pointers.
Sergeev 1:9b1df0b2507d 173 * \par
Sergeev 1:9b1df0b2507d 174 * Use of the initialization function is optional.
Sergeev 1:9b1df0b2507d 175 * However, if the initialization function is used, then the instance structure
Sergeev 1:9b1df0b2507d 176 * cannot be placed into a const data section. To place an instance structure
Sergeev 1:9b1df0b2507d 177 * into a const data section, the instance structure should be manually
Sergeev 1:9b1df0b2507d 178 * initialized as follows:
Sergeev 1:9b1df0b2507d 179 * <pre>
Sergeev 1:9b1df0b2507d 180 *arm_cfft_radix2_instance_q31 S = {fftLen, ifftFlag, bitReverseFlag, pTwiddle, pBitRevTable, twidCoefModifier, bitRevFactor};
Sergeev 1:9b1df0b2507d 181 *arm_cfft_radix2_instance_q15 S = {fftLen, ifftFlag, bitReverseFlag, pTwiddle, pBitRevTable, twidCoefModifier, bitRevFactor};
Sergeev 1:9b1df0b2507d 182 *arm_cfft_radix4_instance_q31 S = {fftLen, ifftFlag, bitReverseFlag, pTwiddle, pBitRevTable, twidCoefModifier, bitRevFactor};
Sergeev 1:9b1df0b2507d 183 *arm_cfft_radix4_instance_q15 S = {fftLen, ifftFlag, bitReverseFlag, pTwiddle, pBitRevTable, twidCoefModifier, bitRevFactor};
Sergeev 1:9b1df0b2507d 184 *arm_cfft_instance_f32 S = {fftLen, pTwiddle, pBitRevTable, bitRevLength};
Sergeev 1:9b1df0b2507d 185 * </pre>
Sergeev 1:9b1df0b2507d 186 * \par
Sergeev 1:9b1df0b2507d 187 * where <code>fftLen</code> length of CFFT/CIFFT; <code>ifftFlag</code> Flag for
Sergeev 1:9b1df0b2507d 188 * selection of forward or inverse transform. When ifftFlag is set the inverse
Sergeev 1:9b1df0b2507d 189 * transform is calculated.
Sergeev 1:9b1df0b2507d 190 * <code>bitReverseFlag</code> Flag for selection of output order (Set bitReverseFlag to output in normal order otherwise output in bit reversed order);
Sergeev 1:9b1df0b2507d 191 * <code>pTwiddle</code>points to array of twiddle coefficients; <code>pBitRevTable</code> points to the bit reversal table.
Sergeev 1:9b1df0b2507d 192 * <code>twidCoefModifier</code> modifier for twiddle factor table which supports all FFT lengths with same table;
Sergeev 1:9b1df0b2507d 193 * <code>pBitRevTable</code> modifier for bit reversal table which supports all FFT lengths with same table.
Sergeev 1:9b1df0b2507d 194 * <code>onebyfftLen</code> value of 1/fftLen to calculate CIFFT;
Sergeev 1:9b1df0b2507d 195 * \par
Sergeev 1:9b1df0b2507d 196 * The Q15 and Q31 FFT functions use a large bit reversal and twiddle factor
Sergeev 1:9b1df0b2507d 197 * table. The tables are defined for the maximum length transform and a subset
Sergeev 1:9b1df0b2507d 198 * of the coefficients are used in shorter transforms.
Sergeev 1:9b1df0b2507d 199 *
Sergeev 1:9b1df0b2507d 200 */
Sergeev 1:9b1df0b2507d 201
Sergeev 1:9b1df0b2507d 202 void arm_cfft_radix8by2_f32( arm_cfft_instance_f32 * S, float32_t * p1)
Sergeev 1:9b1df0b2507d 203 {
Sergeev 1:9b1df0b2507d 204 uint32_t L = S->fftLen;
Sergeev 1:9b1df0b2507d 205 float32_t * pCol1, * pCol2, * pMid1, * pMid2;
Sergeev 1:9b1df0b2507d 206 float32_t * p2 = p1 + L;
Sergeev 1:9b1df0b2507d 207 const float32_t * tw = (float32_t *) S->pTwiddle;
Sergeev 1:9b1df0b2507d 208 float32_t t1[4], t2[4], t3[4], t4[4], twR, twI;
Sergeev 1:9b1df0b2507d 209 float32_t m0, m1, m2, m3;
Sergeev 1:9b1df0b2507d 210 uint32_t l;
Sergeev 1:9b1df0b2507d 211
Sergeev 1:9b1df0b2507d 212 pCol1 = p1;
Sergeev 1:9b1df0b2507d 213 pCol2 = p2;
Sergeev 1:9b1df0b2507d 214
Sergeev 1:9b1df0b2507d 215 // Define new length
Sergeev 1:9b1df0b2507d 216 L >>= 1;
Sergeev 1:9b1df0b2507d 217 // Initialize mid pointers
Sergeev 1:9b1df0b2507d 218 pMid1 = p1 + L;
Sergeev 1:9b1df0b2507d 219 pMid2 = p2 + L;
Sergeev 1:9b1df0b2507d 220
Sergeev 1:9b1df0b2507d 221 // do two dot Fourier transform
Sergeev 1:9b1df0b2507d 222 for ( l = L >> 2; l > 0; l-- )
Sergeev 1:9b1df0b2507d 223 {
Sergeev 1:9b1df0b2507d 224 t1[0] = p1[0];
Sergeev 1:9b1df0b2507d 225 t1[1] = p1[1];
Sergeev 1:9b1df0b2507d 226 t1[2] = p1[2];
Sergeev 1:9b1df0b2507d 227 t1[3] = p1[3];
Sergeev 1:9b1df0b2507d 228
Sergeev 1:9b1df0b2507d 229 t2[0] = p2[0];
Sergeev 1:9b1df0b2507d 230 t2[1] = p2[1];
Sergeev 1:9b1df0b2507d 231 t2[2] = p2[2];
Sergeev 1:9b1df0b2507d 232 t2[3] = p2[3];
Sergeev 1:9b1df0b2507d 233
Sergeev 1:9b1df0b2507d 234 t3[0] = pMid1[0];
Sergeev 1:9b1df0b2507d 235 t3[1] = pMid1[1];
Sergeev 1:9b1df0b2507d 236 t3[2] = pMid1[2];
Sergeev 1:9b1df0b2507d 237 t3[3] = pMid1[3];
Sergeev 1:9b1df0b2507d 238
Sergeev 1:9b1df0b2507d 239 t4[0] = pMid2[0];
Sergeev 1:9b1df0b2507d 240 t4[1] = pMid2[1];
Sergeev 1:9b1df0b2507d 241 t4[2] = pMid2[2];
Sergeev 1:9b1df0b2507d 242 t4[3] = pMid2[3];
Sergeev 1:9b1df0b2507d 243
Sergeev 1:9b1df0b2507d 244 *p1++ = t1[0] + t2[0];
Sergeev 1:9b1df0b2507d 245 *p1++ = t1[1] + t2[1];
Sergeev 1:9b1df0b2507d 246 *p1++ = t1[2] + t2[2];
Sergeev 1:9b1df0b2507d 247 *p1++ = t1[3] + t2[3]; // col 1
Sergeev 1:9b1df0b2507d 248
Sergeev 1:9b1df0b2507d 249 t2[0] = t1[0] - t2[0];
Sergeev 1:9b1df0b2507d 250 t2[1] = t1[1] - t2[1];
Sergeev 1:9b1df0b2507d 251 t2[2] = t1[2] - t2[2];
Sergeev 1:9b1df0b2507d 252 t2[3] = t1[3] - t2[3]; // for col 2
Sergeev 1:9b1df0b2507d 253
Sergeev 1:9b1df0b2507d 254 *pMid1++ = t3[0] + t4[0];
Sergeev 1:9b1df0b2507d 255 *pMid1++ = t3[1] + t4[1];
Sergeev 1:9b1df0b2507d 256 *pMid1++ = t3[2] + t4[2];
Sergeev 1:9b1df0b2507d 257 *pMid1++ = t3[3] + t4[3]; // col 1
Sergeev 1:9b1df0b2507d 258
Sergeev 1:9b1df0b2507d 259 t4[0] = t4[0] - t3[0];
Sergeev 1:9b1df0b2507d 260 t4[1] = t4[1] - t3[1];
Sergeev 1:9b1df0b2507d 261 t4[2] = t4[2] - t3[2];
Sergeev 1:9b1df0b2507d 262 t4[3] = t4[3] - t3[3]; // for col 2
Sergeev 1:9b1df0b2507d 263
Sergeev 1:9b1df0b2507d 264 twR = *tw++;
Sergeev 1:9b1df0b2507d 265 twI = *tw++;
Sergeev 1:9b1df0b2507d 266
Sergeev 1:9b1df0b2507d 267 // multiply by twiddle factors
Sergeev 1:9b1df0b2507d 268 m0 = t2[0] * twR;
Sergeev 1:9b1df0b2507d 269 m1 = t2[1] * twI;
Sergeev 1:9b1df0b2507d 270 m2 = t2[1] * twR;
Sergeev 1:9b1df0b2507d 271 m3 = t2[0] * twI;
Sergeev 1:9b1df0b2507d 272
Sergeev 1:9b1df0b2507d 273 // R = R * Tr - I * Ti
Sergeev 1:9b1df0b2507d 274 *p2++ = m0 + m1;
Sergeev 1:9b1df0b2507d 275 // I = I * Tr + R * Ti
Sergeev 1:9b1df0b2507d 276 *p2++ = m2 - m3;
Sergeev 1:9b1df0b2507d 277
Sergeev 1:9b1df0b2507d 278 // use vertical symmetry
Sergeev 1:9b1df0b2507d 279 // 0.9988 - 0.0491i <==> -0.0491 - 0.9988i
Sergeev 1:9b1df0b2507d 280 m0 = t4[0] * twI;
Sergeev 1:9b1df0b2507d 281 m1 = t4[1] * twR;
Sergeev 1:9b1df0b2507d 282 m2 = t4[1] * twI;
Sergeev 1:9b1df0b2507d 283 m3 = t4[0] * twR;
Sergeev 1:9b1df0b2507d 284
Sergeev 1:9b1df0b2507d 285 *pMid2++ = m0 - m1;
Sergeev 1:9b1df0b2507d 286 *pMid2++ = m2 + m3;
Sergeev 1:9b1df0b2507d 287
Sergeev 1:9b1df0b2507d 288 twR = *tw++;
Sergeev 1:9b1df0b2507d 289 twI = *tw++;
Sergeev 1:9b1df0b2507d 290
Sergeev 1:9b1df0b2507d 291 m0 = t2[2] * twR;
Sergeev 1:9b1df0b2507d 292 m1 = t2[3] * twI;
Sergeev 1:9b1df0b2507d 293 m2 = t2[3] * twR;
Sergeev 1:9b1df0b2507d 294 m3 = t2[2] * twI;
Sergeev 1:9b1df0b2507d 295
Sergeev 1:9b1df0b2507d 296 *p2++ = m0 + m1;
Sergeev 1:9b1df0b2507d 297 *p2++ = m2 - m3;
Sergeev 1:9b1df0b2507d 298
Sergeev 1:9b1df0b2507d 299 m0 = t4[2] * twI;
Sergeev 1:9b1df0b2507d 300 m1 = t4[3] * twR;
Sergeev 1:9b1df0b2507d 301 m2 = t4[3] * twI;
Sergeev 1:9b1df0b2507d 302 m3 = t4[2] * twR;
Sergeev 1:9b1df0b2507d 303
Sergeev 1:9b1df0b2507d 304 *pMid2++ = m0 - m1;
Sergeev 1:9b1df0b2507d 305 *pMid2++ = m2 + m3;
Sergeev 1:9b1df0b2507d 306 }
Sergeev 1:9b1df0b2507d 307
Sergeev 1:9b1df0b2507d 308 // first col
Sergeev 1:9b1df0b2507d 309 arm_radix8_butterfly_f32( pCol1, L, (float32_t *) S->pTwiddle, 2u);
Sergeev 1:9b1df0b2507d 310 // second col
Sergeev 1:9b1df0b2507d 311 arm_radix8_butterfly_f32( pCol2, L, (float32_t *) S->pTwiddle, 2u);
Sergeev 1:9b1df0b2507d 312
Sergeev 1:9b1df0b2507d 313 }
Sergeev 1:9b1df0b2507d 314
Sergeev 1:9b1df0b2507d 315 void arm_cfft_radix8by4_f32( arm_cfft_instance_f32 * S, float32_t * p1)
Sergeev 1:9b1df0b2507d 316 {
Sergeev 1:9b1df0b2507d 317 uint32_t L = S->fftLen >> 1;
Sergeev 1:9b1df0b2507d 318 float32_t * pCol1, *pCol2, *pCol3, *pCol4, *pEnd1, *pEnd2, *pEnd3, *pEnd4;
Sergeev 1:9b1df0b2507d 319 const float32_t *tw2, *tw3, *tw4;
Sergeev 1:9b1df0b2507d 320 float32_t * p2 = p1 + L;
Sergeev 1:9b1df0b2507d 321 float32_t * p3 = p2 + L;
Sergeev 1:9b1df0b2507d 322 float32_t * p4 = p3 + L;
Sergeev 1:9b1df0b2507d 323 float32_t t2[4], t3[4], t4[4], twR, twI;
Sergeev 1:9b1df0b2507d 324 float32_t p1ap3_0, p1sp3_0, p1ap3_1, p1sp3_1;
Sergeev 1:9b1df0b2507d 325 float32_t m0, m1, m2, m3;
Sergeev 1:9b1df0b2507d 326 uint32_t l, twMod2, twMod3, twMod4;
Sergeev 1:9b1df0b2507d 327
Sergeev 1:9b1df0b2507d 328 pCol1 = p1; // points to real values by default
Sergeev 1:9b1df0b2507d 329 pCol2 = p2;
Sergeev 1:9b1df0b2507d 330 pCol3 = p3;
Sergeev 1:9b1df0b2507d 331 pCol4 = p4;
Sergeev 1:9b1df0b2507d 332 pEnd1 = p2 - 1; // points to imaginary values by default
Sergeev 1:9b1df0b2507d 333 pEnd2 = p3 - 1;
Sergeev 1:9b1df0b2507d 334 pEnd3 = p4 - 1;
Sergeev 1:9b1df0b2507d 335 pEnd4 = pEnd3 + L;
Sergeev 1:9b1df0b2507d 336
Sergeev 1:9b1df0b2507d 337 tw2 = tw3 = tw4 = (float32_t *) S->pTwiddle;
Sergeev 1:9b1df0b2507d 338
Sergeev 1:9b1df0b2507d 339 L >>= 1;
Sergeev 1:9b1df0b2507d 340
Sergeev 1:9b1df0b2507d 341 // do four dot Fourier transform
Sergeev 1:9b1df0b2507d 342
Sergeev 1:9b1df0b2507d 343 twMod2 = 2;
Sergeev 1:9b1df0b2507d 344 twMod3 = 4;
Sergeev 1:9b1df0b2507d 345 twMod4 = 6;
Sergeev 1:9b1df0b2507d 346
Sergeev 1:9b1df0b2507d 347 // TOP
Sergeev 1:9b1df0b2507d 348 p1ap3_0 = p1[0] + p3[0];
Sergeev 1:9b1df0b2507d 349 p1sp3_0 = p1[0] - p3[0];
Sergeev 1:9b1df0b2507d 350 p1ap3_1 = p1[1] + p3[1];
Sergeev 1:9b1df0b2507d 351 p1sp3_1 = p1[1] - p3[1];
Sergeev 1:9b1df0b2507d 352
Sergeev 1:9b1df0b2507d 353 // col 2
Sergeev 1:9b1df0b2507d 354 t2[0] = p1sp3_0 + p2[1] - p4[1];
Sergeev 1:9b1df0b2507d 355 t2[1] = p1sp3_1 - p2[0] + p4[0];
Sergeev 1:9b1df0b2507d 356 // col 3
Sergeev 1:9b1df0b2507d 357 t3[0] = p1ap3_0 - p2[0] - p4[0];
Sergeev 1:9b1df0b2507d 358 t3[1] = p1ap3_1 - p2[1] - p4[1];
Sergeev 1:9b1df0b2507d 359 // col 4
Sergeev 1:9b1df0b2507d 360 t4[0] = p1sp3_0 - p2[1] + p4[1];
Sergeev 1:9b1df0b2507d 361 t4[1] = p1sp3_1 + p2[0] - p4[0];
Sergeev 1:9b1df0b2507d 362 // col 1
Sergeev 1:9b1df0b2507d 363 *p1++ = p1ap3_0 + p2[0] + p4[0];
Sergeev 1:9b1df0b2507d 364 *p1++ = p1ap3_1 + p2[1] + p4[1];
Sergeev 1:9b1df0b2507d 365
Sergeev 1:9b1df0b2507d 366 // Twiddle factors are ones
Sergeev 1:9b1df0b2507d 367 *p2++ = t2[0];
Sergeev 1:9b1df0b2507d 368 *p2++ = t2[1];
Sergeev 1:9b1df0b2507d 369 *p3++ = t3[0];
Sergeev 1:9b1df0b2507d 370 *p3++ = t3[1];
Sergeev 1:9b1df0b2507d 371 *p4++ = t4[0];
Sergeev 1:9b1df0b2507d 372 *p4++ = t4[1];
Sergeev 1:9b1df0b2507d 373
Sergeev 1:9b1df0b2507d 374 tw2 += twMod2;
Sergeev 1:9b1df0b2507d 375 tw3 += twMod3;
Sergeev 1:9b1df0b2507d 376 tw4 += twMod4;
Sergeev 1:9b1df0b2507d 377
Sergeev 1:9b1df0b2507d 378 for (l = (L - 2) >> 1; l > 0; l-- )
Sergeev 1:9b1df0b2507d 379 {
Sergeev 1:9b1df0b2507d 380
Sergeev 1:9b1df0b2507d 381 // TOP
Sergeev 1:9b1df0b2507d 382 p1ap3_0 = p1[0] + p3[0];
Sergeev 1:9b1df0b2507d 383 p1sp3_0 = p1[0] - p3[0];
Sergeev 1:9b1df0b2507d 384 p1ap3_1 = p1[1] + p3[1];
Sergeev 1:9b1df0b2507d 385 p1sp3_1 = p1[1] - p3[1];
Sergeev 1:9b1df0b2507d 386 // col 2
Sergeev 1:9b1df0b2507d 387 t2[0] = p1sp3_0 + p2[1] - p4[1];
Sergeev 1:9b1df0b2507d 388 t2[1] = p1sp3_1 - p2[0] + p4[0];
Sergeev 1:9b1df0b2507d 389 // col 3
Sergeev 1:9b1df0b2507d 390 t3[0] = p1ap3_0 - p2[0] - p4[0];
Sergeev 1:9b1df0b2507d 391 t3[1] = p1ap3_1 - p2[1] - p4[1];
Sergeev 1:9b1df0b2507d 392 // col 4
Sergeev 1:9b1df0b2507d 393 t4[0] = p1sp3_0 - p2[1] + p4[1];
Sergeev 1:9b1df0b2507d 394 t4[1] = p1sp3_1 + p2[0] - p4[0];
Sergeev 1:9b1df0b2507d 395 // col 1 - top
Sergeev 1:9b1df0b2507d 396 *p1++ = p1ap3_0 + p2[0] + p4[0];
Sergeev 1:9b1df0b2507d 397 *p1++ = p1ap3_1 + p2[1] + p4[1];
Sergeev 1:9b1df0b2507d 398
Sergeev 1:9b1df0b2507d 399 // BOTTOM
Sergeev 1:9b1df0b2507d 400 p1ap3_1 = pEnd1[-1] + pEnd3[-1];
Sergeev 1:9b1df0b2507d 401 p1sp3_1 = pEnd1[-1] - pEnd3[-1];
Sergeev 1:9b1df0b2507d 402 p1ap3_0 = pEnd1[0] + pEnd3[0];
Sergeev 1:9b1df0b2507d 403 p1sp3_0 = pEnd1[0] - pEnd3[0];
Sergeev 1:9b1df0b2507d 404 // col 2
Sergeev 1:9b1df0b2507d 405 t2[2] = pEnd2[0] - pEnd4[0] + p1sp3_1;
Sergeev 1:9b1df0b2507d 406 t2[3] = pEnd1[0] - pEnd3[0] - pEnd2[-1] + pEnd4[-1];
Sergeev 1:9b1df0b2507d 407 // col 3
Sergeev 1:9b1df0b2507d 408 t3[2] = p1ap3_1 - pEnd2[-1] - pEnd4[-1];
Sergeev 1:9b1df0b2507d 409 t3[3] = p1ap3_0 - pEnd2[0] - pEnd4[0];
Sergeev 1:9b1df0b2507d 410 // col 4
Sergeev 1:9b1df0b2507d 411 t4[2] = pEnd2[0] - pEnd4[0] - p1sp3_1;
Sergeev 1:9b1df0b2507d 412 t4[3] = pEnd4[-1] - pEnd2[-1] - p1sp3_0;
Sergeev 1:9b1df0b2507d 413 // col 1 - Bottom
Sergeev 1:9b1df0b2507d 414 *pEnd1-- = p1ap3_0 + pEnd2[0] + pEnd4[0];
Sergeev 1:9b1df0b2507d 415 *pEnd1-- = p1ap3_1 + pEnd2[-1] + pEnd4[-1];
Sergeev 1:9b1df0b2507d 416
Sergeev 1:9b1df0b2507d 417 // COL 2
Sergeev 1:9b1df0b2507d 418 // read twiddle factors
Sergeev 1:9b1df0b2507d 419 twR = *tw2++;
Sergeev 1:9b1df0b2507d 420 twI = *tw2++;
Sergeev 1:9b1df0b2507d 421 // multiply by twiddle factors
Sergeev 1:9b1df0b2507d 422 // let Z1 = a + i(b), Z2 = c + i(d)
Sergeev 1:9b1df0b2507d 423 // => Z1 * Z2 = (a*c - b*d) + i(b*c + a*d)
Sergeev 1:9b1df0b2507d 424 // Top
Sergeev 1:9b1df0b2507d 425 m0 = t2[0] * twR;
Sergeev 1:9b1df0b2507d 426 m1 = t2[1] * twI;
Sergeev 1:9b1df0b2507d 427 m2 = t2[1] * twR;
Sergeev 1:9b1df0b2507d 428 m3 = t2[0] * twI;
Sergeev 1:9b1df0b2507d 429
Sergeev 1:9b1df0b2507d 430 *p2++ = m0 + m1;
Sergeev 1:9b1df0b2507d 431 *p2++ = m2 - m3;
Sergeev 1:9b1df0b2507d 432 // use vertical symmetry col 2
Sergeev 1:9b1df0b2507d 433 // 0.9997 - 0.0245i <==> 0.0245 - 0.9997i
Sergeev 1:9b1df0b2507d 434 // Bottom
Sergeev 1:9b1df0b2507d 435 m0 = t2[3] * twI;
Sergeev 1:9b1df0b2507d 436 m1 = t2[2] * twR;
Sergeev 1:9b1df0b2507d 437 m2 = t2[2] * twI;
Sergeev 1:9b1df0b2507d 438 m3 = t2[3] * twR;
Sergeev 1:9b1df0b2507d 439
Sergeev 1:9b1df0b2507d 440 *pEnd2-- = m0 - m1;
Sergeev 1:9b1df0b2507d 441 *pEnd2-- = m2 + m3;
Sergeev 1:9b1df0b2507d 442
Sergeev 1:9b1df0b2507d 443 // COL 3
Sergeev 1:9b1df0b2507d 444 twR = tw3[0];
Sergeev 1:9b1df0b2507d 445 twI = tw3[1];
Sergeev 1:9b1df0b2507d 446 tw3 += twMod3;
Sergeev 1:9b1df0b2507d 447 // Top
Sergeev 1:9b1df0b2507d 448 m0 = t3[0] * twR;
Sergeev 1:9b1df0b2507d 449 m1 = t3[1] * twI;
Sergeev 1:9b1df0b2507d 450 m2 = t3[1] * twR;
Sergeev 1:9b1df0b2507d 451 m3 = t3[0] * twI;
Sergeev 1:9b1df0b2507d 452
Sergeev 1:9b1df0b2507d 453 *p3++ = m0 + m1;
Sergeev 1:9b1df0b2507d 454 *p3++ = m2 - m3;
Sergeev 1:9b1df0b2507d 455 // use vertical symmetry col 3
Sergeev 1:9b1df0b2507d 456 // 0.9988 - 0.0491i <==> -0.9988 - 0.0491i
Sergeev 1:9b1df0b2507d 457 // Bottom
Sergeev 1:9b1df0b2507d 458 m0 = -t3[3] * twR;
Sergeev 1:9b1df0b2507d 459 m1 = t3[2] * twI;
Sergeev 1:9b1df0b2507d 460 m2 = t3[2] * twR;
Sergeev 1:9b1df0b2507d 461 m3 = t3[3] * twI;
Sergeev 1:9b1df0b2507d 462
Sergeev 1:9b1df0b2507d 463 *pEnd3-- = m0 - m1;
Sergeev 1:9b1df0b2507d 464 *pEnd3-- = m3 - m2;
Sergeev 1:9b1df0b2507d 465
Sergeev 1:9b1df0b2507d 466 // COL 4
Sergeev 1:9b1df0b2507d 467 twR = tw4[0];
Sergeev 1:9b1df0b2507d 468 twI = tw4[1];
Sergeev 1:9b1df0b2507d 469 tw4 += twMod4;
Sergeev 1:9b1df0b2507d 470 // Top
Sergeev 1:9b1df0b2507d 471 m0 = t4[0] * twR;
Sergeev 1:9b1df0b2507d 472 m1 = t4[1] * twI;
Sergeev 1:9b1df0b2507d 473 m2 = t4[1] * twR;
Sergeev 1:9b1df0b2507d 474 m3 = t4[0] * twI;
Sergeev 1:9b1df0b2507d 475
Sergeev 1:9b1df0b2507d 476 *p4++ = m0 + m1;
Sergeev 1:9b1df0b2507d 477 *p4++ = m2 - m3;
Sergeev 1:9b1df0b2507d 478 // use vertical symmetry col 4
Sergeev 1:9b1df0b2507d 479 // 0.9973 - 0.0736i <==> -0.0736 + 0.9973i
Sergeev 1:9b1df0b2507d 480 // Bottom
Sergeev 1:9b1df0b2507d 481 m0 = t4[3] * twI;
Sergeev 1:9b1df0b2507d 482 m1 = t4[2] * twR;
Sergeev 1:9b1df0b2507d 483 m2 = t4[2] * twI;
Sergeev 1:9b1df0b2507d 484 m3 = t4[3] * twR;
Sergeev 1:9b1df0b2507d 485
Sergeev 1:9b1df0b2507d 486 *pEnd4-- = m0 - m1;
Sergeev 1:9b1df0b2507d 487 *pEnd4-- = m2 + m3;
Sergeev 1:9b1df0b2507d 488 }
Sergeev 1:9b1df0b2507d 489
Sergeev 1:9b1df0b2507d 490 //MIDDLE
Sergeev 1:9b1df0b2507d 491 // Twiddle factors are
Sergeev 1:9b1df0b2507d 492 // 1.0000 0.7071-0.7071i -1.0000i -0.7071-0.7071i
Sergeev 1:9b1df0b2507d 493 p1ap3_0 = p1[0] + p3[0];
Sergeev 1:9b1df0b2507d 494 p1sp3_0 = p1[0] - p3[0];
Sergeev 1:9b1df0b2507d 495 p1ap3_1 = p1[1] + p3[1];
Sergeev 1:9b1df0b2507d 496 p1sp3_1 = p1[1] - p3[1];
Sergeev 1:9b1df0b2507d 497
Sergeev 1:9b1df0b2507d 498 // col 2
Sergeev 1:9b1df0b2507d 499 t2[0] = p1sp3_0 + p2[1] - p4[1];
Sergeev 1:9b1df0b2507d 500 t2[1] = p1sp3_1 - p2[0] + p4[0];
Sergeev 1:9b1df0b2507d 501 // col 3
Sergeev 1:9b1df0b2507d 502 t3[0] = p1ap3_0 - p2[0] - p4[0];
Sergeev 1:9b1df0b2507d 503 t3[1] = p1ap3_1 - p2[1] - p4[1];
Sergeev 1:9b1df0b2507d 504 // col 4
Sergeev 1:9b1df0b2507d 505 t4[0] = p1sp3_0 - p2[1] + p4[1];
Sergeev 1:9b1df0b2507d 506 t4[1] = p1sp3_1 + p2[0] - p4[0];
Sergeev 1:9b1df0b2507d 507 // col 1 - Top
Sergeev 1:9b1df0b2507d 508 *p1++ = p1ap3_0 + p2[0] + p4[0];
Sergeev 1:9b1df0b2507d 509 *p1++ = p1ap3_1 + p2[1] + p4[1];
Sergeev 1:9b1df0b2507d 510
Sergeev 1:9b1df0b2507d 511 // COL 2
Sergeev 1:9b1df0b2507d 512 twR = tw2[0];
Sergeev 1:9b1df0b2507d 513 twI = tw2[1];
Sergeev 1:9b1df0b2507d 514
Sergeev 1:9b1df0b2507d 515 m0 = t2[0] * twR;
Sergeev 1:9b1df0b2507d 516 m1 = t2[1] * twI;
Sergeev 1:9b1df0b2507d 517 m2 = t2[1] * twR;
Sergeev 1:9b1df0b2507d 518 m3 = t2[0] * twI;
Sergeev 1:9b1df0b2507d 519
Sergeev 1:9b1df0b2507d 520 *p2++ = m0 + m1;
Sergeev 1:9b1df0b2507d 521 *p2++ = m2 - m3;
Sergeev 1:9b1df0b2507d 522 // COL 3
Sergeev 1:9b1df0b2507d 523 twR = tw3[0];
Sergeev 1:9b1df0b2507d 524 twI = tw3[1];
Sergeev 1:9b1df0b2507d 525
Sergeev 1:9b1df0b2507d 526 m0 = t3[0] * twR;
Sergeev 1:9b1df0b2507d 527 m1 = t3[1] * twI;
Sergeev 1:9b1df0b2507d 528 m2 = t3[1] * twR;
Sergeev 1:9b1df0b2507d 529 m3 = t3[0] * twI;
Sergeev 1:9b1df0b2507d 530
Sergeev 1:9b1df0b2507d 531 *p3++ = m0 + m1;
Sergeev 1:9b1df0b2507d 532 *p3++ = m2 - m3;
Sergeev 1:9b1df0b2507d 533 // COL 4
Sergeev 1:9b1df0b2507d 534 twR = tw4[0];
Sergeev 1:9b1df0b2507d 535 twI = tw4[1];
Sergeev 1:9b1df0b2507d 536
Sergeev 1:9b1df0b2507d 537 m0 = t4[0] * twR;
Sergeev 1:9b1df0b2507d 538 m1 = t4[1] * twI;
Sergeev 1:9b1df0b2507d 539 m2 = t4[1] * twR;
Sergeev 1:9b1df0b2507d 540 m3 = t4[0] * twI;
Sergeev 1:9b1df0b2507d 541
Sergeev 1:9b1df0b2507d 542 *p4++ = m0 + m1;
Sergeev 1:9b1df0b2507d 543 *p4++ = m2 - m3;
Sergeev 1:9b1df0b2507d 544
Sergeev 1:9b1df0b2507d 545 // first col
Sergeev 1:9b1df0b2507d 546 arm_radix8_butterfly_f32( pCol1, L, (float32_t *) S->pTwiddle, 4u);
Sergeev 1:9b1df0b2507d 547 // second col
Sergeev 1:9b1df0b2507d 548 arm_radix8_butterfly_f32( pCol2, L, (float32_t *) S->pTwiddle, 4u);
Sergeev 1:9b1df0b2507d 549 // third col
Sergeev 1:9b1df0b2507d 550 arm_radix8_butterfly_f32( pCol3, L, (float32_t *) S->pTwiddle, 4u);
Sergeev 1:9b1df0b2507d 551 // fourth col
Sergeev 1:9b1df0b2507d 552 arm_radix8_butterfly_f32( pCol4, L, (float32_t *) S->pTwiddle, 4u);
Sergeev 1:9b1df0b2507d 553
Sergeev 1:9b1df0b2507d 554 }
Sergeev 1:9b1df0b2507d 555
Sergeev 1:9b1df0b2507d 556 /**
Sergeev 1:9b1df0b2507d 557 * @addtogroup ComplexFFT
Sergeev 1:9b1df0b2507d 558 * @{
Sergeev 1:9b1df0b2507d 559 */
Sergeev 1:9b1df0b2507d 560
Sergeev 1:9b1df0b2507d 561 /**
Sergeev 1:9b1df0b2507d 562 * @details
Sergeev 1:9b1df0b2507d 563 * @brief Processing function for the floating-point complex FFT.
Sergeev 1:9b1df0b2507d 564 * @param[in] *S points to an instance of the floating-point CFFT structure.
Sergeev 1:9b1df0b2507d 565 * @param[in, out] *p1 points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
Sergeev 1:9b1df0b2507d 566 * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
Sergeev 1:9b1df0b2507d 567 * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
Sergeev 1:9b1df0b2507d 568 * @return none.
Sergeev 1:9b1df0b2507d 569 */
Sergeev 1:9b1df0b2507d 570
Sergeev 1:9b1df0b2507d 571 void arm_cfft_f32(
Sergeev 1:9b1df0b2507d 572 const arm_cfft_instance_f32 * S,
Sergeev 1:9b1df0b2507d 573 float32_t * p1,
Sergeev 1:9b1df0b2507d 574 uint8_t ifftFlag,
Sergeev 1:9b1df0b2507d 575 uint8_t bitReverseFlag)
Sergeev 1:9b1df0b2507d 576 {
Sergeev 1:9b1df0b2507d 577
Sergeev 1:9b1df0b2507d 578 uint32_t L = S->fftLen, l;
Sergeev 1:9b1df0b2507d 579 float32_t invL, * pSrc;
Sergeev 1:9b1df0b2507d 580
Sergeev 1:9b1df0b2507d 581 if(ifftFlag == 1u)
Sergeev 1:9b1df0b2507d 582 {
Sergeev 1:9b1df0b2507d 583 /* Conjugate input data */
Sergeev 1:9b1df0b2507d 584 pSrc = p1 + 1;
Sergeev 1:9b1df0b2507d 585 for(l=0; l<L; l++) {
Sergeev 1:9b1df0b2507d 586 *pSrc = -*pSrc;
Sergeev 1:9b1df0b2507d 587 pSrc += 2;
Sergeev 1:9b1df0b2507d 588 }
Sergeev 1:9b1df0b2507d 589 }
Sergeev 1:9b1df0b2507d 590
Sergeev 1:9b1df0b2507d 591 switch (L) {
Sergeev 1:9b1df0b2507d 592 case 16:
Sergeev 1:9b1df0b2507d 593 case 128:
Sergeev 1:9b1df0b2507d 594 case 1024:
Sergeev 1:9b1df0b2507d 595 arm_cfft_radix8by2_f32 ( (arm_cfft_instance_f32 *) S, p1);
Sergeev 1:9b1df0b2507d 596 break;
Sergeev 1:9b1df0b2507d 597 case 32:
Sergeev 1:9b1df0b2507d 598 case 256:
Sergeev 1:9b1df0b2507d 599 case 2048:
Sergeev 1:9b1df0b2507d 600 arm_cfft_radix8by4_f32 ( (arm_cfft_instance_f32 *) S, p1);
Sergeev 1:9b1df0b2507d 601 break;
Sergeev 1:9b1df0b2507d 602 case 64:
Sergeev 1:9b1df0b2507d 603 case 512:
Sergeev 1:9b1df0b2507d 604 case 4096:
Sergeev 1:9b1df0b2507d 605 arm_radix8_butterfly_f32( p1, L, (float32_t *) S->pTwiddle, 1);
Sergeev 1:9b1df0b2507d 606 break;
Sergeev 1:9b1df0b2507d 607 }
Sergeev 1:9b1df0b2507d 608
Sergeev 1:9b1df0b2507d 609 if( bitReverseFlag )
Sergeev 1:9b1df0b2507d 610 arm_bitreversal_32((uint32_t*)p1,S->bitRevLength,S->pBitRevTable);
Sergeev 1:9b1df0b2507d 611
Sergeev 1:9b1df0b2507d 612 if(ifftFlag == 1u)
Sergeev 1:9b1df0b2507d 613 {
Sergeev 1:9b1df0b2507d 614 invL = 1.0f/(float32_t)L;
Sergeev 1:9b1df0b2507d 615 /* Conjugate and scale output data */
Sergeev 1:9b1df0b2507d 616 pSrc = p1;
Sergeev 1:9b1df0b2507d 617 for(l=0; l<L; l++) {
Sergeev 1:9b1df0b2507d 618 *pSrc++ *= invL ;
Sergeev 1:9b1df0b2507d 619 *pSrc = -(*pSrc) * invL;
Sergeev 1:9b1df0b2507d 620 pSrc++;
Sergeev 1:9b1df0b2507d 621 }
Sergeev 1:9b1df0b2507d 622 }
Sergeev 1:9b1df0b2507d 623 }