Set blackbox file handler to NULL after closing file
[inav.git] / lib / main / CMSIS / DSP / Source / TransformFunctions / arm_cfft_q15.c
blobda76ddcc752ce3fd6d3287fe2caee273cc0dc636
1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: arm_cfft_q15.c
4 * Description: Combined Radix Decimation in Q15 Frequency CFFT 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 extern void arm_radix4_butterfly_q15(
32 q15_t * pSrc,
33 uint32_t fftLen,
34 q15_t * pCoef,
35 uint32_t twidCoefModifier);
37 extern void arm_radix4_butterfly_inverse_q15(
38 q15_t * pSrc,
39 uint32_t fftLen,
40 q15_t * pCoef,
41 uint32_t twidCoefModifier);
43 extern void arm_bitreversal_16(
44 uint16_t * pSrc,
45 const uint16_t bitRevLen,
46 const uint16_t * pBitRevTable);
48 void arm_cfft_radix4by2_q15(
49 q15_t * pSrc,
50 uint32_t fftLen,
51 const q15_t * pCoef);
53 void arm_cfft_radix4by2_inverse_q15(
54 q15_t * pSrc,
55 uint32_t fftLen,
56 const q15_t * pCoef);
58 /**
59 * @ingroup groupTransforms
62 /**
63 * @addtogroup ComplexFFT
64 * @{
67 /**
68 * @details
69 * @brief Processing function for the Q15 complex FFT.
70 * @param[in] *S points to an instance of the Q15 CFFT structure.
71 * @param[in, out] *p1 points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
72 * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
73 * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
74 * @return none.
77 void arm_cfft_q15(
78 const arm_cfft_instance_q15 * S,
79 q15_t * p1,
80 uint8_t ifftFlag,
81 uint8_t bitReverseFlag)
83 uint32_t L = S->fftLen;
85 if (ifftFlag == 1U)
87 switch (L)
89 case 16:
90 case 64:
91 case 256:
92 case 1024:
93 case 4096:
94 arm_radix4_butterfly_inverse_q15 ( p1, L, (q15_t*)S->pTwiddle, 1 );
95 break;
97 case 32:
98 case 128:
99 case 512:
100 case 2048:
101 arm_cfft_radix4by2_inverse_q15 ( p1, L, S->pTwiddle );
102 break;
105 else
107 switch (L)
109 case 16:
110 case 64:
111 case 256:
112 case 1024:
113 case 4096:
114 arm_radix4_butterfly_q15 ( p1, L, (q15_t*)S->pTwiddle, 1 );
115 break;
117 case 32:
118 case 128:
119 case 512:
120 case 2048:
121 arm_cfft_radix4by2_q15 ( p1, L, S->pTwiddle );
122 break;
126 if ( bitReverseFlag )
127 arm_bitreversal_16((uint16_t*)p1,S->bitRevLength,S->pBitRevTable);
131 * @} end of ComplexFFT group
134 void arm_cfft_radix4by2_q15(
135 q15_t * pSrc,
136 uint32_t fftLen,
137 const q15_t * pCoef)
139 uint32_t i;
140 uint32_t n2;
141 q15_t p0, p1, p2, p3;
142 #if defined (ARM_MATH_DSP)
143 q31_t T, S, R;
144 q31_t coeff, out1, out2;
145 const q15_t *pC = pCoef;
146 q15_t *pSi = pSrc;
147 q15_t *pSl = pSrc + fftLen;
148 #else
149 uint32_t ia, l;
150 q15_t xt, yt, cosVal, sinVal;
151 #endif
153 n2 = fftLen >> 1;
155 #if defined (ARM_MATH_DSP)
157 for (i = n2; i > 0; i--)
159 coeff = _SIMD32_OFFSET(pC);
160 pC += 2;
162 T = _SIMD32_OFFSET(pSi);
163 T = __SHADD16(T, 0); // this is just a SIMD arithmetic shift right by 1
165 S = _SIMD32_OFFSET(pSl);
166 S = __SHADD16(S, 0); // this is just a SIMD arithmetic shift right by 1
168 R = __QSUB16(T, S);
170 _SIMD32_OFFSET(pSi) = __SHADD16(T, S);
171 pSi += 2;
173 #ifndef ARM_MATH_BIG_ENDIAN
175 out1 = __SMUAD(coeff, R) >> 16;
176 out2 = __SMUSDX(coeff, R);
178 #else
180 out1 = __SMUSDX(R, coeff) >> 16U;
181 out2 = __SMUAD(coeff, R);
183 #endif // #ifndef ARM_MATH_BIG_ENDIAN
185 _SIMD32_OFFSET(pSl) =
186 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
187 pSl += 2;
190 #else // #if defined (ARM_MATH_DSP)
192 ia = 0;
193 for (i = 0; i < n2; i++)
195 cosVal = pCoef[ia * 2];
196 sinVal = pCoef[(ia * 2) + 1];
197 ia++;
199 l = i + n2;
201 xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U);
202 pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U;
204 yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U);
205 pSrc[2 * i + 1] =
206 ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U;
208 pSrc[2U * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
209 ((int16_t) (((q31_t) yt * sinVal) >> 16)));
211 pSrc[2U * l + 1U] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
212 ((int16_t) (((q31_t) xt * sinVal) >> 16)));
215 #endif // #if defined (ARM_MATH_DSP)
217 // first col
218 arm_radix4_butterfly_q15( pSrc, n2, (q15_t*)pCoef, 2U);
219 // second col
220 arm_radix4_butterfly_q15( pSrc + fftLen, n2, (q15_t*)pCoef, 2U);
222 for (i = 0; i < fftLen >> 1; i++)
224 p0 = pSrc[4*i+0];
225 p1 = pSrc[4*i+1];
226 p2 = pSrc[4*i+2];
227 p3 = pSrc[4*i+3];
229 p0 <<= 1;
230 p1 <<= 1;
231 p2 <<= 1;
232 p3 <<= 1;
234 pSrc[4*i+0] = p0;
235 pSrc[4*i+1] = p1;
236 pSrc[4*i+2] = p2;
237 pSrc[4*i+3] = p3;
241 void arm_cfft_radix4by2_inverse_q15(
242 q15_t * pSrc,
243 uint32_t fftLen,
244 const q15_t * pCoef)
246 uint32_t i;
247 uint32_t n2;
248 q15_t p0, p1, p2, p3;
249 #if defined (ARM_MATH_DSP)
250 q31_t T, S, R;
251 q31_t coeff, out1, out2;
252 const q15_t *pC = pCoef;
253 q15_t *pSi = pSrc;
254 q15_t *pSl = pSrc + fftLen;
255 #else
256 uint32_t ia, l;
257 q15_t xt, yt, cosVal, sinVal;
258 #endif
260 n2 = fftLen >> 1;
262 #if defined (ARM_MATH_DSP)
264 for (i = n2; i > 0; i--)
266 coeff = _SIMD32_OFFSET(pC);
267 pC += 2;
269 T = _SIMD32_OFFSET(pSi);
270 T = __SHADD16(T, 0); // this is just a SIMD arithmetic shift right by 1
272 S = _SIMD32_OFFSET(pSl);
273 S = __SHADD16(S, 0); // this is just a SIMD arithmetic shift right by 1
275 R = __QSUB16(T, S);
277 _SIMD32_OFFSET(pSi) = __SHADD16(T, S);
278 pSi += 2;
280 #ifndef ARM_MATH_BIG_ENDIAN
282 out1 = __SMUSD(coeff, R) >> 16;
283 out2 = __SMUADX(coeff, R);
284 #else
286 out1 = __SMUADX(R, coeff) >> 16U;
287 out2 = __SMUSD(__QSUB(0, coeff), R);
289 #endif // #ifndef ARM_MATH_BIG_ENDIAN
291 _SIMD32_OFFSET(pSl) =
292 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
293 pSl += 2;
296 #else // #if defined (ARM_MATH_DSP)
298 ia = 0;
299 for (i = 0; i < n2; i++)
301 cosVal = pCoef[ia * 2];
302 sinVal = pCoef[(ia * 2) + 1];
303 ia++;
305 l = i + n2;
306 xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U);
307 pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U;
309 yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U);
310 pSrc[2 * i + 1] =
311 ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U;
313 pSrc[2U * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
314 ((int16_t) (((q31_t) yt * sinVal) >> 16)));
316 pSrc[2U * l + 1U] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
317 ((int16_t) (((q31_t) xt * sinVal) >> 16)));
320 #endif // #if defined (ARM_MATH_DSP)
322 // first col
323 arm_radix4_butterfly_inverse_q15( pSrc, n2, (q15_t*)pCoef, 2U);
324 // second col
325 arm_radix4_butterfly_inverse_q15( pSrc + fftLen, n2, (q15_t*)pCoef, 2U);
327 for (i = 0; i < fftLen >> 1; i++)
329 p0 = pSrc[4*i+0];
330 p1 = pSrc[4*i+1];
331 p2 = pSrc[4*i+2];
332 p3 = pSrc[4*i+3];
334 p0 <<= 1;
335 p1 <<= 1;
336 p2 <<= 1;
337 p3 <<= 1;
339 pSrc[4*i+0] = p0;
340 pSrc[4*i+1] = p1;
341 pSrc[4*i+2] = p2;
342 pSrc[4*i+3] = p3;