]> git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/dsp/cmsis_dsp/TransformFunctions/arm_cfft_radix2_f32.c
Merge commit '1fe4406f374291ab2e86e95a97341fd9c475fcb8'
[tmk_keyboard.git] / tmk_core / tool / mbed / mbed-sdk / libraries / dsp / cmsis_dsp / TransformFunctions / arm_cfft_radix2_f32.c
1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010-2013 ARM Limited. All rights reserved.
3 *
4 * $Date: 17. January 2013
5 * $Revision: V1.4.1
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
44 void arm_radix2_butterfly_f32(
45 float32_t * pSrc,
46 uint32_t fftLen,
47 float32_t * pCoef,
48 uint16_t twidCoefModifier);
49
50 void arm_radix2_butterfly_inverse_f32(
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
63 /**
64 * @ingroup groupTransforms
65 */
66
67 /**
68 * @addtogroup ComplexFFT
69 * @{
70 */
71
72 /**
73 * @details
74 * @brief Radix-2 CFFT/CIFFT.
75 * @deprecated Do not use this function. It has been superceded by \ref arm_cfft_f32 and will be removed
76 * in the future.
77 * @param[in] *S points to an instance of the floating-point Radix-2 CFFT/CIFFT structure.
78 * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
79 * @return none.
80 */
81
82 void arm_cfft_radix2_f32(
83 const arm_cfft_radix2_instance_f32 * S,
84 float32_t * pSrc)
85 {
86
87 if(S->ifftFlag == 1u)
88 {
89 /* Complex IFFT radix-2 */
90 arm_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
91 S->twidCoefModifier, S->onebyfftLen);
92 }
93 else
94 {
95 /* Complex FFT radix-2 */
96 arm_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
97 S->twidCoefModifier);
98 }
99
100 if(S->bitReverseFlag == 1u)
101 {
102 /* Bit Reversal */
103 arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
104 }
105
106 }
107
108
109 /**
110 * @} end of ComplexFFT group
111 */
112
113
114
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
128 void arm_radix2_butterfly_f32(
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
296 void arm_radix2_butterfly_inverse_f32(
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 }
Imprint / Impressum