1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010 ARM Limited. All rights reserved.
3 *
4 * $Date: 15. July 2011
5 * $Revision: V1.0.10
6 *
7 * Project: CMSIS DSP Library
8 * Title: arm_cfft_radix4_f32.c
9 *
10 * Description: Radix-4 Decimation in Frequency CFFT & CIFFT Floating point processing function
11 *
12 *
13 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
14 *
15 * Version 1.0.10 2011/7/15
16 * Big Endian support added and Merged M0 and M3/M4 Source code.
17 *
18 * Version 1.0.3 2010/11/29
19 * Re-organized the CMSIS folders and updated documentation.
20 *
21 * Version 1.0.2 2010/11/11
22 * Documentation updated.
23 *
24 * Version 1.0.1 2010/10/05
25 * Production release and review comments incorporated.
26 *
27 * Version 1.0.0 2010/09/20
28 * Production release and review comments incorporated.
29 *
30 * Version 0.0.5 2010/04/26
31 * incorporated review comments and updated with latest CMSIS layer
32 *
33 * Version 0.0.3 2010/03/10
34 * Initial version
35 * -------------------------------------------------------------------- */
36
37 #include "arm_math.h"
38
39 /**
40 * @ingroup groupTransforms
41 */
42
43 /**
44 * @defgroup CFFT_CIFFT Complex FFT Functions
45 *
46 * \par
47 * Complex Fast Fourier Transform(CFFT) and Complex Inverse Fast Fourier Transform(CIFFT) is an efficient algorithm to compute Discrete Fourier Transform(DFT) and Inverse Discrete Fourier Transform(IDFT).
48 * Computational complexity of CFFT reduces drastically when compared to DFT.
49 * \par
50 * This set of functions implements CFFT/CIFFT
51 * for Q15, Q31, and floating-point data types. The functions operates on in-place buffer which uses same buffer for input and output.
52 * Complex input is stored in input buffer in an interleaved fashion.
53 *
54 * \par
55 * The functions operate on blocks of input and output data and each call to the function processes
56 * <code>2*fftLen</code> samples through the transform. <code>pSrc</code> points to In-place arrays containing <code>2*fftLen</code> values.
57 * \par
58 * The <code>pSrc</code> points to the array of in-place buffer of size <code>2*fftLen</code> and inputs and outputs are stored in an interleaved fashion as shown below.
59 * <pre> {real[0], imag[0], real[1], imag[1],..} </pre>
60 *
61 * \par Lengths supported by the transform:
62 * \par
63 * Internally, the function utilize a radix-4 decimation in frequency(DIF) algorithm
64 * and the size of the FFT supported are of the lengths [16, 64, 256, 1024].
65 *
66 *
67 * \par Algorithm:
68 *
69 * <b>Complex Fast Fourier Transform:</b>
70 * \par
71 * Input real and imaginary data:
72 * <pre>
73 * x(n) = xa + j * ya
74 * x(n+N/4 ) = xb + j * yb
75 * x(n+N/2 ) = xc + j * yc
76 * x(n+3N 4) = xd + j * yd
77 * </pre>
78 * where N is length of FFT
79 * \par
80 * Output real and imaginary data:
81 * <pre>
82 * X(4r) = xa'+ j * ya'
83 * X(4r+1) = xb'+ j * yb'
84 * X(4r+2) = xc'+ j * yc'
85 * X(4r+3) = xd'+ j * yd'
86 * </pre>
87 * \par
88 * Twiddle factors for radix-4 FFT:
89 * <pre>
90 * Wn = co1 + j * (- si1)
91 * W2n = co2 + j * (- si2)
92 * W3n = co3 + j * (- si3)
93 * </pre>
94 *
95 * \par
96 * \image html CFFT.gif "Radix-4 Decimation-in Frequency Complex Fast Fourier Transform"
97 *
98 * \par
99 * Output from Radix-4 CFFT Results in Digit reversal order. Interchange middle two branches of every butterfly results in Bit reversed output.
100 * \par
101 * <b> Butterfly CFFT equations:</b>
102 * <pre>
103 * xa' = xa + xb + xc + xd
104 * ya' = ya + yb + yc + yd
105 * xc' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1)
106 * yc' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1)
107 * xb' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2)
108 * yb' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2)
109 * xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3)
110 * yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3)
111 * </pre>
112 *
113 *
114 * <b>Complex Inverse Fast Fourier Transform:</b>
115 * \par
116 * CIFFT uses same twiddle factor table as CFFT with modifications in the design equation as shown below.
117 *
118 * \par
119 * <b> Modified Butterfly CIFFT equations:</b>
120 * <pre>
121 * xa' = xa + xb + xc + xd
122 * ya' = ya + yb + yc + yd
123 * xc' = (xa-yb-xc+yd)* co1 - (ya+xb-yc-xd)* (si1)
124 * yc' = (ya+xb-yc-xd)* co1 + (xa-yb-xc+yd)* (si1)
125 * xb' = (xa-xb+xc-xd)* co2 - (ya-yb+yc-yd)* (si2)
126 * yb' = (ya-yb+yc-yd)* co2 + (xa-xb+xc-xd)* (si2)
127 * xd' = (xa+yb-xc-yd)* co3 - (ya-xb-yc+xd)* (si3)
128 * yd' = (ya-xb-yc+xd)* co3 + (xa+yb-xc-yd)* (si3)
129 * </pre>
130 *
131 * \par Instance Structure
132 * A separate instance structure must be defined for each Instance but the twiddle factors and bit reversal tables can be reused.
133 * There are separate instance structure declarations for each of the 3 supported data types.
134 *
135 * \par Initialization Functions
136 * There is also an associated initialization function for each data type.
137 * The initialization function performs the following operations:
138 * - Sets the values of the internal structure fields.
139 * - Initializes twiddle factor table and bit reversal table pointers
140 * \par
141 * Use of the initialization function is optional.
142 * However, if the initialization function is used, then the instance structure cannot be placed into a const data section.
143 * To place an instance structure into a const data section, the instance structure must be manually initialized.
144 * Manually initialize the instance structure as follows:
145 * <pre>
146 *arm_cfft_radix4_instance_f32 S = {fftLen, ifftFlag, bitReverseFlag, pTwiddle, pBitRevTable, twidCoefModifier, bitRevFactor, onebyfftLen};
147 *arm_cfft_radix4_instance_q31 S = {fftLen, ifftFlag, bitReverseFlag, pTwiddle, pBitRevTable, twidCoefModifier, bitRevFactor};
148 *arm_cfft_radix4_instance_q15 S = {fftLen, ifftFlag, bitReverseFlag, pTwiddle, pBitRevTable, twidCoefModifier, bitRevFactor};
149 * </pre>
150 * \par
151 * where <code>fftLen</code> length of CFFT/CIFFT; <code>ifftFlag</code> Flag for selection of CFFT or CIFFT(Set ifftFlag to calculate CIFFT otherwise calculates CFFT);
152 * <code>bitReverseFlag</code> Flag for selection of output order(Set bitReverseFlag to output in normal order otherwise output in bit reversed order);
153 * <code>pTwiddle</code>points to array of twiddle coefficients; <code>pBitRevTable</code> points to the array of bit reversal table.
154 * <code>twidCoefModifier</code> modifier for twiddle factor table which supports all FFT lengths with same table;
155 * <code>pBitRevTable</code> modifier for bit reversal table which supports all FFT lengths with same table.
156 * <code>onebyfftLen</code> value of 1/fftLen to calculate CIFFT;
157 *
158 * \par Fixed-Point Behavior
159 * Care must be taken when using the fixed-point versions of the CFFT/CIFFT function.
160 * Refer to the function specific documentation below for usage guidelines.
161 */
162
163
164 /**
165 * @addtogroup CFFT_CIFFT
166 * @{
167 */
168
169 /**
170 * @details
171 * @brief Processing function for the floating-point CFFT/CIFFT.
172 * @param[in] *S points to an instance of the floating-point CFFT/CIFFT structure.
173 * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
174 * @return none.
175 */
176
arm_cfft_radix4_f32(const arm_cfft_radix4_instance_f32 * S,float32_t * pSrc)177 void arm_cfft_radix4_f32(
178 const arm_cfft_radix4_instance_f32 * S,
179 float32_t * pSrc)
180 {
181
182 if(S->ifftFlag == 1u)
183 {
184 /* Complex IFFT radix-4 */
185 arm_radix4_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
186 S->twidCoefModifier, S->onebyfftLen);
187 }
188 else
189 {
190 /* Complex FFT radix-4 */
191 arm_radix4_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
192 S->twidCoefModifier);
193 }
194
195 if(S->bitReverseFlag == 1u)
196 {
197 /* Bit Reversal */
198 arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
199 }
200
201 }
202
203
204 /**
205 * @} end of CFFT_CIFFT group
206 */
207
208
209
210 /* ----------------------------------------------------------------------
211 ** Internal helper function used by the FFTs
212 ** ------------------------------------------------------------------- */
213
214 /*
215 * @brief Core function for the floating-point CFFT butterfly process.
216 * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
217 * @param[in] fftLen length of the FFT.
218 * @param[in] *pCoef points to the twiddle coefficient buffer.
219 * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
220 * @return none.
221 */
222
arm_radix4_butterfly_f32(float32_t * pSrc,uint16_t fftLen,float32_t * pCoef,uint16_t twidCoefModifier)223 void arm_radix4_butterfly_f32(
224 float32_t * pSrc,
225 uint16_t fftLen,
226 float32_t * pCoef,
227 uint16_t twidCoefModifier)
228 {
229
230 float32_t co1, co2, co3, si1, si2, si3;
231 float32_t t1, t2, r1, r2, s1, s2;
232 uint32_t ia1, ia2, ia3;
233 uint32_t i0, i1, i2, i3;
234 uint32_t n1, n2, j, k;
235
236 #ifndef ARM_MATH_CM0
237
238 /* Run the below code for Cortex-M4 and Cortex-M3 */
239
240 /* Initializations for the first stage */
241 n2 = fftLen;
242 n1 = n2;
243
244 /* n2 = fftLen/4 */
245 n2 >>= 2u;
246 i0 = 0u;
247 ia1 = 0u;
248
249 j = n2;
250
251 /* Calculation of first stage */
252 do
253 {
254 /* index calculation for the input as, */
255 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
256 i1 = i0 + n2;
257 i2 = i1 + n2;
258 i3 = i2 + n2;
259
260 /* Butterfly implementation */
261
262 /* xa + xc */
263 r1 = pSrc[(2u * i0)] + pSrc[(2u * i2)];
264
265 /* xa - xc */
266 r2 = pSrc[2u * i0] - pSrc[2u * i2];
267
268 /* ya + yc */
269 s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
270
271 /* ya - yc */
272 s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
273
274 /* xb + xd */
275 t1 = pSrc[2u * i1] + pSrc[2u * i3];
276
277 /* xa' = xa + xb + xc + xd */
278 pSrc[2u * i0] = r1 + t1;
279
280 /* (xa + xc) - (xb + xd) */
281 r1 = r1 - t1;
282
283 /* yb + yd */
284 t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
285
286 /* ya' = ya + yb + yc + yd */
287 pSrc[(2u * i0) + 1u] = s1 + t2;
288
289 /* (ya + yc) - (yb + yd) */
290 s1 = s1 - t2;
291
292 /* yb - yd */
293 t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
294
295 /* xb - xd */
296 t2 = pSrc[2u * i1] - pSrc[2u * i3];
297
298 /* index calculation for the coefficients */
299 ia2 = ia1 + ia1;
300 co2 = pCoef[ia2 * 2u];
301 si2 = pCoef[(ia2 * 2u) + 1u];
302
303 /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
304 pSrc[2u * i1] = (r1 * co2) + (s1 * si2);
305
306 /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
307 pSrc[(2u * i1) + 1u] = (s1 * co2) - (r1 * si2);
308
309 /* (xa - xc) + (yb - yd) */
310 r1 = r2 + t1;
311
312 /* (xa - xc) - (yb - yd) */
313 r2 = r2 - t1;
314
315 /* (ya - yc) - (xb - xd) */
316 s1 = s2 - t2;
317
318 /* (ya - yc) + (xb - xd) */
319 s2 = s2 + t2;
320
321 co1 = pCoef[ia1 * 2u];
322 si1 = pCoef[(ia1 * 2u) + 1u];
323
324 /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
325 pSrc[2u * i2] = (r1 * co1) + (s1 * si1);
326
327 /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
328 pSrc[(2u * i2) + 1u] = (s1 * co1) - (r1 * si1);
329
330 /* index calculation for the coefficients */
331 ia3 = ia2 + ia1;
332 co3 = pCoef[ia3 * 2u];
333 si3 = pCoef[(ia3 * 2u) + 1u];
334
335
336 /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
337 pSrc[2u * i3] = (r2 * co3) + (s2 * si3);
338
339 /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
340 pSrc[(2u * i3) + 1u] = (s2 * co3) - (r2 * si3);
341
342 /* Twiddle coefficients index modifier */
343 ia1 = ia1 + twidCoefModifier;
344
345 /* Updating input index */
346 i0 = i0 + 1u;
347
348 }
349 while(--j);
350
351 twidCoefModifier <<= 2u;
352
353 /* Calculation of second stage to excluding last stage */
354 for (k = fftLen / 4; k > 4u; k >>= 2u)
355 {
356 /* Initializations for the first stage */
357 n1 = n2;
358 n2 >>= 2u;
359 ia1 = 0u;
360
361 /* Calculation of first stage */
362 for (j = 0u; j <= (n2 - 1u); j++)
363 {
364 /* index calculation for the coefficients */
365 ia2 = ia1 + ia1;
366 ia3 = ia2 + ia1;
367 co1 = pCoef[ia1 * 2u];
368 si1 = pCoef[(ia1 * 2u) + 1u];
369 co2 = pCoef[ia2 * 2u];
370 si2 = pCoef[(ia2 * 2u) + 1u];
371 co3 = pCoef[ia3 * 2u];
372 si3 = pCoef[(ia3 * 2u) + 1u];
373
374 /* Twiddle coefficients index modifier */
375 ia1 = ia1 + twidCoefModifier;
376
377 for (i0 = j; i0 < fftLen; i0 += n1)
378 {
379 /* index calculation for the input as, */
380 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
381 i1 = i0 + n2;
382 i2 = i1 + n2;
383 i3 = i2 + n2;
384
385 /* xa + xc */
386 r1 = pSrc[(2u * i0)] + pSrc[(2u * i2)];
387
388 /* xa - xc */
389 r2 = pSrc[(2u * i0)] - pSrc[(2u * i2)];
390
391 /* ya + yc */
392 s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
393
394 /* ya - yc */
395 s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
396
397 /* xb + xd */
398 t1 = pSrc[2u * i1] + pSrc[2u * i3];
399
400 /* xa' = xa + xb + xc + xd */
401 pSrc[2u * i0] = r1 + t1;
402
403 /* xa + xc -(xb + xd) */
404 r1 = r1 - t1;
405
406 /* yb + yd */
407 t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
408
409 /* ya' = ya + yb + yc + yd */
410 pSrc[(2u * i0) + 1u] = s1 + t2;
411
412 /* (ya + yc) - (yb + yd) */
413 s1 = s1 - t2;
414
415 /* (yb - yd) */
416 t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
417
418 /* (xb - xd) */
419 t2 = pSrc[2u * i1] - pSrc[2u * i3];
420
421 /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
422 pSrc[2u * i1] = (r1 * co2) + (s1 * si2);
423
424 /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
425 pSrc[(2u * i1) + 1u] = (s1 * co2) - (r1 * si2);
426
427 /* (xa - xc) + (yb - yd) */
428 r1 = r2 + t1;
429
430 /* (xa - xc) - (yb - yd) */
431 r2 = r2 - t1;
432
433 /* (ya - yc) - (xb - xd) */
434 s1 = s2 - t2;
435
436 /* (ya - yc) + (xb - xd) */
437 s2 = s2 + t2;
438
439 /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
440 pSrc[2u * i2] = (r1 * co1) + (s1 * si1);
441
442 /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
443 pSrc[(2u * i2) + 1u] = (s1 * co1) - (r1 * si1);
444
445 /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
446 pSrc[2u * i3] = (r2 * co3) + (s2 * si3);
447
448 /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
449 pSrc[(2u * i3) + 1u] = (s2 * co3) - (r2 * si3);
450 }
451 }
452 twidCoefModifier <<= 2u;
453 }
454
455 /* Initializations of last stage */
456 n1 = n2;
457 n2 >>= 2u;
458
459 /* Calculations of last stage */
460 for (i0 = 0u; i0 <= (fftLen - n1); i0 += n1)
461 {
462 /* index calculation for the input as, */
463 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
464 i1 = i0 + n2;
465 i2 = i1 + n2;
466 i3 = i2 + n2;
467
468 /* Butterfly implementation */
469
470 /* xa + xb */
471 r1 = pSrc[2u * i0] + pSrc[2u * i2];
472
473 /* xa - xb */
474 r2 = pSrc[2u * i0] - pSrc[2u * i2];
475
476 /* ya + yc */
477 s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
478
479 /* ya - yc */
480 s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
481
482 /* xc + xd */
483 t1 = pSrc[2u * i1] + pSrc[2u * i3];
484
485 /* xa' = xa + xb + xc + xd */
486 pSrc[2u * i0] = r1 + t1;
487
488 /* (xa + xb) - (xc + xd) */
489 r1 = r1 - t1;
490
491 /* yb + yd */
492 t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
493
494 /* ya' = ya + yb + yc + yd */
495 pSrc[(2u * i0) + 1u] = s1 + t2;
496
497 /* (ya + yc) - (yb + yd) */
498 s1 = s1 - t2;
499
500 /* (yb-yd) */
501 t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
502
503 /* (xb-xd) */
504 t2 = pSrc[2u * i1] - pSrc[2u * i3];
505
506 /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
507 pSrc[2u * i1] = r1;
508
509 /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
510 pSrc[(2u * i1) + 1u] = s1;
511
512 /* (xa+yb-xc-yd) */
513 r1 = r2 + t1;
514
515 /* (xa-yb-xc+yd) */
516 r2 = r2 - t1;
517
518 /* (ya-xb-yc+xd) */
519 s1 = s2 - t2;
520
521 /* (ya+xb-yc-xd) */
522 s2 = s2 + t2;
523
524 /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
525 pSrc[2u * i2] = r1;
526
527 /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
528 pSrc[(2u * i2) + 1u] = s1;
529
530 /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
531 pSrc[2u * i3] = r2;
532
533 /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
534 pSrc[(2u * i3) + 1u] = s2;
535 }
536
537
538 #else
539
540 /* Run the below code for Cortex-M0 */
541
542 /* Initializations for the fft calculation */
543 n2 = fftLen;
544 n1 = n2;
545 for (k = fftLen; k > 1u; k >>= 2u)
546 {
547 /* Initializations for the fft calculation */
548 n1 = n2;
549 n2 >>= 2u;
550 ia1 = 0u;
551
552 /* FFT Calculation */
553 for (j = 0u; j <= (n2 - 1u); j++)
554 {
555 /* index calculation for the coefficients */
556 ia2 = ia1 + ia1;
557 ia3 = ia2 + ia1;
558 co1 = pCoef[ia1 * 2u];
559 si1 = pCoef[(ia1 * 2u) + 1u];
560 co2 = pCoef[ia2 * 2u];
561 si2 = pCoef[(ia2 * 2u) + 1u];
562 co3 = pCoef[ia3 * 2u];
563 si3 = pCoef[(ia3 * 2u) + 1u];
564
565 /* Twiddle coefficients index modifier */
566 ia1 = ia1 + twidCoefModifier;
567
568 for (i0 = j; i0 < fftLen; i0 += n1)
569 {
570 /* index calculation for the input as, */
571 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
572 i1 = i0 + n2;
573 i2 = i1 + n2;
574 i3 = i2 + n2;
575
576 /* xa + xc */
577 r1 = pSrc[(2u * i0)] + pSrc[(2u * i2)];
578
579 /* xa - xc */
580 r2 = pSrc[(2u * i0)] - pSrc[(2u * i2)];
581
582 /* ya + yc */
583 s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
584
585 /* ya - yc */
586 s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
587
588 /* xb + xd */
589 t1 = pSrc[2u * i1] + pSrc[2u * i3];
590
591 /* xa' = xa + xb + xc + xd */
592 pSrc[2u * i0] = r1 + t1;
593
594 /* xa + xc -(xb + xd) */
595 r1 = r1 - t1;
596
597 /* yb + yd */
598 t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
599
600 /* ya' = ya + yb + yc + yd */
601 pSrc[(2u * i0) + 1u] = s1 + t2;
602
603 /* (ya + yc) - (yb + yd) */
604 s1 = s1 - t2;
605
606 /* (yb - yd) */
607 t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
608
609 /* (xb - xd) */
610 t2 = pSrc[2u * i1] - pSrc[2u * i3];
611
612 /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
613 pSrc[2u * i1] = (r1 * co2) + (s1 * si2);
614
615 /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
616 pSrc[(2u * i1) + 1u] = (s1 * co2) - (r1 * si2);
617
618 /* (xa - xc) + (yb - yd) */
619 r1 = r2 + t1;
620
621 /* (xa - xc) - (yb - yd) */
622 r2 = r2 - t1;
623
624 /* (ya - yc) - (xb - xd) */
625 s1 = s2 - t2;
626
627 /* (ya - yc) + (xb - xd) */
628 s2 = s2 + t2;
629
630 /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
631 pSrc[2u * i2] = (r1 * co1) + (s1 * si1);
632
633 /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
634 pSrc[(2u * i2) + 1u] = (s1 * co1) - (r1 * si1);
635
636 /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
637 pSrc[2u * i3] = (r2 * co3) + (s2 * si3);
638
639 /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
640 pSrc[(2u * i3) + 1u] = (s2 * co3) - (r2 * si3);
641 }
642 }
643 twidCoefModifier <<= 2u;
644 }
645
646 #endif /* #ifndef ARM_MATH_CM0 */
647
648 }
649
650 /*
651 * @brief Core function for the floating-point CIFFT butterfly process.
652 * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
653 * @param[in] fftLen length of the FFT.
654 * @param[in] *pCoef points to twiddle coefficient buffer.
655 * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
656 * @param[in] onebyfftLen value of 1/fftLen.
657 * @return none.
658 */
659
arm_radix4_butterfly_inverse_f32(float32_t * pSrc,uint16_t fftLen,float32_t * pCoef,uint16_t twidCoefModifier,float32_t onebyfftLen)660 void arm_radix4_butterfly_inverse_f32(
661 float32_t * pSrc,
662 uint16_t fftLen,
663 float32_t * pCoef,
664 uint16_t twidCoefModifier,
665 float32_t onebyfftLen)
666 {
667 float32_t co1, co2, co3, si1, si2, si3;
668 float32_t t1, t2, r1, r2, s1, s2;
669 uint32_t ia1, ia2, ia3;
670 uint32_t i0, i1, i2, i3;
671 uint32_t n1, n2, j, k;
672
673 #ifndef ARM_MATH_CM0
674
675 /* Run the below code for Cortex-M4 and Cortex-M3 */
676
677 /* Initializations for the first stage */
678 n2 = fftLen;
679 n1 = n2;
680
681 /* n2 = fftLen/4 */
682 n2 >>= 2u;
683 i0 = 0u;
684 ia1 = 0u;
685
686 j = n2;
687
688 /* Calculation of first stage */
689 do
690 {
691 /* index calculation for the input as, */
692 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
693 i1 = i0 + n2;
694 i2 = i1 + n2;
695 i3 = i2 + n2;
696
697 /* Butterfly implementation */
698 /* xa + xc */
699 r1 = pSrc[(2u * i0)] + pSrc[(2u * i2)];
700
701 /* xa - xc */
702 r2 = pSrc[2u * i0] - pSrc[2u * i2];
703
704 /* ya + yc */
705 s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
706
707 /* ya - yc */
708 s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
709
710 /* xb + xd */
711 t1 = pSrc[2u * i1] + pSrc[2u * i3];
712
713 /* xa' = xa + xb + xc + xd */
714 pSrc[2u * i0] = r1 + t1;
715
716 /* (xa + xc) - (xb + xd) */
717 r1 = r1 - t1;
718
719 /* yb + yd */
720 t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
721
722 /* ya' = ya + yb + yc + yd */
723 pSrc[(2u * i0) + 1u] = s1 + t2;
724
725 /* (ya + yc) - (yb + yd) */
726 s1 = s1 - t2;
727
728 /* yb - yd */
729 t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
730
731 /* xb - xd */
732 t2 = pSrc[2u * i1] - pSrc[2u * i3];
733
734 /* index calculation for the coefficients */
735 ia2 = ia1 + ia1;
736 co2 = pCoef[ia2 * 2u];
737 si2 = pCoef[(ia2 * 2u) + 1u];
738
739 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
740 pSrc[2u * i1] = (r1 * co2) - (s1 * si2);
741
742 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
743 pSrc[(2u * i1) + 1u] = (s1 * co2) + (r1 * si2);
744
745 /* (xa - xc) - (yb - yd) */
746 r1 = r2 - t1;
747
748 /* (xa - xc) + (yb - yd) */
749 r2 = r2 + t1;
750
751 /* (ya - yc) + (xb - xd) */
752 s1 = s2 + t2;
753
754 /* (ya - yc) - (xb - xd) */
755 s2 = s2 - t2;
756
757 co1 = pCoef[ia1 * 2u];
758 si1 = pCoef[(ia1 * 2u) + 1u];
759
760 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
761 pSrc[2u * i2] = (r1 * co1) - (s1 * si1);
762
763 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
764 pSrc[(2u * i2) + 1u] = (s1 * co1) + (r1 * si1);
765
766 /* index calculation for the coefficients */
767 ia3 = ia2 + ia1;
768 co3 = pCoef[ia3 * 2u];
769 si3 = pCoef[(ia3 * 2u) + 1u];
770
771 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
772 pSrc[2u * i3] = (r2 * co3) - (s2 * si3);
773
774 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
775 pSrc[(2u * i3) + 1u] = (s2 * co3) + (r2 * si3);
776
777 /* Twiddle coefficients index modifier */
778 ia1 = ia1 + twidCoefModifier;
779
780 /* Updating input index */
781 i0 = i0 + 1u;
782
783 }
784 while(--j);
785
786 twidCoefModifier <<= 2u;
787
788 /* Calculation of second stage to excluding last stage */
789 for (k = fftLen / 4; k > 4u; k >>= 2u)
790 {
791 /* Initializations for the first stage */
792 n1 = n2;
793 n2 >>= 2u;
794 ia1 = 0u;
795
796 /* Calculation of first stage */
797 for (j = 0u; j <= (n2 - 1u); j++)
798 {
799 /* index calculation for the coefficients */
800 ia2 = ia1 + ia1;
801 ia3 = ia2 + ia1;
802 co1 = pCoef[ia1 * 2u];
803 si1 = pCoef[(ia1 * 2u) + 1u];
804 co2 = pCoef[ia2 * 2u];
805 si2 = pCoef[(ia2 * 2u) + 1u];
806 co3 = pCoef[ia3 * 2u];
807 si3 = pCoef[(ia3 * 2u) + 1u];
808
809 /* Twiddle coefficients index modifier */
810 ia1 = ia1 + twidCoefModifier;
811
812 for (i0 = j; i0 < fftLen; i0 += n1)
813 {
814 /* index calculation for the input as, */
815 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
816 i1 = i0 + n2;
817 i2 = i1 + n2;
818 i3 = i2 + n2;
819
820 /* xa + xc */
821 r1 = pSrc[(2u * i0)] + pSrc[(2u * i2)];
822
823 /* xa - xc */
824 r2 = pSrc[(2u * i0)] - pSrc[(2u * i2)];
825
826 /* ya + yc */
827 s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
828
829 /* ya - yc */
830 s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
831
832 /* xb + xd */
833 t1 = pSrc[2u * i1] + pSrc[2u * i3];
834
835 /* xa' = xa + xb + xc + xd */
836 pSrc[2u * i0] = r1 + t1;
837
838 /* xa + xc -(xb + xd) */
839 r1 = r1 - t1;
840
841 /* yb + yd */
842 t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
843
844 /* ya' = ya + yb + yc + yd */
845 pSrc[(2u * i0) + 1u] = s1 + t2;
846
847 /* (ya + yc) - (yb + yd) */
848 s1 = s1 - t2;
849
850 /* (yb - yd) */
851 t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
852
853 /* (xb - xd) */
854 t2 = pSrc[2u * i1] - pSrc[2u * i3];
855
856 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
857 pSrc[2u * i1] = (r1 * co2) - (s1 * si2);
858
859 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
860 pSrc[(2u * i1) + 1u] = (s1 * co2) + (r1 * si2);
861
862 /* (xa - xc) - (yb - yd) */
863 r1 = r2 - t1;
864
865 /* (xa - xc) + (yb - yd) */
866 r2 = r2 + t1;
867
868 /* (ya - yc) + (xb - xd) */
869 s1 = s2 + t2;
870
871 /* (ya - yc) - (xb - xd) */
872 s2 = s2 - t2;
873
874 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
875 pSrc[2u * i2] = (r1 * co1) - (s1 * si1);
876
877 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
878 pSrc[(2u * i2) + 1u] = (s1 * co1) + (r1 * si1);
879
880 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
881 pSrc[2u * i3] = (r2 * co3) - (s2 * si3);
882
883 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
884 pSrc[(2u * i3) + 1u] = (s2 * co3) + (r2 * si3);
885 }
886 }
887 twidCoefModifier <<= 2u;
888 }
889
890 /* Initializations of last stage */
891 n1 = n2;
892 n2 >>= 2u;
893
894 /* Calculations of last stage */
895 for (i0 = 0u; i0 <= (fftLen - n1); i0 += n1)
896 {
897 /* index calculation for the input as, */
898 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
899 i1 = i0 + n2;
900 i2 = i1 + n2;
901 i3 = i2 + n2;
902
903 /* Butterfly implementation */
904 /* xa + xc */
905 r1 = pSrc[2u * i0] + pSrc[2u * i2];
906
907 /* xa - xc */
908 r2 = pSrc[2u * i0] - pSrc[2u * i2];
909
910 /* ya + yc */
911 s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
912
913 /* ya - yc */
914 s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
915
916 /* xc + xd */
917 t1 = pSrc[2u * i1] + pSrc[2u * i3];
918
919 /* xa' = xa + xb + xc + xd */
920 pSrc[2u * i0] = (r1 + t1) * onebyfftLen;
921
922 /* (xa + xb) - (xc + xd) */
923 r1 = r1 - t1;
924
925 /* yb + yd */
926 t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
927
928 /* ya' = ya + yb + yc + yd */
929 pSrc[(2u * i0) + 1u] = (s1 + t2) * onebyfftLen;
930
931 /* (ya + yc) - (yb + yd) */
932 s1 = s1 - t2;
933
934 /* (yb-yd) */
935 t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
936
937 /* (xb-xd) */
938 t2 = pSrc[2u * i1] - pSrc[2u * i3];
939
940 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
941 pSrc[2u * i1] = r1 * onebyfftLen;
942
943 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
944 pSrc[(2u * i1) + 1u] = s1 * onebyfftLen;
945
946
947 /* (xa - xc) - (yb-yd) */
948 r1 = r2 - t1;
949
950 /* (xa - xc) + (yb-yd) */
951 r2 = r2 + t1;
952
953 /* (ya - yc) + (xb-xd) */
954 s1 = s2 + t2;
955
956 /* (ya - yc) - (xb-xd) */
957 s2 = s2 - t2;
958
959 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
960 pSrc[2u * i2] = r1 * onebyfftLen;
961
962 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
963 pSrc[(2u * i2) + 1u] = s1 * onebyfftLen;
964
965 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
966 pSrc[2u * i3] = r2 * onebyfftLen;
967
968 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
969 pSrc[(2u * i3) + 1u] = s2 * onebyfftLen;
970 }
971
972
973 #else
974
975 /* Run the below code for Cortex-M0 */
976
977 /* Initializations for the first stage */
978 n2 = fftLen;
979 n1 = n2;
980
981 /* Calculation of first stage */
982 for (k = fftLen; k > 4u; k >>= 2u)
983 {
984 /* Initializations for the first stage */
985 n1 = n2;
986 n2 >>= 2u;
987 ia1 = 0u;
988
989 /* Calculation of first stage */
990 for (j = 0u; j <= (n2 - 1u); j++)
991 {
992 /* index calculation for the coefficients */
993 ia2 = ia1 + ia1;
994 ia3 = ia2 + ia1;
995 co1 = pCoef[ia1 * 2u];
996 si1 = pCoef[(ia1 * 2u) + 1u];
997 co2 = pCoef[ia2 * 2u];
998 si2 = pCoef[(ia2 * 2u) + 1u];
999 co3 = pCoef[ia3 * 2u];
1000 si3 = pCoef[(ia3 * 2u) + 1u];
1001
1002 /* Twiddle coefficients index modifier */
1003 ia1 = ia1 + twidCoefModifier;
1004
1005 for (i0 = j; i0 < fftLen; i0 += n1)
1006 {
1007 /* index calculation for the input as, */
1008 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
1009 i1 = i0 + n2;
1010 i2 = i1 + n2;
1011 i3 = i2 + n2;
1012
1013 /* xa + xc */
1014 r1 = pSrc[(2u * i0)] + pSrc[(2u * i2)];
1015
1016 /* xa - xc */
1017 r2 = pSrc[(2u * i0)] - pSrc[(2u * i2)];
1018
1019 /* ya + yc */
1020 s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
1021
1022 /* ya - yc */
1023 s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
1024
1025 /* xb + xd */
1026 t1 = pSrc[2u * i1] + pSrc[2u * i3];
1027
1028 /* xa' = xa + xb + xc + xd */
1029 pSrc[2u * i0] = r1 + t1;
1030
1031 /* xa + xc -(xb + xd) */
1032 r1 = r1 - t1;
1033
1034 /* yb + yd */
1035 t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
1036
1037 /* ya' = ya + yb + yc + yd */
1038 pSrc[(2u * i0) + 1u] = s1 + t2;
1039
1040 /* (ya + yc) - (yb + yd) */
1041 s1 = s1 - t2;
1042
1043 /* (yb - yd) */
1044 t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
1045
1046 /* (xb - xd) */
1047 t2 = pSrc[2u * i1] - pSrc[2u * i3];
1048
1049 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
1050 pSrc[2u * i1] = (r1 * co2) - (s1 * si2);
1051
1052 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
1053 pSrc[(2u * i1) + 1u] = (s1 * co2) + (r1 * si2);
1054
1055 /* (xa - xc) - (yb - yd) */
1056 r1 = r2 - t1;
1057
1058 /* (xa - xc) + (yb - yd) */
1059 r2 = r2 + t1;
1060
1061 /* (ya - yc) + (xb - xd) */
1062 s1 = s2 + t2;
1063
1064 /* (ya - yc) - (xb - xd) */
1065 s2 = s2 - t2;
1066
1067 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
1068 pSrc[2u * i2] = (r1 * co1) - (s1 * si1);
1069
1070 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
1071 pSrc[(2u * i2) + 1u] = (s1 * co1) + (r1 * si1);
1072
1073 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
1074 pSrc[2u * i3] = (r2 * co3) - (s2 * si3);
1075
1076 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
1077 pSrc[(2u * i3) + 1u] = (s2 * co3) + (r2 * si3);
1078 }
1079 }
1080 twidCoefModifier <<= 2u;
1081 }
1082 /* Initializations of last stage */
1083 n1 = n2;
1084 n2 >>= 2u;
1085
1086 /* Calculations of last stage */
1087 for (i0 = 0u; i0 <= (fftLen - n1); i0 += n1)
1088 {
1089 /* index calculation for the input as, */
1090 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
1091 i1 = i0 + n2;
1092 i2 = i1 + n2;
1093 i3 = i2 + n2;
1094
1095 /* Butterfly implementation */
1096 /* xa + xc */
1097 r1 = pSrc[2u * i0] + pSrc[2u * i2];
1098
1099 /* xa - xc */
1100 r2 = pSrc[2u * i0] - pSrc[2u * i2];
1101
1102 /* ya + yc */
1103 s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
1104
1105 /* ya - yc */
1106 s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
1107
1108 /* xc + xd */
1109 t1 = pSrc[2u * i1] + pSrc[2u * i3];
1110
1111 /* xa' = xa + xb + xc + xd */
1112 pSrc[2u * i0] = (r1 + t1) * onebyfftLen;
1113
1114 /* (xa + xb) - (xc + xd) */
1115 r1 = r1 - t1;
1116
1117 /* yb + yd */
1118 t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
1119
1120 /* ya' = ya + yb + yc + yd */
1121 pSrc[(2u * i0) + 1u] = (s1 + t2) * onebyfftLen;
1122
1123 /* (ya + yc) - (yb + yd) */
1124 s1 = s1 - t2;
1125
1126 /* (yb-yd) */
1127 t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
1128
1129 /* (xb-xd) */
1130 t2 = pSrc[2u * i1] - pSrc[2u * i3];
1131
1132 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
1133 pSrc[2u * i1] = r1 * onebyfftLen;
1134
1135 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
1136 pSrc[(2u * i1) + 1u] = s1 * onebyfftLen;
1137
1138
1139 /* (xa - xc) - (yb-yd) */
1140 r1 = r2 - t1;
1141
1142 /* (xa - xc) + (yb-yd) */
1143 r2 = r2 + t1;
1144
1145 /* (ya - yc) + (xb-xd) */
1146 s1 = s2 + t2;
1147
1148 /* (ya - yc) - (xb-xd) */
1149 s2 = s2 - t2;
1150
1151 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
1152 pSrc[2u * i2] = r1 * onebyfftLen;
1153
1154 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
1155 pSrc[(2u * i2) + 1u] = s1 * onebyfftLen;
1156
1157 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
1158 pSrc[2u * i3] = r2 * onebyfftLen;
1159
1160 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
1161 pSrc[(2u * i3) + 1u] = s2 * onebyfftLen;
1162 }
1163
1164 #endif /* #ifndef ARM_MATH_CM0 */
1165
1166 }
1167
1168 /*
1169 * @brief In-place bit reversal function.
1170 * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
1171 * @param[in] fftSize length of the FFT.
1172 * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table.
1173 * @param[in] *pBitRevTab points to the bit reversal table.
1174 * @return none.
1175 */
1176
arm_bitreversal_f32(float32_t * pSrc,uint16_t fftSize,uint16_t bitRevFactor,uint16_t * pBitRevTab)1177 void arm_bitreversal_f32(
1178 float32_t * pSrc,
1179 uint16_t fftSize,
1180 uint16_t bitRevFactor,
1181 uint16_t * pBitRevTab)
1182 {
1183 uint16_t fftLenBy2, fftLenBy2p1;
1184 uint16_t i, j;
1185 float32_t in;
1186
1187 /* Initializations */
1188 j = 0u;
1189 fftLenBy2 = fftSize >> 1u;
1190 fftLenBy2p1 = (fftSize >> 1u) + 1u;
1191
1192 /* Bit Reversal Implementation */
1193 for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
1194 {
1195 if(i < j)
1196 {
1197 /* pSrc[i] <-> pSrc[j]; */
1198 in = pSrc[2u * i];
1199 pSrc[2u * i] = pSrc[2u * j];
1200 pSrc[2u * j] = in;
1201
1202 /* pSrc[i+1u] <-> pSrc[j+1u] */
1203 in = pSrc[(2u * i) + 1u];
1204 pSrc[(2u * i) + 1u] = pSrc[(2u * j) + 1u];
1205 pSrc[(2u * j) + 1u] = in;
1206
1207 /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
1208 in = pSrc[2u * (i + fftLenBy2p1)];
1209 pSrc[2u * (i + fftLenBy2p1)] = pSrc[2u * (j + fftLenBy2p1)];
1210 pSrc[2u * (j + fftLenBy2p1)] = in;
1211
1212 /* pSrc[i+fftLenBy2p1+1u] <-> pSrc[j+fftLenBy2p1+1u] */
1213 in = pSrc[(2u * (i + fftLenBy2p1)) + 1u];
1214 pSrc[(2u * (i + fftLenBy2p1)) + 1u] =
1215 pSrc[(2u * (j + fftLenBy2p1)) + 1u];
1216 pSrc[(2u * (j + fftLenBy2p1)) + 1u] = in;
1217
1218 }
1219
1220 /* pSrc[i+1u] <-> pSrc[j+1u] */
1221 in = pSrc[2u * (i + 1u)];
1222 pSrc[2u * (i + 1u)] = pSrc[2u * (j + fftLenBy2)];
1223 pSrc[2u * (j + fftLenBy2)] = in;
1224
1225 /* pSrc[i+2u] <-> pSrc[j+2u] */
1226 in = pSrc[(2u * (i + 1u)) + 1u];
1227 pSrc[(2u * (i + 1u)) + 1u] = pSrc[(2u * (j + fftLenBy2)) + 1u];
1228 pSrc[(2u * (j + fftLenBy2)) + 1u] = in;
1229
1230 /* Reading the index for the bit reversal */
1231 j = *pBitRevTab;
1232
1233 /* Updating the bit reversal index depending on the fft length */
1234 pBitRevTab += bitRevFactor;
1235 }
1236 }
1237