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
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.
31 void arm_radix2_butterfly_q15(
35 uint16_t twidCoefModifier
);
37 void arm_radix2_butterfly_inverse_q15(
41 uint16_t twidCoefModifier
);
43 void arm_bitreversal_q15(
46 uint16_t bitRevFactor
,
47 uint16_t * pBitRevTab
);
50 * @ingroup groupTransforms
54 * @addtogroup ComplexFFT
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.
67 void arm_cfft_radix2_q15(
68 const arm_cfft_radix2_instance_q15
* S
,
72 if (S
->ifftFlag
== 1U)
74 arm_radix2_butterfly_inverse_q15(pSrc
, S
->fftLen
,
75 S
->pTwiddle
, S
->twidCoefModifier
);
79 arm_radix2_butterfly_q15(pSrc
, S
->fftLen
,
80 S
->pTwiddle
, S
->twidCoefModifier
);
83 arm_bitreversal_q15(pSrc
, S
->fftLen
, S
->bitRevFactor
, S
->pBitRevTable
);
87 * @} end of ComplexFFT group
90 void arm_radix2_butterfly_q15(
94 uint16_t twidCoefModifier
)
96 #if defined (ARM_MATH_DSP)
102 q31_t coeff
, out1
, out2
;
112 for (i
= 0; i
< n2
; i
++)
114 coeff
= _SIMD32_OFFSET(pCoef
+ (ia
* 2U));
116 ia
= ia
+ twidCoefModifier
;
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);
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
);
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
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);
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
);
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);
184 twidCoefModifier
= twidCoefModifier
<< 1U;
187 for (k
= fftLen
/ 2; k
> 2; k
= k
>> 1)
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
)
205 T
= _SIMD32_OFFSET(pSrc
+ (2 * i
));
207 S
= _SIMD32_OFFSET(pSrc
+ (2 * l
));
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
);
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);
232 T
= _SIMD32_OFFSET(pSrc
+ (2 * i
));
234 S
= _SIMD32_OFFSET(pSrc
+ (2 * l
));
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
);
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
259 twidCoefModifier
= twidCoefModifier
<< 1U;
266 coeff
= _SIMD32_OFFSET(pCoef
+ (ia
* 2U));
268 ia
= ia
+ twidCoefModifier
;
270 // loop for butterfly
271 for (i
= 0; i
< fftLen
; i
+= n1
)
275 T
= _SIMD32_OFFSET(pSrc
+ (2 * i
));
277 S
= _SIMD32_OFFSET(pSrc
+ (2 * l
));
281 _SIMD32_OFFSET(pSrc
+ (2 * i
)) = __QADD16(T
, S
);
283 _SIMD32_OFFSET(pSrc
+ (2U * l
)) = R
;
288 T
= _SIMD32_OFFSET(pSrc
+ (2 * i
));
290 S
= _SIMD32_OFFSET(pSrc
+ (2 * l
));
294 _SIMD32_OFFSET(pSrc
+ (2 * i
)) = __QADD16(T
, S
);
296 _SIMD32_OFFSET(pSrc
+ (2U * l
)) = R
;
305 q15_t xt
, yt
, cosVal
, sinVal
;
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
)
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);
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
343 twidCoefModifier
= twidCoefModifier
<< 1U;
346 for (k
= fftLen
/ 2; k
> 2; k
= k
>> 1)
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
)
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
379 twidCoefModifier
= twidCoefModifier
<< 1U;
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
)
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]);
406 pSrc
[2U * l
+ 1U] = yt
;
408 } // butterfly loop end
412 twidCoefModifier
= twidCoefModifier
<< 1U;
414 #endif // #if defined (ARM_MATH_DSP)
419 void arm_radix2_butterfly_inverse_q15(
423 uint16_t twidCoefModifier
)
425 #if defined (ARM_MATH_DSP)
431 q31_t coeff
, out1
, out2
;
441 for (i
= 0; i
< n2
; i
++)
443 coeff
= _SIMD32_OFFSET(pCoef
+ (ia
* 2U));
445 ia
= ia
+ twidCoefModifier
;
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);
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
);
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
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);
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
);
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);
511 twidCoefModifier
= twidCoefModifier
<< 1U;
514 for (k
= fftLen
/ 2; k
> 2; k
= k
>> 1)
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
)
532 T
= _SIMD32_OFFSET(pSrc
+ (2 * i
));
534 S
= _SIMD32_OFFSET(pSrc
+ (2 * l
));
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
);
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);
559 T
= _SIMD32_OFFSET(pSrc
+ (2 * i
));
561 S
= _SIMD32_OFFSET(pSrc
+ (2 * l
));
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
);
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
585 twidCoefModifier
= twidCoefModifier
<< 1U;
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
)
604 T
= _SIMD32_OFFSET(pSrc
+ (2 * i
));
606 S
= _SIMD32_OFFSET(pSrc
+ (2 * l
));
610 _SIMD32_OFFSET(pSrc
+ (2 * i
)) = __QADD16(T
, S
);
612 _SIMD32_OFFSET(pSrc
+ (2U * l
)) = R
;
614 } // butterfly loop end
618 twidCoefModifier
= twidCoefModifier
<< 1U;
625 q15_t xt
, yt
, cosVal
, sinVal
;
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
)
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);
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
662 twidCoefModifier
= twidCoefModifier
<< 1U;
665 for (k
= fftLen
/ 2; k
> 2; k
= k
>> 1)
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
)
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
698 twidCoefModifier
= twidCoefModifier
<< 1U;
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
)
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]);
722 pSrc
[2U * l
+ 1U] = yt
;
727 #endif // #if defined (ARM_MATH_DSP)