STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
arm_cfft_radix2_f32.c
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
3 *
4 * $Date: 19. March 2015
5 * $Revision: V.1.4.5
6 *
7 * Project: CMSIS DSP Library
8 * Title: arm_cfft_radix2_f32.c
9 *
10 * Description: Radix-2 Decimation in Frequency CFFT & CIFFT Floating point processing function
11 *
12 *
13 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
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
23 * distribution.
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.
27 *
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 * -------------------------------------------------------------------- */
41 
42 #include "arm_math.h"
43 
45  float32_t * pSrc,
46  uint32_t fftLen,
47  float32_t * pCoef,
48  uint16_t twidCoefModifier);
49 
51  float32_t * pSrc,
52  uint32_t fftLen,
53  float32_t * pCoef,
54  uint16_t twidCoefModifier,
55  float32_t onebyfftLen);
56 
57 extern void arm_bitreversal_f32(
58  float32_t * pSrc,
59  uint16_t fftSize,
60  uint16_t bitRevFactor,
61  uint16_t * pBitRevTab);
62 
84 float32_t * pSrc)
85 {
86 
87  if(S->ifftFlag == 1u)
88  {
89  /* Complex IFFT radix-2 */
92  }
93  else
94  {
95  /* Complex FFT radix-2 */
97  S->twidCoefModifier);
98  }
99 
100  if(S->bitReverseFlag == 1u)
101  {
102  /* Bit Reversal */
104  }
105 
106 }
107 
108 
115 /* ----------------------------------------------------------------------
116 ** Internal helper function used by the FFTs
117 ** ------------------------------------------------------------------- */
118 
119 /*
120 * @brief Core function for the floating-point CFFT butterfly process.
121 * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
122 * @param[in] fftLen length of the FFT.
123 * @param[in] *pCoef points to the twiddle coefficient buffer.
124 * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
125 * @return none.
126 */
127 
129 float32_t * pSrc,
130 uint32_t fftLen,
131 float32_t * pCoef,
132 uint16_t twidCoefModifier)
133 {
134 
135  uint32_t i, j, k, l;
136  uint32_t n1, n2, ia;
137  float32_t xt, yt, cosVal, sinVal;
138  float32_t p0, p1, p2, p3;
139  float32_t a0, a1;
140 
141 #ifndef ARM_MATH_CM0_FAMILY
142 
143  /* Initializations for the first stage */
144  n2 = fftLen >> 1;
145  ia = 0;
146  i = 0;
147 
148  // loop for groups
149  for (k = n2; k > 0; k--)
150  {
151  cosVal = pCoef[ia * 2];
152  sinVal = pCoef[(ia * 2) + 1];
153 
154  /* Twiddle coefficients index modifier */
155  ia += twidCoefModifier;
156 
157  /* index calculation for the input as, */
158  /* pSrc[i + 0], pSrc[i + fftLen/1] */
159  l = i + n2;
160 
161  /* Butterfly implementation */
162  a0 = pSrc[2 * i] + pSrc[2 * l];
163  xt = pSrc[2 * i] - pSrc[2 * l];
164 
165  yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
166  a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
167 
168  p0 = xt * cosVal;
169  p1 = yt * sinVal;
170  p2 = yt * cosVal;
171  p3 = xt * sinVal;
172 
173  pSrc[2 * i] = a0;
174  pSrc[2 * i + 1] = a1;
175 
176  pSrc[2 * l] = p0 + p1;
177  pSrc[2 * l + 1] = p2 - p3;
178 
179  i++;
180  } // groups loop end
181 
182  twidCoefModifier <<= 1u;
183 
184  // loop for stage
185  for (k = n2; k > 2; k = k >> 1)
186  {
187  n1 = n2;
188  n2 = n2 >> 1;
189  ia = 0;
190 
191  // loop for groups
192  j = 0;
193  do
194  {
195  cosVal = pCoef[ia * 2];
196  sinVal = pCoef[(ia * 2) + 1];
197  ia += twidCoefModifier;
198 
199  // loop for butterfly
200  i = j;
201  do
202  {
203  l = i + n2;
204  a0 = pSrc[2 * i] + pSrc[2 * l];
205  xt = pSrc[2 * i] - pSrc[2 * l];
206 
207  yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
208  a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
209 
210  p0 = xt * cosVal;
211  p1 = yt * sinVal;
212  p2 = yt * cosVal;
213  p3 = xt * sinVal;
214 
215  pSrc[2 * i] = a0;
216  pSrc[2 * i + 1] = a1;
217 
218  pSrc[2 * l] = p0 + p1;
219  pSrc[2 * l + 1] = p2 - p3;
220 
221  i += n1;
222  } while( i < fftLen ); // butterfly loop end
223  j++;
224  } while( j < n2); // groups loop end
225  twidCoefModifier <<= 1u;
226  } // stages loop end
227 
228  // loop for butterfly
229  for (i = 0; i < fftLen; i += 2)
230  {
231  a0 = pSrc[2 * i] + pSrc[2 * i + 2];
232  xt = pSrc[2 * i] - pSrc[2 * i + 2];
233 
234  yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
235  a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
236 
237  pSrc[2 * i] = a0;
238  pSrc[2 * i + 1] = a1;
239  pSrc[2 * i + 2] = xt;
240  pSrc[2 * i + 3] = yt;
241  } // groups loop end
242 
243 #else
244 
245  n2 = fftLen;
246 
247  // loop for stage
248  for (k = fftLen; k > 1; k = k >> 1)
249  {
250  n1 = n2;
251  n2 = n2 >> 1;
252  ia = 0;
253 
254  // loop for groups
255  j = 0;
256  do
257  {
258  cosVal = pCoef[ia * 2];
259  sinVal = pCoef[(ia * 2) + 1];
260  ia += twidCoefModifier;
261 
262  // loop for butterfly
263  i = j;
264  do
265  {
266  l = i + n2;
267  a0 = pSrc[2 * i] + pSrc[2 * l];
268  xt = pSrc[2 * i] - pSrc[2 * l];
269 
270  yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
271  a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
272 
273  p0 = xt * cosVal;
274  p1 = yt * sinVal;
275  p2 = yt * cosVal;
276  p3 = xt * sinVal;
277 
278  pSrc[2 * i] = a0;
279  pSrc[2 * i + 1] = a1;
280 
281  pSrc[2 * l] = p0 + p1;
282  pSrc[2 * l + 1] = p2 - p3;
283 
284  i += n1;
285  } while(i < fftLen);
286  j++;
287  } while(j < n2);
288  twidCoefModifier <<= 1u;
289  }
290 
291 #endif // #ifndef ARM_MATH_CM0_FAMILY
292 
293 }
294 
295 
297 float32_t * pSrc,
298 uint32_t fftLen,
299 float32_t * pCoef,
300 uint16_t twidCoefModifier,
301 float32_t onebyfftLen)
302 {
303 
304  uint32_t i, j, k, l;
305  uint32_t n1, n2, ia;
306  float32_t xt, yt, cosVal, sinVal;
307  float32_t p0, p1, p2, p3;
308  float32_t a0, a1;
309 
310 #ifndef ARM_MATH_CM0_FAMILY
311 
312  n2 = fftLen >> 1;
313  ia = 0;
314 
315  // loop for groups
316  for (i = 0; i < n2; i++)
317  {
318  cosVal = pCoef[ia * 2];
319  sinVal = pCoef[(ia * 2) + 1];
320  ia += twidCoefModifier;
321 
322  l = i + n2;
323  a0 = pSrc[2 * i] + pSrc[2 * l];
324  xt = pSrc[2 * i] - pSrc[2 * l];
325 
326  yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
327  a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
328 
329  p0 = xt * cosVal;
330  p1 = yt * sinVal;
331  p2 = yt * cosVal;
332  p3 = xt * sinVal;
333 
334  pSrc[2 * i] = a0;
335  pSrc[2 * i + 1] = a1;
336 
337  pSrc[2 * l] = p0 - p1;
338  pSrc[2 * l + 1] = p2 + p3;
339  } // groups loop end
340 
341  twidCoefModifier <<= 1u;
342 
343  // loop for stage
344  for (k = fftLen / 2; k > 2; k = k >> 1)
345  {
346  n1 = n2;
347  n2 = n2 >> 1;
348  ia = 0;
349 
350  // loop for groups
351  j = 0;
352  do
353  {
354  cosVal = pCoef[ia * 2];
355  sinVal = pCoef[(ia * 2) + 1];
356  ia += twidCoefModifier;
357 
358  // loop for butterfly
359  i = j;
360  do
361  {
362  l = i + n2;
363  a0 = pSrc[2 * i] + pSrc[2 * l];
364  xt = pSrc[2 * i] - pSrc[2 * l];
365 
366  yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
367  a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
368 
369  p0 = xt * cosVal;
370  p1 = yt * sinVal;
371  p2 = yt * cosVal;
372  p3 = xt * sinVal;
373 
374  pSrc[2 * i] = a0;
375  pSrc[2 * i + 1] = a1;
376 
377  pSrc[2 * l] = p0 - p1;
378  pSrc[2 * l + 1] = p2 + p3;
379 
380  i += n1;
381  } while( i < fftLen ); // butterfly loop end
382  j++;
383  } while(j < n2); // groups loop end
384 
385  twidCoefModifier <<= 1u;
386  } // stages loop end
387 
388  // loop for butterfly
389  for (i = 0; i < fftLen; i += 2)
390  {
391  a0 = pSrc[2 * i] + pSrc[2 * i + 2];
392  xt = pSrc[2 * i] - pSrc[2 * i + 2];
393 
394  a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
395  yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
396 
397  p0 = a0 * onebyfftLen;
398  p2 = xt * onebyfftLen;
399  p1 = a1 * onebyfftLen;
400  p3 = yt * onebyfftLen;
401 
402  pSrc[2 * i] = p0;
403  pSrc[2 * i + 1] = p1;
404  pSrc[2 * i + 2] = p2;
405  pSrc[2 * i + 3] = p3;
406  } // butterfly loop end
407 
408 #else
409 
410  n2 = fftLen;
411 
412  // loop for stage
413  for (k = fftLen; k > 2; k = k >> 1)
414  {
415  n1 = n2;
416  n2 = n2 >> 1;
417  ia = 0;
418 
419  // loop for groups
420  j = 0;
421  do
422  {
423  cosVal = pCoef[ia * 2];
424  sinVal = pCoef[(ia * 2) + 1];
425  ia = ia + twidCoefModifier;
426 
427  // loop for butterfly
428  i = j;
429  do
430  {
431  l = i + n2;
432  a0 = pSrc[2 * i] + pSrc[2 * l];
433  xt = pSrc[2 * i] - pSrc[2 * l];
434 
435  yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
436  a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
437 
438  p0 = xt * cosVal;
439  p1 = yt * sinVal;
440  p2 = yt * cosVal;
441  p3 = xt * sinVal;
442 
443  pSrc[2 * i] = a0;
444  pSrc[2 * i + 1] = a1;
445 
446  pSrc[2 * l] = p0 - p1;
447  pSrc[2 * l + 1] = p2 + p3;
448 
449  i += n1;
450  } while( i < fftLen ); // butterfly loop end
451  j++;
452  } while( j < n2 ); // groups loop end
453 
454  twidCoefModifier = twidCoefModifier << 1u;
455  } // stages loop end
456 
457  n1 = n2;
458  n2 = n2 >> 1;
459 
460  // loop for butterfly
461  for (i = 0; i < fftLen; i += n1)
462  {
463  l = i + n2;
464 
465  a0 = pSrc[2 * i] + pSrc[2 * l];
466  xt = pSrc[2 * i] - pSrc[2 * l];
467 
468  a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
469  yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
470 
471  p0 = a0 * onebyfftLen;
472  p2 = xt * onebyfftLen;
473  p1 = a1 * onebyfftLen;
474  p3 = yt * onebyfftLen;
475 
476  pSrc[2 * i] = p0;
477  pSrc[2u * l] = p2;
478 
479  pSrc[2 * i + 1] = p1;
480  pSrc[2u * l + 1u] = p3;
481  } // butterfly loop end
482 
483 #endif // #ifndef ARM_MATH_CM0_FAMILY
484 
485 }
float float32_t
32-bit floating-point type definition.
Definition: arm_math.h:407
void arm_radix2_butterfly_inverse_f32(float32_t *pSrc, uint32_t fftLen, float32_t *pCoef, uint16_t twidCoefModifier, float32_t onebyfftLen)
void arm_cfft_radix2_f32(const arm_cfft_radix2_instance_f32 *S, float32_t *pSrc)
Radix-2 CFFT/CIFFT.
void arm_bitreversal_f32(float32_t *pSrc, uint16_t fftSize, uint16_t bitRevFactor, uint16_t *pBitRevTab)
Instance structure for the floating-point CFFT/CIFFT function.
Definition: arm_math.h:2053
void arm_radix2_butterfly_f32(float32_t *pSrc, uint32_t fftLen, float32_t *pCoef, uint16_t twidCoefModifier)