/ Drivers / CMSIS / DSP / Source / TransformFunctions / arm_cfft_radix2_f32.c
arm_cfft_radix2_f32.c
  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  
 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  
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  
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  }