Merge pull request #11270 from haslinghuis/rename_attr
[betaflight.git] / lib / main / CMSIS / DSP / Source / TransformFunctions / arm_cfft_radix2_q15.c
blob8880ab9c91a9760a53c8bac3bc9dd6589865d84e
1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: arm_cfft_radix2_q15.c
4 * Description: Radix-2 Decimation in Frequency CFFT & CIFFT Fixed point processing function
6 * $Date: 27. January 2017
7 * $Revision: V.1.5.1
9 * Target Processor: Cortex-M cores
10 * -------------------------------------------------------------------- */
12 * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
14 * SPDX-License-Identifier: Apache-2.0
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
20 * www.apache.org/licenses/LICENSE-2.0
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.
29 #include "arm_math.h"
31 void arm_radix2_butterfly_q15(
32 q15_t * pSrc,
33 uint32_t fftLen,
34 q15_t * pCoef,
35 uint16_t twidCoefModifier);
37 void arm_radix2_butterfly_inverse_q15(
38 q15_t * pSrc,
39 uint32_t fftLen,
40 q15_t * pCoef,
41 uint16_t twidCoefModifier);
43 void arm_bitreversal_q15(
44 q15_t * pSrc,
45 uint32_t fftLen,
46 uint16_t bitRevFactor,
47 uint16_t * pBitRevTab);
49 /**
50 * @ingroup groupTransforms
53 /**
54 * @addtogroup ComplexFFT
55 * @{
58 /**
59 * @details
60 * @brief Processing function for the fixed-point CFFT/CIFFT.
61 * @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed
62 * @param[in] *S points to an instance of the fixed-point 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.
67 void arm_cfft_radix2_q15(
68 const arm_cfft_radix2_instance_q15 * S,
69 q15_t * pSrc)
72 if (S->ifftFlag == 1U)
74 arm_radix2_butterfly_inverse_q15(pSrc, S->fftLen,
75 S->pTwiddle, S->twidCoefModifier);
77 else
79 arm_radix2_butterfly_q15(pSrc, S->fftLen,
80 S->pTwiddle, S->twidCoefModifier);
83 arm_bitreversal_q15(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
86 /**
87 * @} end of ComplexFFT group
90 void arm_radix2_butterfly_q15(
91 q15_t * pSrc,
92 uint32_t fftLen,
93 q15_t * pCoef,
94 uint16_t twidCoefModifier)
96 #if defined (ARM_MATH_DSP)
98 unsigned i, j, k, l;
99 unsigned n1, n2, ia;
100 q15_t in;
101 q31_t T, S, R;
102 q31_t coeff, out1, out2;
104 //N = fftLen;
105 n2 = fftLen;
107 n1 = n2;
108 n2 = n2 >> 1;
109 ia = 0;
111 // loop for groups
112 for (i = 0; i < n2; i++)
114 coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
116 ia = ia + twidCoefModifier;
118 l = i + n2;
120 T = _SIMD32_OFFSET(pSrc + (2 * i));
121 in = ((int16_t) (T & 0xFFFF)) >> 1;
122 T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
124 S = _SIMD32_OFFSET(pSrc + (2 * l));
125 in = ((int16_t) (S & 0xFFFF)) >> 1;
126 S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
128 R = __QSUB16(T, S);
130 _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
132 #ifndef ARM_MATH_BIG_ENDIAN
134 out1 = __SMUAD(coeff, R) >> 16;
135 out2 = __SMUSDX(coeff, R);
137 #else
139 out1 = __SMUSDX(R, coeff) >> 16U;
140 out2 = __SMUAD(coeff, R);
142 #endif // #ifndef ARM_MATH_BIG_ENDIAN
144 _SIMD32_OFFSET(pSrc + (2U * l)) =
145 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
147 coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
149 ia = ia + twidCoefModifier;
151 // loop for butterfly
152 i++;
153 l++;
155 T = _SIMD32_OFFSET(pSrc + (2 * i));
156 in = ((int16_t) (T & 0xFFFF)) >> 1;
157 T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
159 S = _SIMD32_OFFSET(pSrc + (2 * l));
160 in = ((int16_t) (S & 0xFFFF)) >> 1;
161 S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
163 R = __QSUB16(T, S);
165 _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
167 #ifndef ARM_MATH_BIG_ENDIAN
169 out1 = __SMUAD(coeff, R) >> 16;
170 out2 = __SMUSDX(coeff, R);
172 #else
174 out1 = __SMUSDX(R, coeff) >> 16U;
175 out2 = __SMUAD(coeff, R);
177 #endif // #ifndef ARM_MATH_BIG_ENDIAN
179 _SIMD32_OFFSET(pSrc + (2U * l)) =
180 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
182 } // groups loop end
184 twidCoefModifier = twidCoefModifier << 1U;
186 // loop for stage
187 for (k = fftLen / 2; k > 2; k = k >> 1)
189 n1 = n2;
190 n2 = n2 >> 1;
191 ia = 0;
193 // loop for groups
194 for (j = 0; j < n2; j++)
196 coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
198 ia = ia + twidCoefModifier;
200 // loop for butterfly
201 for (i = j; i < fftLen; i += n1)
203 l = i + n2;
205 T = _SIMD32_OFFSET(pSrc + (2 * i));
207 S = _SIMD32_OFFSET(pSrc + (2 * l));
209 R = __QSUB16(T, S);
211 _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
213 #ifndef ARM_MATH_BIG_ENDIAN
215 out1 = __SMUAD(coeff, R) >> 16;
216 out2 = __SMUSDX(coeff, R);
218 #else
220 out1 = __SMUSDX(R, coeff) >> 16U;
221 out2 = __SMUAD(coeff, R);
223 #endif // #ifndef ARM_MATH_BIG_ENDIAN
225 _SIMD32_OFFSET(pSrc + (2U * l)) =
226 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
228 i += n1;
230 l = i + n2;
232 T = _SIMD32_OFFSET(pSrc + (2 * i));
234 S = _SIMD32_OFFSET(pSrc + (2 * l));
236 R = __QSUB16(T, S);
238 _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
240 #ifndef ARM_MATH_BIG_ENDIAN
242 out1 = __SMUAD(coeff, R) >> 16;
243 out2 = __SMUSDX(coeff, R);
245 #else
247 out1 = __SMUSDX(R, coeff) >> 16U;
248 out2 = __SMUAD(coeff, R);
250 #endif // #ifndef ARM_MATH_BIG_ENDIAN
252 _SIMD32_OFFSET(pSrc + (2U * l)) =
253 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
255 } // butterfly loop end
257 } // groups loop end
259 twidCoefModifier = twidCoefModifier << 1U;
260 } // stages loop end
262 n1 = n2;
263 n2 = n2 >> 1;
264 ia = 0;
266 coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
268 ia = ia + twidCoefModifier;
270 // loop for butterfly
271 for (i = 0; i < fftLen; i += n1)
273 l = i + n2;
275 T = _SIMD32_OFFSET(pSrc + (2 * i));
277 S = _SIMD32_OFFSET(pSrc + (2 * l));
279 R = __QSUB16(T, S);
281 _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
283 _SIMD32_OFFSET(pSrc + (2U * l)) = R;
285 i += n1;
286 l = i + n2;
288 T = _SIMD32_OFFSET(pSrc + (2 * i));
290 S = _SIMD32_OFFSET(pSrc + (2 * l));
292 R = __QSUB16(T, S);
294 _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
296 _SIMD32_OFFSET(pSrc + (2U * l)) = R;
298 } // groups loop end
301 #else
303 unsigned i, j, k, l;
304 unsigned n1, n2, ia;
305 q15_t xt, yt, cosVal, sinVal;
308 //N = fftLen;
309 n2 = fftLen;
311 n1 = n2;
312 n2 = n2 >> 1;
313 ia = 0;
315 // loop for groups
316 for (j = 0; j < n2; j++)
318 cosVal = pCoef[ia * 2];
319 sinVal = pCoef[(ia * 2) + 1];
320 ia = ia + twidCoefModifier;
322 // loop for butterfly
323 for (i = j; i < fftLen; i += n1)
325 l = i + n2;
326 xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U);
327 pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U;
329 yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U);
330 pSrc[2 * i + 1] =
331 ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U;
333 pSrc[2U * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
334 ((int16_t) (((q31_t) yt * sinVal) >> 16)));
336 pSrc[2U * l + 1U] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
337 ((int16_t) (((q31_t) xt * sinVal) >> 16)));
339 } // butterfly loop end
341 } // groups loop end
343 twidCoefModifier = twidCoefModifier << 1U;
345 // loop for stage
346 for (k = fftLen / 2; k > 2; k = k >> 1)
348 n1 = n2;
349 n2 = n2 >> 1;
350 ia = 0;
352 // loop for groups
353 for (j = 0; j < n2; j++)
355 cosVal = pCoef[ia * 2];
356 sinVal = pCoef[(ia * 2) + 1];
357 ia = ia + twidCoefModifier;
359 // loop for butterfly
360 for (i = j; i < fftLen; i += n1)
362 l = i + n2;
363 xt = pSrc[2 * i] - pSrc[2 * l];
364 pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U;
366 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
367 pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U;
369 pSrc[2U * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
370 ((int16_t) (((q31_t) yt * sinVal) >> 16)));
372 pSrc[2U * l + 1U] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
373 ((int16_t) (((q31_t) xt * sinVal) >> 16)));
375 } // butterfly loop end
377 } // groups loop end
379 twidCoefModifier = twidCoefModifier << 1U;
380 } // stages loop end
382 n1 = n2;
383 n2 = n2 >> 1;
384 ia = 0;
386 // loop for groups
387 for (j = 0; j < n2; j++)
389 cosVal = pCoef[ia * 2];
390 sinVal = pCoef[(ia * 2) + 1];
392 ia = ia + twidCoefModifier;
394 // loop for butterfly
395 for (i = j; i < fftLen; i += n1)
397 l = i + n2;
398 xt = pSrc[2 * i] - pSrc[2 * l];
399 pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
401 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
402 pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
404 pSrc[2U * l] = xt;
406 pSrc[2U * l + 1U] = yt;
408 } // butterfly loop end
410 } // groups loop end
412 twidCoefModifier = twidCoefModifier << 1U;
414 #endif // #if defined (ARM_MATH_DSP)
419 void arm_radix2_butterfly_inverse_q15(
420 q15_t * pSrc,
421 uint32_t fftLen,
422 q15_t * pCoef,
423 uint16_t twidCoefModifier)
425 #if defined (ARM_MATH_DSP)
427 unsigned i, j, k, l;
428 unsigned n1, n2, ia;
429 q15_t in;
430 q31_t T, S, R;
431 q31_t coeff, out1, out2;
433 //N = fftLen;
434 n2 = fftLen;
436 n1 = n2;
437 n2 = n2 >> 1;
438 ia = 0;
440 // loop for groups
441 for (i = 0; i < n2; i++)
443 coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
445 ia = ia + twidCoefModifier;
447 l = i + n2;
449 T = _SIMD32_OFFSET(pSrc + (2 * i));
450 in = ((int16_t) (T & 0xFFFF)) >> 1;
451 T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
453 S = _SIMD32_OFFSET(pSrc + (2 * l));
454 in = ((int16_t) (S & 0xFFFF)) >> 1;
455 S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
457 R = __QSUB16(T, S);
459 _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
461 #ifndef ARM_MATH_BIG_ENDIAN
463 out1 = __SMUSD(coeff, R) >> 16;
464 out2 = __SMUADX(coeff, R);
465 #else
467 out1 = __SMUADX(R, coeff) >> 16U;
468 out2 = __SMUSD(__QSUB(0, coeff), R);
470 #endif // #ifndef ARM_MATH_BIG_ENDIAN
472 _SIMD32_OFFSET(pSrc + (2U * l)) =
473 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
475 coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
477 ia = ia + twidCoefModifier;
479 // loop for butterfly
480 i++;
481 l++;
483 T = _SIMD32_OFFSET(pSrc + (2 * i));
484 in = ((int16_t) (T & 0xFFFF)) >> 1;
485 T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
487 S = _SIMD32_OFFSET(pSrc + (2 * l));
488 in = ((int16_t) (S & 0xFFFF)) >> 1;
489 S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
491 R = __QSUB16(T, S);
493 _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
495 #ifndef ARM_MATH_BIG_ENDIAN
497 out1 = __SMUSD(coeff, R) >> 16;
498 out2 = __SMUADX(coeff, R);
499 #else
501 out1 = __SMUADX(R, coeff) >> 16U;
502 out2 = __SMUSD(__QSUB(0, coeff), R);
504 #endif // #ifndef ARM_MATH_BIG_ENDIAN
506 _SIMD32_OFFSET(pSrc + (2U * l)) =
507 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
509 } // groups loop end
511 twidCoefModifier = twidCoefModifier << 1U;
513 // loop for stage
514 for (k = fftLen / 2; k > 2; k = k >> 1)
516 n1 = n2;
517 n2 = n2 >> 1;
518 ia = 0;
520 // loop for groups
521 for (j = 0; j < n2; j++)
523 coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
525 ia = ia + twidCoefModifier;
527 // loop for butterfly
528 for (i = j; i < fftLen; i += n1)
530 l = i + n2;
532 T = _SIMD32_OFFSET(pSrc + (2 * i));
534 S = _SIMD32_OFFSET(pSrc + (2 * l));
536 R = __QSUB16(T, S);
538 _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
540 #ifndef ARM_MATH_BIG_ENDIAN
542 out1 = __SMUSD(coeff, R) >> 16;
543 out2 = __SMUADX(coeff, R);
545 #else
547 out1 = __SMUADX(R, coeff) >> 16U;
548 out2 = __SMUSD(__QSUB(0, coeff), R);
550 #endif // #ifndef ARM_MATH_BIG_ENDIAN
552 _SIMD32_OFFSET(pSrc + (2U * l)) =
553 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
555 i += n1;
557 l = i + n2;
559 T = _SIMD32_OFFSET(pSrc + (2 * i));
561 S = _SIMD32_OFFSET(pSrc + (2 * l));
563 R = __QSUB16(T, S);
565 _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
567 #ifndef ARM_MATH_BIG_ENDIAN
569 out1 = __SMUSD(coeff, R) >> 16;
570 out2 = __SMUADX(coeff, R);
571 #else
573 out1 = __SMUADX(R, coeff) >> 16U;
574 out2 = __SMUSD(__QSUB(0, coeff), R);
576 #endif // #ifndef ARM_MATH_BIG_ENDIAN
578 _SIMD32_OFFSET(pSrc + (2U * l)) =
579 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
581 } // butterfly loop end
583 } // groups loop end
585 twidCoefModifier = twidCoefModifier << 1U;
586 } // stages loop end
588 n1 = n2;
589 n2 = n2 >> 1;
590 ia = 0;
592 // loop for groups
593 for (j = 0; j < n2; j++)
595 coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
597 ia = ia + twidCoefModifier;
599 // loop for butterfly
600 for (i = j; i < fftLen; i += n1)
602 l = i + n2;
604 T = _SIMD32_OFFSET(pSrc + (2 * i));
606 S = _SIMD32_OFFSET(pSrc + (2 * l));
608 R = __QSUB16(T, S);
610 _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
612 _SIMD32_OFFSET(pSrc + (2U * l)) = R;
614 } // butterfly loop end
616 } // groups loop end
618 twidCoefModifier = twidCoefModifier << 1U;
620 #else
623 unsigned i, j, k, l;
624 unsigned n1, n2, ia;
625 q15_t xt, yt, cosVal, sinVal;
627 //N = fftLen;
628 n2 = fftLen;
630 n1 = n2;
631 n2 = n2 >> 1;
632 ia = 0;
634 // loop for groups
635 for (j = 0; j < n2; j++)
637 cosVal = pCoef[ia * 2];
638 sinVal = pCoef[(ia * 2) + 1];
639 ia = ia + twidCoefModifier;
641 // loop for butterfly
642 for (i = j; i < fftLen; i += n1)
644 l = i + n2;
645 xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U);
646 pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U;
648 yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U);
649 pSrc[2 * i + 1] =
650 ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U;
652 pSrc[2U * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
653 ((int16_t) (((q31_t) yt * sinVal) >> 16)));
655 pSrc[2U * l + 1U] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
656 ((int16_t) (((q31_t) xt * sinVal) >> 16)));
658 } // butterfly loop end
660 } // groups loop end
662 twidCoefModifier = twidCoefModifier << 1U;
664 // loop for stage
665 for (k = fftLen / 2; k > 2; k = k >> 1)
667 n1 = n2;
668 n2 = n2 >> 1;
669 ia = 0;
671 // loop for groups
672 for (j = 0; j < n2; j++)
674 cosVal = pCoef[ia * 2];
675 sinVal = pCoef[(ia * 2) + 1];
676 ia = ia + twidCoefModifier;
678 // loop for butterfly
679 for (i = j; i < fftLen; i += n1)
681 l = i + n2;
682 xt = pSrc[2 * i] - pSrc[2 * l];
683 pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U;
685 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
686 pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U;
688 pSrc[2U * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
689 ((int16_t) (((q31_t) yt * sinVal) >> 16)));
691 pSrc[2U * l + 1U] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
692 ((int16_t) (((q31_t) xt * sinVal) >> 16)));
694 } // butterfly loop end
696 } // groups loop end
698 twidCoefModifier = twidCoefModifier << 1U;
699 } // stages loop end
701 n1 = n2;
702 n2 = n2 >> 1;
703 ia = 0;
705 cosVal = pCoef[ia * 2];
706 sinVal = pCoef[(ia * 2) + 1];
708 ia = ia + twidCoefModifier;
710 // loop for butterfly
711 for (i = 0; i < fftLen; i += n1)
713 l = i + n2;
714 xt = pSrc[2 * i] - pSrc[2 * l];
715 pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
717 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
718 pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
720 pSrc[2U * l] = xt;
722 pSrc[2U * l + 1U] = yt;
724 } // groups loop end
727 #endif // #if defined (ARM_MATH_DSP)