• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        arm_cfft_radix2_f32.c
4  * Description:  Radix-2 Decimation in Frequency CFFT & CIFFT Floating point processing function
5  *
6  * $Date:        23 April 2021
7  * $Revision:    V1.9.0
8  *
9  * Target Processor: Cortex-M and Cortex-A cores
10  * -------------------------------------------------------------------- */
11 /*
12  * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
13  *
14  * SPDX-License-Identifier: Apache-2.0
15  *
16  * Licensed under the Apache License, Version 2.0 (the License); you may
17  * not use this file except in compliance with the License.
18  * You may obtain a copy of the License at
19  *
20  * www.apache.org/licenses/LICENSE-2.0
21  *
22  * Unless required by applicable law or agreed to in writing, software
23  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25  * See the License for the specific language governing permissions and
26  * limitations under the License.
27  */
28 
29 #include "dsp/transform_functions.h"
30 
31 void arm_radix2_butterfly_f32(
32         float32_t * pSrc,
33         uint32_t fftLen,
34   const float32_t * pCoef,
35         uint16_t twidCoefModifier);
36 
37 void arm_radix2_butterfly_inverse_f32(
38         float32_t * pSrc,
39         uint32_t fftLen,
40   const float32_t * pCoef,
41         uint16_t twidCoefModifier,
42         float32_t onebyfftLen);
43 
44 extern void arm_bitreversal_f32(
45         float32_t * pSrc,
46         uint16_t fftSize,
47         uint16_t bitRevFactor,
48   const uint16_t * pBitRevTab);
49 
50 /**
51   @ingroup groupTransforms
52  */
53 
54 /**
55   @addtogroup ComplexFFT
56   @{
57  */
58 
59 /**
60   @brief         Radix-2 CFFT/CIFFT.
61   @deprecated    Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed in the future
62   @param[in]     S    points to an instance of the floating-point Radix-2 CFFT/CIFFT structure
63   @param[in,out] pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place
64   @return        none
65  */
66 
arm_cfft_radix2_f32(const arm_cfft_radix2_instance_f32 * S,float32_t * pSrc)67 void arm_cfft_radix2_f32(
68 const arm_cfft_radix2_instance_f32 * S,
69       float32_t * pSrc)
70 {
71 
72    if (S->ifftFlag == 1U)
73    {
74       /* Complex IFFT radix-2 */
75       arm_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
76       S->twidCoefModifier, S->onebyfftLen);
77    }
78    else
79    {
80       /* Complex FFT radix-2 */
81       arm_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
82       S->twidCoefModifier);
83    }
84 
85    if (S->bitReverseFlag == 1U)
86    {
87       /* Bit Reversal */
88       arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
89    }
90 
91 }
92 
93 
94 /**
95   @} end of ComplexFFT group
96  */
97 
98 
99 
100 /* ----------------------------------------------------------------------
101  ** Internal helper function used by the FFTs
102  ** ------------------------------------------------------------------- */
103 
104 /**
105   brief  Core function for the floating-point CFFT butterfly process.
106   param[in,out] pSrc             points to in-place buffer of floating-point data type
107   param[in]     fftLen           length of the FFT
108   param[in]     pCoef            points to twiddle coefficient buffer
109   param[in]     twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table
110   return        none
111  */
112 
arm_radix2_butterfly_f32(float32_t * pSrc,uint32_t fftLen,const float32_t * pCoef,uint16_t twidCoefModifier)113 void arm_radix2_butterfly_f32(
114         float32_t * pSrc,
115         uint32_t fftLen,
116   const float32_t * pCoef,
117         uint16_t twidCoefModifier)
118 {
119 
120         uint32_t i, j, k, l;
121         uint32_t n1, n2, ia;
122         float32_t xt, yt, cosVal, sinVal;
123         float32_t p0, p1, p2, p3;
124         float32_t a0, a1;
125 
126 #if defined (ARM_MATH_DSP)
127 
128    /*  Initializations for the first stage */
129    n2 = fftLen >> 1;
130    ia = 0;
131    i = 0;
132 
133    // loop for groups
134    for (k = n2; k > 0; k--)
135    {
136       cosVal = pCoef[ia * 2];
137       sinVal = pCoef[(ia * 2) + 1];
138 
139       /*  Twiddle coefficients index modifier */
140       ia += twidCoefModifier;
141 
142       /*  index calculation for the input as, */
143       /*  pSrc[i + 0], pSrc[i + fftLen/1] */
144       l = i + n2;
145 
146       /*  Butterfly implementation */
147       a0 = pSrc[2 * i] + pSrc[2 * l];
148       xt = pSrc[2 * i] - pSrc[2 * l];
149 
150       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
151       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
152 
153       p0 = xt * cosVal;
154       p1 = yt * sinVal;
155       p2 = yt * cosVal;
156       p3 = xt * sinVal;
157 
158       pSrc[2 * i]     = a0;
159       pSrc[2 * i + 1] = a1;
160 
161       pSrc[2 * l]     = p0 + p1;
162       pSrc[2 * l + 1] = p2 - p3;
163 
164       i++;
165    }                             // groups loop end
166 
167    twidCoefModifier <<= 1U;
168 
169    // loop for stage
170    for (k = n2; k > 2; k = k >> 1)
171    {
172       n1 = n2;
173       n2 = n2 >> 1;
174       ia = 0;
175 
176       // loop for groups
177       j = 0;
178       do
179       {
180          cosVal = pCoef[ia * 2];
181          sinVal = pCoef[(ia * 2) + 1];
182          ia += twidCoefModifier;
183 
184          // loop for butterfly
185          i = j;
186          do
187          {
188             l = i + n2;
189             a0 = pSrc[2 * i] + pSrc[2 * l];
190             xt = pSrc[2 * i] - pSrc[2 * l];
191 
192             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
193             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
194 
195             p0 = xt * cosVal;
196             p1 = yt * sinVal;
197             p2 = yt * cosVal;
198             p3 = xt * sinVal;
199 
200             pSrc[2 * i] = a0;
201             pSrc[2 * i + 1] = a1;
202 
203             pSrc[2 * l]     = p0 + p1;
204             pSrc[2 * l + 1] = p2 - p3;
205 
206             i += n1;
207          } while ( i < fftLen );                        // butterfly loop end
208          j++;
209       } while ( j < n2);                          // groups loop end
210       twidCoefModifier <<= 1U;
211    }                             // stages loop end
212 
213    // loop for butterfly
214    for (i = 0; i < fftLen; i += 2)
215    {
216       a0 = pSrc[2 * i] + pSrc[2 * i + 2];
217       xt = pSrc[2 * i] - pSrc[2 * i + 2];
218 
219       yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
220       a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
221 
222       pSrc[2 * i] = a0;
223       pSrc[2 * i + 1] = a1;
224       pSrc[2 * i + 2] = xt;
225       pSrc[2 * i + 3] = yt;
226    }                             // groups loop end
227 
228 #else /* #if defined (ARM_MATH_DSP) */
229 
230    n2 = fftLen;
231 
232    // loop for stage
233    for (k = fftLen; k > 1; k = k >> 1)
234    {
235       n1 = n2;
236       n2 = n2 >> 1;
237       ia = 0;
238 
239       // loop for groups
240       j = 0;
241       do
242       {
243          cosVal = pCoef[ia * 2];
244          sinVal = pCoef[(ia * 2) + 1];
245          ia += twidCoefModifier;
246 
247          // loop for butterfly
248          i = j;
249          do
250          {
251             l = i + n2;
252             a0 = pSrc[2 * i] + pSrc[2 * l];
253             xt = pSrc[2 * i] - pSrc[2 * l];
254 
255             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
256             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
257 
258             p0 = xt * cosVal;
259             p1 = yt * sinVal;
260             p2 = yt * cosVal;
261             p3 = xt * sinVal;
262 
263             pSrc[2 * i] = a0;
264             pSrc[2 * i + 1] = a1;
265 
266             pSrc[2 * l]     = p0 + p1;
267             pSrc[2 * l + 1] = p2 - p3;
268 
269             i += n1;
270          } while (i < fftLen);
271          j++;
272       } while (j < n2);
273       twidCoefModifier <<= 1U;
274    }
275 
276 #endif /* #if defined (ARM_MATH_DSP) */
277 
278 }
279 
280 
arm_radix2_butterfly_inverse_f32(float32_t * pSrc,uint32_t fftLen,const float32_t * pCoef,uint16_t twidCoefModifier,float32_t onebyfftLen)281 void arm_radix2_butterfly_inverse_f32(
282         float32_t * pSrc,
283         uint32_t fftLen,
284   const float32_t * pCoef,
285         uint16_t twidCoefModifier,
286         float32_t onebyfftLen)
287 {
288 
289         uint32_t i, j, k, l;
290         uint32_t n1, n2, ia;
291         float32_t xt, yt, cosVal, sinVal;
292         float32_t p0, p1, p2, p3;
293         float32_t a0, a1;
294 
295 #if defined (ARM_MATH_DSP)
296 
297    n2 = fftLen >> 1;
298    ia = 0;
299 
300    // loop for groups
301    for (i = 0; i < n2; i++)
302    {
303       cosVal = pCoef[ia * 2];
304       sinVal = pCoef[(ia * 2) + 1];
305       ia += twidCoefModifier;
306 
307       l = i + n2;
308       a0 = pSrc[2 * i] + pSrc[2 * l];
309       xt = pSrc[2 * i] - pSrc[2 * l];
310 
311       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
312       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
313 
314       p0 = xt * cosVal;
315       p1 = yt * sinVal;
316       p2 = yt * cosVal;
317       p3 = xt * sinVal;
318 
319       pSrc[2 * i] = a0;
320       pSrc[2 * i + 1] = a1;
321 
322       pSrc[2 * l]     = p0 - p1;
323       pSrc[2 * l + 1] = p2 + p3;
324    }                             // groups loop end
325 
326    twidCoefModifier <<= 1U;
327 
328    // loop for stage
329    for (k = fftLen / 2; k > 2; k = k >> 1)
330    {
331       n1 = n2;
332       n2 = n2 >> 1;
333       ia = 0;
334 
335       // loop for groups
336       j = 0;
337       do
338       {
339          cosVal = pCoef[ia * 2];
340          sinVal = pCoef[(ia * 2) + 1];
341          ia += twidCoefModifier;
342 
343          // loop for butterfly
344          i = j;
345          do
346          {
347             l = i + n2;
348             a0 = pSrc[2 * i] + pSrc[2 * l];
349             xt = pSrc[2 * i] - pSrc[2 * l];
350 
351             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
352             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
353 
354             p0 = xt * cosVal;
355             p1 = yt * sinVal;
356             p2 = yt * cosVal;
357             p3 = xt * sinVal;
358 
359             pSrc[2 * i] = a0;
360             pSrc[2 * i + 1] = a1;
361 
362             pSrc[2 * l]     = p0 - p1;
363             pSrc[2 * l + 1] = p2 + p3;
364 
365             i += n1;
366          } while ( i < fftLen );                 // butterfly loop end
367          j++;
368       } while (j < n2);                      // groups loop end
369 
370       twidCoefModifier <<= 1U;
371    }                             // stages loop end
372 
373    // loop for butterfly
374    for (i = 0; i < fftLen; i += 2)
375    {
376       a0 = pSrc[2 * i] + pSrc[2 * i + 2];
377       xt = pSrc[2 * i] - pSrc[2 * i + 2];
378 
379       a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
380       yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
381 
382       p0 = a0 * onebyfftLen;
383       p2 = xt * onebyfftLen;
384       p1 = a1 * onebyfftLen;
385       p3 = yt * onebyfftLen;
386 
387       pSrc[2 * i] = p0;
388       pSrc[2 * i + 1] = p1;
389       pSrc[2 * i + 2] = p2;
390       pSrc[2 * i + 3] = p3;
391    }                             // butterfly loop end
392 
393 #else /* #if defined (ARM_MATH_DSP) */
394 
395    n2 = fftLen;
396 
397    // loop for stage
398    for (k = fftLen; k > 2; k = k >> 1)
399    {
400       n1 = n2;
401       n2 = n2 >> 1;
402       ia = 0;
403 
404       // loop for groups
405       j = 0;
406       do
407       {
408          cosVal = pCoef[ia * 2];
409          sinVal = pCoef[(ia * 2) + 1];
410          ia = ia + twidCoefModifier;
411 
412          // loop for butterfly
413          i = j;
414          do
415          {
416             l = i + n2;
417             a0 = pSrc[2 * i] + pSrc[2 * l];
418             xt = pSrc[2 * i] - pSrc[2 * l];
419 
420             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
421             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
422 
423             p0 = xt * cosVal;
424             p1 = yt * sinVal;
425             p2 = yt * cosVal;
426             p3 = xt * sinVal;
427 
428             pSrc[2 * i] = a0;
429             pSrc[2 * i + 1] = a1;
430 
431             pSrc[2 * l]     = p0 - p1;
432             pSrc[2 * l + 1] = p2 + p3;
433 
434             i += n1;
435          } while ( i < fftLen );                    // butterfly loop end
436          j++;
437       } while ( j < n2 );                      // groups loop end
438 
439       twidCoefModifier = twidCoefModifier << 1U;
440    }                             // stages loop end
441 
442    n1 = n2;
443    n2 = n2 >> 1;
444 
445    // loop for butterfly
446    for (i = 0; i < fftLen; i += n1)
447    {
448       l = i + n2;
449 
450       a0 = pSrc[2 * i] + pSrc[2 * l];
451       xt = pSrc[2 * i] - pSrc[2 * l];
452 
453       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
454       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
455 
456       p0 = a0 * onebyfftLen;
457       p2 = xt * onebyfftLen;
458       p1 = a1 * onebyfftLen;
459       p3 = yt * onebyfftLen;
460 
461       pSrc[2 * i] = p0;
462       pSrc[2 * l] = p2;
463 
464       pSrc[2 * i + 1] = p1;
465       pSrc[2 * l + 1] = p3;
466    }                             // butterfly loop end
467 
468 #endif /* #if defined (ARM_MATH_DSP) */
469 
470 }
471