1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010-2013 ARM Limited. All rights reserved.
4 * $Date: 17. January 2013
7 * Project: CMSIS DSP Library
8 * Title: arm_cfft_radix4_f32.c
10 * Description: Radix-4 Decimation in Frequency CFFT & CIFFT Floating point processing function
13 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * - Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * - Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in
22 * the documentation and/or other materials provided with the
24 * - Neither the name of ARM LIMITED nor the names of its contributors
25 * may be used to endorse or promote products derived from this
26 * software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 * -------------------------------------------------------------------- */
44 extern void arm_bitreversal_f32(
47 uint16_t bitRevFactor
,
48 uint16_t * pBitRevTab
);
51 * @ingroup groupTransforms
54 /* ----------------------------------------------------------------------
55 ** Internal helper function used by the FFTs
56 ** ------------------------------------------------------------------- */
59 * @brief Core function for the floating-point CFFT butterfly process.
60 * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
61 * @param[in] fftLen length of the FFT.
62 * @param[in] *pCoef points to the twiddle coefficient buffer.
63 * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
67 void arm_radix4_butterfly_f32(
71 uint16_t twidCoefModifier
)
74 float32_t co1
, co2
, co3
, si1
, si2
, si3
;
75 uint32_t ia1
, ia2
, ia3
;
76 uint32_t i0
, i1
, i2
, i3
;
77 uint32_t n1
, n2
, j
, k
;
79 #ifndef ARM_MATH_CM0_FAMILY_FAMILY
81 /* Run the below code for Cortex-M4 and Cortex-M3 */
83 float32_t xaIn
, yaIn
, xbIn
, ybIn
, xcIn
, ycIn
, xdIn
, ydIn
;
84 float32_t Xaplusc
, Xbplusd
, Yaplusc
, Ybplusd
, Xaminusc
, Xbminusd
, Yaminusc
,
86 float32_t Xb12C_out
, Yb12C_out
, Xc12C_out
, Yc12C_out
, Xd12C_out
, Yd12C_out
;
87 float32_t Xb12_out
, Yb12_out
, Xc12_out
, Yc12_out
, Xd12_out
, Yd12_out
;
89 float32_t p0
,p1
,p2
,p3
,p4
,p5
;
90 float32_t a0
,a1
,a2
,a3
,a4
,a5
,a6
,a7
;
92 /* Initializations for the first stage */
103 /* Calculation of first stage */
106 /* index calculation for the input as, */
107 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
112 xaIn
= pSrc
[(2u * i0
)];
113 yaIn
= pSrc
[(2u * i0
) + 1u];
115 xbIn
= pSrc
[(2u * i1
)];
116 ybIn
= pSrc
[(2u * i1
) + 1u];
118 xcIn
= pSrc
[(2u * i2
)];
119 ycIn
= pSrc
[(2u * i2
) + 1u];
121 xdIn
= pSrc
[(2u * i3
)];
122 ydIn
= pSrc
[(2u * i3
) + 1u];
125 Xaplusc
= xaIn
+ xcIn
;
127 Xbplusd
= xbIn
+ xdIn
;
129 Yaplusc
= yaIn
+ ycIn
;
131 Ybplusd
= ybIn
+ ydIn
;
133 /* index calculation for the coefficients */
135 co2
= pCoef
[ia2
* 2u];
136 si2
= pCoef
[(ia2
* 2u) + 1u];
139 Xaminusc
= xaIn
- xcIn
;
141 Xbminusd
= xbIn
- xdIn
;
143 Yaminusc
= yaIn
- ycIn
;
145 Ybminusd
= ybIn
- ydIn
;
147 /* xa' = xa + xb + xc + xd */
148 pSrc
[(2u * i0
)] = Xaplusc
+ Xbplusd
;
149 /* ya' = ya + yb + yc + yd */
150 pSrc
[(2u * i0
) + 1u] = Yaplusc
+ Ybplusd
;
152 /* (xa - xc) + (yb - yd) */
153 Xb12C_out
= (Xaminusc
+ Ybminusd
);
154 /* (ya - yc) + (xb - xd) */
155 Yb12C_out
= (Yaminusc
- Xbminusd
);
156 /* (xa + xc) - (xb + xd) */
157 Xc12C_out
= (Xaplusc
- Xbplusd
);
158 /* (ya + yc) - (yb + yd) */
159 Yc12C_out
= (Yaplusc
- Ybplusd
);
160 /* (xa - xc) - (yb - yd) */
161 Xd12C_out
= (Xaminusc
- Ybminusd
);
162 /* (ya - yc) + (xb - xd) */
163 Yd12C_out
= (Xbminusd
+ Yaminusc
);
165 co1
= pCoef
[ia1
* 2u];
166 si1
= pCoef
[(ia1
* 2u) + 1u];
168 /* index calculation for the coefficients */
170 co3
= pCoef
[ia3
* 2u];
171 si3
= pCoef
[(ia3
* 2u) + 1u];
173 Xb12_out
= Xb12C_out
* co1
;
174 Yb12_out
= Yb12C_out
* co1
;
175 Xc12_out
= Xc12C_out
* co2
;
176 Yc12_out
= Yc12C_out
* co2
;
177 Xd12_out
= Xd12C_out
* co3
;
178 Yd12_out
= Yd12C_out
* co3
;
180 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
181 //Xb12_out -= Yb12C_out * si1;
182 p0
= Yb12C_out
* si1
;
183 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
184 //Yb12_out += Xb12C_out * si1;
185 p1
= Xb12C_out
* si1
;
186 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
187 //Xc12_out -= Yc12C_out * si2;
188 p2
= Yc12C_out
* si2
;
189 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
190 //Yc12_out += Xc12C_out * si2;
191 p3
= Xc12C_out
* si2
;
192 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
193 //Xd12_out -= Yd12C_out * si3;
194 p4
= Yd12C_out
* si3
;
195 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
196 //Yd12_out += Xd12C_out * si3;
197 p5
= Xd12C_out
* si3
;
206 /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
207 pSrc
[2u * i1
] = Xc12_out
;
209 /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
210 pSrc
[(2u * i1
) + 1u] = Yc12_out
;
212 /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
213 pSrc
[2u * i2
] = Xb12_out
;
215 /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
216 pSrc
[(2u * i2
) + 1u] = Yb12_out
;
218 /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
219 pSrc
[2u * i3
] = Xd12_out
;
221 /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
222 pSrc
[(2u * i3
) + 1u] = Yd12_out
;
224 /* Twiddle coefficients index modifier */
225 ia1
+= twidCoefModifier
;
227 /* Updating input index */
233 twidCoefModifier
<<= 2u;
235 /* Calculation of second stage to excluding last stage */
236 for (k
= fftLen
>> 2u; k
> 4u; k
>>= 2u)
238 /* Initializations for the first stage */
243 /* Calculation of first stage */
247 /* index calculation for the coefficients */
250 co1
= pCoef
[ia1
* 2u];
251 si1
= pCoef
[(ia1
* 2u) + 1u];
252 co2
= pCoef
[ia2
* 2u];
253 si2
= pCoef
[(ia2
* 2u) + 1u];
254 co3
= pCoef
[ia3
* 2u];
255 si3
= pCoef
[(ia3
* 2u) + 1u];
257 /* Twiddle coefficients index modifier */
258 ia1
+= twidCoefModifier
;
263 /* index calculation for the input as, */
264 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
269 xaIn
= pSrc
[(2u * i0
)];
270 yaIn
= pSrc
[(2u * i0
) + 1u];
272 xbIn
= pSrc
[(2u * i1
)];
273 ybIn
= pSrc
[(2u * i1
) + 1u];
275 xcIn
= pSrc
[(2u * i2
)];
276 ycIn
= pSrc
[(2u * i2
) + 1u];
278 xdIn
= pSrc
[(2u * i3
)];
279 ydIn
= pSrc
[(2u * i3
) + 1u];
282 Xaminusc
= xaIn
- xcIn
;
284 Xbminusd
= xbIn
- xdIn
;
286 Yaminusc
= yaIn
- ycIn
;
288 Ybminusd
= ybIn
- ydIn
;
291 Xaplusc
= xaIn
+ xcIn
;
293 Xbplusd
= xbIn
+ xdIn
;
295 Yaplusc
= yaIn
+ ycIn
;
297 Ybplusd
= ybIn
+ ydIn
;
299 /* (xa - xc) + (yb - yd) */
300 Xb12C_out
= (Xaminusc
+ Ybminusd
);
301 /* (ya - yc) - (xb - xd) */
302 Yb12C_out
= (Yaminusc
- Xbminusd
);
303 /* xa + xc -(xb + xd) */
304 Xc12C_out
= (Xaplusc
- Xbplusd
);
305 /* (ya + yc) - (yb + yd) */
306 Yc12C_out
= (Yaplusc
- Ybplusd
);
307 /* (xa - xc) - (yb - yd) */
308 Xd12C_out
= (Xaminusc
- Ybminusd
);
309 /* (ya - yc) + (xb - xd) */
310 Yd12C_out
= (Xbminusd
+ Yaminusc
);
312 pSrc
[(2u * i0
)] = Xaplusc
+ Xbplusd
;
313 pSrc
[(2u * i0
) + 1u] = Yaplusc
+ Ybplusd
;
315 Xb12_out
= Xb12C_out
* co1
;
316 Yb12_out
= Yb12C_out
* co1
;
317 Xc12_out
= Xc12C_out
* co2
;
318 Yc12_out
= Yc12C_out
* co2
;
319 Xd12_out
= Xd12C_out
* co3
;
320 Yd12_out
= Yd12C_out
* co3
;
322 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
323 //Xb12_out -= Yb12C_out * si1;
324 p0
= Yb12C_out
* si1
;
325 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
326 //Yb12_out += Xb12C_out * si1;
327 p1
= Xb12C_out
* si1
;
328 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
329 //Xc12_out -= Yc12C_out * si2;
330 p2
= Yc12C_out
* si2
;
331 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
332 //Yc12_out += Xc12C_out * si2;
333 p3
= Xc12C_out
* si2
;
334 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
335 //Xd12_out -= Yd12C_out * si3;
336 p4
= Yd12C_out
* si3
;
337 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
338 //Yd12_out += Xd12C_out * si3;
339 p5
= Xd12C_out
* si3
;
348 /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
349 pSrc
[2u * i1
] = Xc12_out
;
351 /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
352 pSrc
[(2u * i1
) + 1u] = Yc12_out
;
354 /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
355 pSrc
[2u * i2
] = Xb12_out
;
357 /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
358 pSrc
[(2u * i2
) + 1u] = Yb12_out
;
360 /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
361 pSrc
[2u * i3
] = Xd12_out
;
363 /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
364 pSrc
[(2u * i3
) + 1u] = Yd12_out
;
367 } while(i0
< fftLen
);
369 } while(j
<= (n2
- 1u));
370 twidCoefModifier
<<= 2u;
376 /* Calculations of last stage */
389 Xaplusc
= xaIn
+ xcIn
;
392 Xaminusc
= xaIn
- xcIn
;
395 Yaplusc
= yaIn
+ ycIn
;
398 Yaminusc
= yaIn
- ycIn
;
401 Xbplusd
= xbIn
+ xdIn
;
404 Ybplusd
= ybIn
+ ydIn
;
407 Xbminusd
= xbIn
- xdIn
;
410 Ybminusd
= ybIn
- ydIn
;
412 /* xa' = xa + xb + xc + xd */
413 a0
= (Xaplusc
+ Xbplusd
);
414 /* ya' = ya + yb + yc + yd */
415 a1
= (Yaplusc
+ Ybplusd
);
416 /* xc' = (xa-xb+xc-xd) */
417 a2
= (Xaplusc
- Xbplusd
);
418 /* yc' = (ya-yb+yc-yd) */
419 a3
= (Yaplusc
- Ybplusd
);
420 /* xb' = (xa+yb-xc-yd) */
421 a4
= (Xaminusc
+ Ybminusd
);
422 /* yb' = (ya-xb-yc+xd) */
423 a5
= (Yaminusc
- Xbminusd
);
424 /* xd' = (xa-yb-xc+yd)) */
425 a6
= (Xaminusc
- Ybminusd
);
426 /* yd' = (ya+xb-yc-xd) */
427 a7
= (Xbminusd
+ Yaminusc
);
438 /* increment pointer by 8 */
444 float32_t t1
, t2
, r1
, r2
, s1
, s2
;
446 /* Run the below code for Cortex-M0 */
448 /* Initializations for the fft calculation */
451 for (k
= fftLen
; k
> 1u; k
>>= 2u)
453 /* Initializations for the fft calculation */
458 /* FFT Calculation */
462 /* index calculation for the coefficients */
465 co1
= pCoef
[ia1
* 2u];
466 si1
= pCoef
[(ia1
* 2u) + 1u];
467 co2
= pCoef
[ia2
* 2u];
468 si2
= pCoef
[(ia2
* 2u) + 1u];
469 co3
= pCoef
[ia3
* 2u];
470 si3
= pCoef
[(ia3
* 2u) + 1u];
472 /* Twiddle coefficients index modifier */
473 ia1
= ia1
+ twidCoefModifier
;
478 /* index calculation for the input as, */
479 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
485 r1
= pSrc
[(2u * i0
)] + pSrc
[(2u * i2
)];
488 r2
= pSrc
[(2u * i0
)] - pSrc
[(2u * i2
)];
491 s1
= pSrc
[(2u * i0
) + 1u] + pSrc
[(2u * i2
) + 1u];
494 s2
= pSrc
[(2u * i0
) + 1u] - pSrc
[(2u * i2
) + 1u];
497 t1
= pSrc
[2u * i1
] + pSrc
[2u * i3
];
499 /* xa' = xa + xb + xc + xd */
500 pSrc
[2u * i0
] = r1
+ t1
;
502 /* xa + xc -(xb + xd) */
506 t2
= pSrc
[(2u * i1
) + 1u] + pSrc
[(2u * i3
) + 1u];
508 /* ya' = ya + yb + yc + yd */
509 pSrc
[(2u * i0
) + 1u] = s1
+ t2
;
511 /* (ya + yc) - (yb + yd) */
515 t1
= pSrc
[(2u * i1
) + 1u] - pSrc
[(2u * i3
) + 1u];
518 t2
= pSrc
[2u * i1
] - pSrc
[2u * i3
];
520 /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
521 pSrc
[2u * i1
] = (r1
* co2
) + (s1
* si2
);
523 /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
524 pSrc
[(2u * i1
) + 1u] = (s1
* co2
) - (r1
* si2
);
526 /* (xa - xc) + (yb - yd) */
529 /* (xa - xc) - (yb - yd) */
532 /* (ya - yc) - (xb - xd) */
535 /* (ya - yc) + (xb - xd) */
538 /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
539 pSrc
[2u * i2
] = (r1
* co1
) + (s1
* si1
);
541 /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
542 pSrc
[(2u * i2
) + 1u] = (s1
* co1
) - (r1
* si1
);
544 /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
545 pSrc
[2u * i3
] = (r2
* co3
) + (s2
* si3
);
547 /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
548 pSrc
[(2u * i3
) + 1u] = (s2
* co3
) - (r2
* si3
);
551 } while( i0
< fftLen
);
553 } while(j
<= (n2
- 1u));
554 twidCoefModifier
<<= 2u;
557 #endif /* #ifndef ARM_MATH_CM0_FAMILY_FAMILY */
562 * @brief Core function for the floating-point CIFFT butterfly process.
563 * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
564 * @param[in] fftLen length of the FFT.
565 * @param[in] *pCoef points to twiddle coefficient buffer.
566 * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
567 * @param[in] onebyfftLen value of 1/fftLen.
571 void arm_radix4_butterfly_inverse_f32(
575 uint16_t twidCoefModifier
,
576 float32_t onebyfftLen
)
578 float32_t co1
, co2
, co3
, si1
, si2
, si3
;
579 uint32_t ia1
, ia2
, ia3
;
580 uint32_t i0
, i1
, i2
, i3
;
581 uint32_t n1
, n2
, j
, k
;
583 #ifndef ARM_MATH_CM0_FAMILY_FAMILY
585 float32_t xaIn
, yaIn
, xbIn
, ybIn
, xcIn
, ycIn
, xdIn
, ydIn
;
586 float32_t Xaplusc
, Xbplusd
, Yaplusc
, Ybplusd
, Xaminusc
, Xbminusd
, Yaminusc
,
588 float32_t Xb12C_out
, Yb12C_out
, Xc12C_out
, Yc12C_out
, Xd12C_out
, Yd12C_out
;
589 float32_t Xb12_out
, Yb12_out
, Xc12_out
, Yc12_out
, Xd12_out
, Yd12_out
;
591 float32_t p0
,p1
,p2
,p3
,p4
,p5
,p6
,p7
;
592 float32_t a0
,a1
,a2
,a3
,a4
,a5
,a6
,a7
;
595 /* Initializations for the first stage */
606 /* Calculation of first stage */
609 /* index calculation for the input as, */
610 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
615 /* Butterfly implementation */
616 xaIn
= pSrc
[(2u * i0
)];
617 yaIn
= pSrc
[(2u * i0
) + 1u];
619 xcIn
= pSrc
[(2u * i2
)];
620 ycIn
= pSrc
[(2u * i2
) + 1u];
622 xbIn
= pSrc
[(2u * i1
)];
623 ybIn
= pSrc
[(2u * i1
) + 1u];
625 xdIn
= pSrc
[(2u * i3
)];
626 ydIn
= pSrc
[(2u * i3
) + 1u];
629 Xaplusc
= xaIn
+ xcIn
;
631 Xbplusd
= xbIn
+ xdIn
;
633 Yaplusc
= yaIn
+ ycIn
;
635 Ybplusd
= ybIn
+ ydIn
;
637 /* index calculation for the coefficients */
639 co2
= pCoef
[ia2
* 2u];
640 si2
= pCoef
[(ia2
* 2u) + 1u];
643 Xaminusc
= xaIn
- xcIn
;
645 Xbminusd
= xbIn
- xdIn
;
647 Yaminusc
= yaIn
- ycIn
;
649 Ybminusd
= ybIn
- ydIn
;
651 /* xa' = xa + xb + xc + xd */
652 pSrc
[(2u * i0
)] = Xaplusc
+ Xbplusd
;
654 /* ya' = ya + yb + yc + yd */
655 pSrc
[(2u * i0
) + 1u] = Yaplusc
+ Ybplusd
;
657 /* (xa - xc) - (yb - yd) */
658 Xb12C_out
= (Xaminusc
- Ybminusd
);
659 /* (ya - yc) + (xb - xd) */
660 Yb12C_out
= (Yaminusc
+ Xbminusd
);
661 /* (xa + xc) - (xb + xd) */
662 Xc12C_out
= (Xaplusc
- Xbplusd
);
663 /* (ya + yc) - (yb + yd) */
664 Yc12C_out
= (Yaplusc
- Ybplusd
);
665 /* (xa - xc) + (yb - yd) */
666 Xd12C_out
= (Xaminusc
+ Ybminusd
);
667 /* (ya - yc) - (xb - xd) */
668 Yd12C_out
= (Yaminusc
- Xbminusd
);
670 co1
= pCoef
[ia1
* 2u];
671 si1
= pCoef
[(ia1
* 2u) + 1u];
673 /* index calculation for the coefficients */
675 co3
= pCoef
[ia3
* 2u];
676 si3
= pCoef
[(ia3
* 2u) + 1u];
678 Xb12_out
= Xb12C_out
* co1
;
679 Yb12_out
= Yb12C_out
* co1
;
680 Xc12_out
= Xc12C_out
* co2
;
681 Yc12_out
= Yc12C_out
* co2
;
682 Xd12_out
= Xd12C_out
* co3
;
683 Yd12_out
= Yd12C_out
* co3
;
685 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
686 //Xb12_out -= Yb12C_out * si1;
687 p0
= Yb12C_out
* si1
;
688 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
689 //Yb12_out += Xb12C_out * si1;
690 p1
= Xb12C_out
* si1
;
691 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
692 //Xc12_out -= Yc12C_out * si2;
693 p2
= Yc12C_out
* si2
;
694 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
695 //Yc12_out += Xc12C_out * si2;
696 p3
= Xc12C_out
* si2
;
697 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
698 //Xd12_out -= Yd12C_out * si3;
699 p4
= Yd12C_out
* si3
;
700 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
701 //Yd12_out += Xd12C_out * si3;
702 p5
= Xd12C_out
* si3
;
711 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
712 pSrc
[2u * i1
] = Xc12_out
;
714 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
715 pSrc
[(2u * i1
) + 1u] = Yc12_out
;
717 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
718 pSrc
[2u * i2
] = Xb12_out
;
720 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
721 pSrc
[(2u * i2
) + 1u] = Yb12_out
;
723 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
724 pSrc
[2u * i3
] = Xd12_out
;
726 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
727 pSrc
[(2u * i3
) + 1u] = Yd12_out
;
729 /* Twiddle coefficients index modifier */
730 ia1
= ia1
+ twidCoefModifier
;
732 /* Updating input index */
737 twidCoefModifier
<<= 2u;
739 /* Calculation of second stage to excluding last stage */
740 for (k
= fftLen
>> 2u; k
> 4u; k
>>= 2u)
742 /* Initializations for the first stage */
747 /* Calculation of first stage */
751 /* index calculation for the coefficients */
754 co1
= pCoef
[ia1
* 2u];
755 si1
= pCoef
[(ia1
* 2u) + 1u];
756 co2
= pCoef
[ia2
* 2u];
757 si2
= pCoef
[(ia2
* 2u) + 1u];
758 co3
= pCoef
[ia3
* 2u];
759 si3
= pCoef
[(ia3
* 2u) + 1u];
761 /* Twiddle coefficients index modifier */
762 ia1
= ia1
+ twidCoefModifier
;
767 /* index calculation for the input as, */
768 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
773 xaIn
= pSrc
[(2u * i0
)];
774 yaIn
= pSrc
[(2u * i0
) + 1u];
776 xbIn
= pSrc
[(2u * i1
)];
777 ybIn
= pSrc
[(2u * i1
) + 1u];
779 xcIn
= pSrc
[(2u * i2
)];
780 ycIn
= pSrc
[(2u * i2
) + 1u];
782 xdIn
= pSrc
[(2u * i3
)];
783 ydIn
= pSrc
[(2u * i3
) + 1u];
786 Xaminusc
= xaIn
- xcIn
;
788 Xbminusd
= xbIn
- xdIn
;
790 Yaminusc
= yaIn
- ycIn
;
792 Ybminusd
= ybIn
- ydIn
;
795 Xaplusc
= xaIn
+ xcIn
;
797 Xbplusd
= xbIn
+ xdIn
;
799 Yaplusc
= yaIn
+ ycIn
;
801 Ybplusd
= ybIn
+ ydIn
;
803 /* (xa - xc) - (yb - yd) */
804 Xb12C_out
= (Xaminusc
- Ybminusd
);
805 /* (ya - yc) + (xb - xd) */
806 Yb12C_out
= (Yaminusc
+ Xbminusd
);
807 /* xa + xc -(xb + xd) */
808 Xc12C_out
= (Xaplusc
- Xbplusd
);
809 /* (ya + yc) - (yb + yd) */
810 Yc12C_out
= (Yaplusc
- Ybplusd
);
811 /* (xa - xc) + (yb - yd) */
812 Xd12C_out
= (Xaminusc
+ Ybminusd
);
813 /* (ya - yc) - (xb - xd) */
814 Yd12C_out
= (Yaminusc
- Xbminusd
);
816 pSrc
[(2u * i0
)] = Xaplusc
+ Xbplusd
;
817 pSrc
[(2u * i0
) + 1u] = Yaplusc
+ Ybplusd
;
819 Xb12_out
= Xb12C_out
* co1
;
820 Yb12_out
= Yb12C_out
* co1
;
821 Xc12_out
= Xc12C_out
* co2
;
822 Yc12_out
= Yc12C_out
* co2
;
823 Xd12_out
= Xd12C_out
* co3
;
824 Yd12_out
= Yd12C_out
* co3
;
826 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
827 //Xb12_out -= Yb12C_out * si1;
828 p0
= Yb12C_out
* si1
;
829 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
830 //Yb12_out += Xb12C_out * si1;
831 p1
= Xb12C_out
* si1
;
832 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
833 //Xc12_out -= Yc12C_out * si2;
834 p2
= Yc12C_out
* si2
;
835 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
836 //Yc12_out += Xc12C_out * si2;
837 p3
= Xc12C_out
* si2
;
838 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
839 //Xd12_out -= Yd12C_out * si3;
840 p4
= Yd12C_out
* si3
;
841 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
842 //Yd12_out += Xd12C_out * si3;
843 p5
= Xd12C_out
* si3
;
852 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
853 pSrc
[2u * i1
] = Xc12_out
;
855 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
856 pSrc
[(2u * i1
) + 1u] = Yc12_out
;
858 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
859 pSrc
[2u * i2
] = Xb12_out
;
861 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
862 pSrc
[(2u * i2
) + 1u] = Yb12_out
;
864 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
865 pSrc
[2u * i3
] = Xd12_out
;
867 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
868 pSrc
[(2u * i3
) + 1u] = Yd12_out
;
871 } while(i0
< fftLen
);
873 } while(j
<= (n2
- 1u));
874 twidCoefModifier
<<= 2u;
876 /* Initializations of last stage */
881 /* Calculations of last stage */
893 /* Butterfly implementation */
895 Xaplusc
= xaIn
+ xcIn
;
898 Xaminusc
= xaIn
- xcIn
;
901 Yaplusc
= yaIn
+ ycIn
;
904 Yaminusc
= yaIn
- ycIn
;
907 Xbplusd
= xbIn
+ xdIn
;
910 Ybplusd
= ybIn
+ ydIn
;
913 Xbminusd
= xbIn
- xdIn
;
916 Ybminusd
= ybIn
- ydIn
;
918 /* xa' = (xa+xb+xc+xd) * onebyfftLen */
919 a0
= (Xaplusc
+ Xbplusd
);
920 /* ya' = (ya+yb+yc+yd) * onebyfftLen */
921 a1
= (Yaplusc
+ Ybplusd
);
922 /* xc' = (xa-xb+xc-xd) * onebyfftLen */
923 a2
= (Xaplusc
- Xbplusd
);
924 /* yc' = (ya-yb+yc-yd) * onebyfftLen */
925 a3
= (Yaplusc
- Ybplusd
);
926 /* xb' = (xa-yb-xc+yd) * onebyfftLen */
927 a4
= (Xaminusc
- Ybminusd
);
928 /* yb' = (ya+xb-yc-xd) * onebyfftLen */
929 a5
= (Yaminusc
+ Xbminusd
);
930 /* xd' = (xa-yb-xc+yd) * onebyfftLen */
931 a6
= (Xaminusc
+ Ybminusd
);
932 /* yd' = (ya-xb-yc+xd) * onebyfftLen */
933 a7
= (Yaminusc
- Xbminusd
);
935 p0
= a0
* onebyfftLen
;
936 p1
= a1
* onebyfftLen
;
937 p2
= a2
* onebyfftLen
;
938 p3
= a3
* onebyfftLen
;
939 p4
= a4
* onebyfftLen
;
940 p5
= a5
* onebyfftLen
;
941 p6
= a6
* onebyfftLen
;
942 p7
= a7
* onebyfftLen
;
944 /* xa' = (xa+xb+xc+xd) * onebyfftLen */
946 /* ya' = (ya+yb+yc+yd) * onebyfftLen */
948 /* xc' = (xa-xb+xc-xd) * onebyfftLen */
950 /* yc' = (ya-yb+yc-yd) * onebyfftLen */
952 /* xb' = (xa-yb-xc+yd) * onebyfftLen */
954 /* yb' = (ya+xb-yc-xd) * onebyfftLen */
956 /* xd' = (xa-yb-xc+yd) * onebyfftLen */
958 /* yd' = (ya-xb-yc+xd) * onebyfftLen */
961 /* increment source pointer by 8 for next calculations */
968 float32_t t1
, t2
, r1
, r2
, s1
, s2
;
970 /* Run the below code for Cortex-M0 */
972 /* Initializations for the first stage */
976 /* Calculation of first stage */
977 for (k
= fftLen
; k
> 4u; k
>>= 2u)
979 /* Initializations for the first stage */
984 /* Calculation of first stage */
988 /* index calculation for the coefficients */
991 co1
= pCoef
[ia1
* 2u];
992 si1
= pCoef
[(ia1
* 2u) + 1u];
993 co2
= pCoef
[ia2
* 2u];
994 si2
= pCoef
[(ia2
* 2u) + 1u];
995 co3
= pCoef
[ia3
* 2u];
996 si3
= pCoef
[(ia3
* 2u) + 1u];
998 /* Twiddle coefficients index modifier */
999 ia1
= ia1
+ twidCoefModifier
;
1004 /* index calculation for the input as, */
1005 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
1011 r1
= pSrc
[(2u * i0
)] + pSrc
[(2u * i2
)];
1014 r2
= pSrc
[(2u * i0
)] - pSrc
[(2u * i2
)];
1017 s1
= pSrc
[(2u * i0
) + 1u] + pSrc
[(2u * i2
) + 1u];
1020 s2
= pSrc
[(2u * i0
) + 1u] - pSrc
[(2u * i2
) + 1u];
1023 t1
= pSrc
[2u * i1
] + pSrc
[2u * i3
];
1025 /* xa' = xa + xb + xc + xd */
1026 pSrc
[2u * i0
] = r1
+ t1
;
1028 /* xa + xc -(xb + xd) */
1032 t2
= pSrc
[(2u * i1
) + 1u] + pSrc
[(2u * i3
) + 1u];
1034 /* ya' = ya + yb + yc + yd */
1035 pSrc
[(2u * i0
) + 1u] = s1
+ t2
;
1037 /* (ya + yc) - (yb + yd) */
1041 t1
= pSrc
[(2u * i1
) + 1u] - pSrc
[(2u * i3
) + 1u];
1044 t2
= pSrc
[2u * i1
] - pSrc
[2u * i3
];
1046 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
1047 pSrc
[2u * i1
] = (r1
* co2
) - (s1
* si2
);
1049 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
1050 pSrc
[(2u * i1
) + 1u] = (s1
* co2
) + (r1
* si2
);
1052 /* (xa - xc) - (yb - yd) */
1055 /* (xa - xc) + (yb - yd) */
1058 /* (ya - yc) + (xb - xd) */
1061 /* (ya - yc) - (xb - xd) */
1064 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
1065 pSrc
[2u * i2
] = (r1
* co1
) - (s1
* si1
);
1067 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
1068 pSrc
[(2u * i2
) + 1u] = (s1
* co1
) + (r1
* si1
);
1070 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
1071 pSrc
[2u * i3
] = (r2
* co3
) - (s2
* si3
);
1073 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
1074 pSrc
[(2u * i3
) + 1u] = (s2
* co3
) + (r2
* si3
);
1077 } while( i0
< fftLen
);
1079 } while(j
<= (n2
- 1u));
1080 twidCoefModifier
<<= 2u;
1082 /* Initializations of last stage */
1086 /* Calculations of last stage */
1087 for (i0
= 0u; i0
<= (fftLen
- n1
); i0
+= n1
)
1089 /* index calculation for the input as, */
1090 /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
1095 /* Butterfly implementation */
1097 r1
= pSrc
[2u * i0
] + pSrc
[2u * i2
];
1100 r2
= pSrc
[2u * i0
] - pSrc
[2u * i2
];
1103 s1
= pSrc
[(2u * i0
) + 1u] + pSrc
[(2u * i2
) + 1u];
1106 s2
= pSrc
[(2u * i0
) + 1u] - pSrc
[(2u * i2
) + 1u];
1109 t1
= pSrc
[2u * i1
] + pSrc
[2u * i3
];
1111 /* xa' = xa + xb + xc + xd */
1112 pSrc
[2u * i0
] = (r1
+ t1
) * onebyfftLen
;
1114 /* (xa + xb) - (xc + xd) */
1118 t2
= pSrc
[(2u * i1
) + 1u] + pSrc
[(2u * i3
) + 1u];
1120 /* ya' = ya + yb + yc + yd */
1121 pSrc
[(2u * i0
) + 1u] = (s1
+ t2
) * onebyfftLen
;
1123 /* (ya + yc) - (yb + yd) */
1127 t1
= pSrc
[(2u * i1
) + 1u] - pSrc
[(2u * i3
) + 1u];
1130 t2
= pSrc
[2u * i1
] - pSrc
[2u * i3
];
1132 /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
1133 pSrc
[2u * i1
] = r1
* onebyfftLen
;
1135 /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
1136 pSrc
[(2u * i1
) + 1u] = s1
* onebyfftLen
;
1138 /* (xa - xc) - (yb-yd) */
1141 /* (xa - xc) + (yb-yd) */
1144 /* (ya - yc) + (xb-xd) */
1147 /* (ya - yc) - (xb-xd) */
1150 /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
1151 pSrc
[2u * i2
] = r1
* onebyfftLen
;
1153 /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
1154 pSrc
[(2u * i2
) + 1u] = s1
* onebyfftLen
;
1156 /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
1157 pSrc
[2u * i3
] = r2
* onebyfftLen
;
1159 /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
1160 pSrc
[(2u * i3
) + 1u] = s2
* onebyfftLen
;
1163 #endif /* #ifndef ARM_MATH_CM0_FAMILY_FAMILY */
1167 * @addtogroup ComplexFFT
1173 * @brief Processing function for the floating-point Radix-4 CFFT/CIFFT.
1174 * @deprecated Do not use this function. It has been superceded by \ref arm_cfft_f32 and will be removed
1176 * @param[in] *S points to an instance of the floating-point Radix-4 CFFT/CIFFT structure.
1177 * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
1181 void arm_cfft_radix4_f32(
1182 const arm_cfft_radix4_instance_f32
* S
,
1186 if(S
->ifftFlag
== 1u)
1188 /* Complex IFFT radix-4 */
1189 arm_radix4_butterfly_inverse_f32(pSrc
, S
->fftLen
, S
->pTwiddle
,
1190 S
->twidCoefModifier
, S
->onebyfftLen
);
1194 /* Complex FFT radix-4 */
1195 arm_radix4_butterfly_f32(pSrc
, S
->fftLen
, S
->pTwiddle
,
1196 S
->twidCoefModifier
);
1199 if(S
->bitReverseFlag
== 1u)
1202 arm_bitreversal_f32(pSrc
, S
->fftLen
, S
->bitRevFactor
, S
->pBitRevTable
);
1208 * @} end of ComplexFFT group