arm_cfft_radix2_q15.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  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
  5. *
  6. * $Date: 27. January 2017
  7. * $Revision: V.1.5.1
  8. *
  9. * Target Processor: Cortex-M cores
  10. * -------------------------------------------------------------------- */
  11. /*
  12. * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
  13. *
  14. * SPDX-License-Identifier: Apache-2.0
  15. *
  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
  19. *
  20. * www.apache.org/licenses/LICENSE-2.0
  21. *
  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.
  27. */
  28. #include "arm_math.h"
  29. void arm_radix2_butterfly_q15(
  30. q15_t * pSrc,
  31. uint32_t fftLen,
  32. q15_t * pCoef,
  33. uint16_t twidCoefModifier);
  34. void arm_radix2_butterfly_inverse_q15(
  35. q15_t * pSrc,
  36. uint32_t fftLen,
  37. q15_t * pCoef,
  38. uint16_t twidCoefModifier);
  39. void arm_bitreversal_q15(
  40. q15_t * pSrc,
  41. uint32_t fftLen,
  42. uint16_t bitRevFactor,
  43. uint16_t * pBitRevTab);
  44. /**
  45. * @ingroup groupTransforms
  46. */
  47. /**
  48. * @addtogroup ComplexFFT
  49. * @{
  50. */
  51. /**
  52. * @details
  53. * @brief Processing function for the fixed-point CFFT/CIFFT.
  54. * @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed
  55. * @param[in] *S points to an instance of the fixed-point CFFT/CIFFT structure.
  56. * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
  57. * @return none.
  58. */
  59. void arm_cfft_radix2_q15(
  60. const arm_cfft_radix2_instance_q15 * S,
  61. q15_t * pSrc)
  62. {
  63. if (S->ifftFlag == 1U)
  64. {
  65. arm_radix2_butterfly_inverse_q15(pSrc, S->fftLen,
  66. S->pTwiddle, S->twidCoefModifier);
  67. }
  68. else
  69. {
  70. arm_radix2_butterfly_q15(pSrc, S->fftLen,
  71. S->pTwiddle, S->twidCoefModifier);
  72. }
  73. arm_bitreversal_q15(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
  74. }
  75. /**
  76. * @} end of ComplexFFT group
  77. */
  78. void arm_radix2_butterfly_q15(
  79. q15_t * pSrc,
  80. uint32_t fftLen,
  81. q15_t * pCoef,
  82. uint16_t twidCoefModifier)
  83. {
  84. #if defined (ARM_MATH_DSP)
  85. unsigned i, j, k, l;
  86. unsigned n1, n2, ia;
  87. q15_t in;
  88. q31_t T, S, R;
  89. q31_t coeff, out1, out2;
  90. //N = fftLen;
  91. n2 = fftLen;
  92. n1 = n2;
  93. n2 = n2 >> 1;
  94. ia = 0;
  95. // loop for groups
  96. for (i = 0; i < n2; i++)
  97. {
  98. coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
  99. ia = ia + twidCoefModifier;
  100. l = i + n2;
  101. T = _SIMD32_OFFSET(pSrc + (2 * i));
  102. in = ((int16_t) (T & 0xFFFF)) >> 1;
  103. T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
  104. S = _SIMD32_OFFSET(pSrc + (2 * l));
  105. in = ((int16_t) (S & 0xFFFF)) >> 1;
  106. S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
  107. R = __QSUB16(T, S);
  108. _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
  109. #ifndef ARM_MATH_BIG_ENDIAN
  110. out1 = __SMUAD(coeff, R) >> 16;
  111. out2 = __SMUSDX(coeff, R);
  112. #else
  113. out1 = __SMUSDX(R, coeff) >> 16U;
  114. out2 = __SMUAD(coeff, R);
  115. #endif // #ifndef ARM_MATH_BIG_ENDIAN
  116. _SIMD32_OFFSET(pSrc + (2U * l)) =
  117. (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
  118. coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
  119. ia = ia + twidCoefModifier;
  120. // loop for butterfly
  121. i++;
  122. l++;
  123. T = _SIMD32_OFFSET(pSrc + (2 * i));
  124. in = ((int16_t) (T & 0xFFFF)) >> 1;
  125. T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
  126. S = _SIMD32_OFFSET(pSrc + (2 * l));
  127. in = ((int16_t) (S & 0xFFFF)) >> 1;
  128. S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
  129. R = __QSUB16(T, S);
  130. _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
  131. #ifndef ARM_MATH_BIG_ENDIAN
  132. out1 = __SMUAD(coeff, R) >> 16;
  133. out2 = __SMUSDX(coeff, R);
  134. #else
  135. out1 = __SMUSDX(R, coeff) >> 16U;
  136. out2 = __SMUAD(coeff, R);
  137. #endif // #ifndef ARM_MATH_BIG_ENDIAN
  138. _SIMD32_OFFSET(pSrc + (2U * l)) =
  139. (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
  140. } // groups loop end
  141. twidCoefModifier = twidCoefModifier << 1U;
  142. // loop for stage
  143. for (k = fftLen / 2; k > 2; k = k >> 1)
  144. {
  145. n1 = n2;
  146. n2 = n2 >> 1;
  147. ia = 0;
  148. // loop for groups
  149. for (j = 0; j < n2; j++)
  150. {
  151. coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
  152. ia = ia + twidCoefModifier;
  153. // loop for butterfly
  154. for (i = j; i < fftLen; i += n1)
  155. {
  156. l = i + n2;
  157. T = _SIMD32_OFFSET(pSrc + (2 * i));
  158. S = _SIMD32_OFFSET(pSrc + (2 * l));
  159. R = __QSUB16(T, S);
  160. _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
  161. #ifndef ARM_MATH_BIG_ENDIAN
  162. out1 = __SMUAD(coeff, R) >> 16;
  163. out2 = __SMUSDX(coeff, R);
  164. #else
  165. out1 = __SMUSDX(R, coeff) >> 16U;
  166. out2 = __SMUAD(coeff, R);
  167. #endif // #ifndef ARM_MATH_BIG_ENDIAN
  168. _SIMD32_OFFSET(pSrc + (2U * l)) =
  169. (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
  170. i += n1;
  171. l = i + n2;
  172. T = _SIMD32_OFFSET(pSrc + (2 * i));
  173. S = _SIMD32_OFFSET(pSrc + (2 * l));
  174. R = __QSUB16(T, S);
  175. _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
  176. #ifndef ARM_MATH_BIG_ENDIAN
  177. out1 = __SMUAD(coeff, R) >> 16;
  178. out2 = __SMUSDX(coeff, R);
  179. #else
  180. out1 = __SMUSDX(R, coeff) >> 16U;
  181. out2 = __SMUAD(coeff, R);
  182. #endif // #ifndef ARM_MATH_BIG_ENDIAN
  183. _SIMD32_OFFSET(pSrc + (2U * l)) =
  184. (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
  185. } // butterfly loop end
  186. } // groups loop end
  187. twidCoefModifier = twidCoefModifier << 1U;
  188. } // stages loop end
  189. n1 = n2;
  190. n2 = n2 >> 1;
  191. ia = 0;
  192. coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
  193. ia = ia + twidCoefModifier;
  194. // loop for butterfly
  195. for (i = 0; i < fftLen; i += n1)
  196. {
  197. l = i + n2;
  198. T = _SIMD32_OFFSET(pSrc + (2 * i));
  199. S = _SIMD32_OFFSET(pSrc + (2 * l));
  200. R = __QSUB16(T, S);
  201. _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
  202. _SIMD32_OFFSET(pSrc + (2U * l)) = R;
  203. i += n1;
  204. l = i + n2;
  205. T = _SIMD32_OFFSET(pSrc + (2 * i));
  206. S = _SIMD32_OFFSET(pSrc + (2 * l));
  207. R = __QSUB16(T, S);
  208. _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
  209. _SIMD32_OFFSET(pSrc + (2U * l)) = R;
  210. } // groups loop end
  211. #else
  212. unsigned i, j, k, l;
  213. unsigned n1, n2, ia;
  214. q15_t xt, yt, cosVal, sinVal;
  215. //N = fftLen;
  216. n2 = fftLen;
  217. n1 = n2;
  218. n2 = n2 >> 1;
  219. ia = 0;
  220. // loop for groups
  221. for (j = 0; j < n2; j++)
  222. {
  223. cosVal = pCoef[ia * 2];
  224. sinVal = pCoef[(ia * 2) + 1];
  225. ia = ia + twidCoefModifier;
  226. // loop for butterfly
  227. for (i = j; i < fftLen; i += n1)
  228. {
  229. l = i + n2;
  230. xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U);
  231. pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U;
  232. yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U);
  233. pSrc[2 * i + 1] =
  234. ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U;
  235. pSrc[2U * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
  236. ((int16_t) (((q31_t) yt * sinVal) >> 16)));
  237. pSrc[2U * l + 1U] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
  238. ((int16_t) (((q31_t) xt * sinVal) >> 16)));
  239. } // butterfly loop end
  240. } // groups loop end
  241. twidCoefModifier = twidCoefModifier << 1U;
  242. // loop for stage
  243. for (k = fftLen / 2; k > 2; k = k >> 1)
  244. {
  245. n1 = n2;
  246. n2 = n2 >> 1;
  247. ia = 0;
  248. // loop for groups
  249. for (j = 0; j < n2; j++)
  250. {
  251. cosVal = pCoef[ia * 2];
  252. sinVal = pCoef[(ia * 2) + 1];
  253. ia = ia + twidCoefModifier;
  254. // loop for butterfly
  255. for (i = j; i < fftLen; i += n1)
  256. {
  257. l = i + n2;
  258. xt = pSrc[2 * i] - pSrc[2 * l];
  259. pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U;
  260. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  261. pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U;
  262. pSrc[2U * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
  263. ((int16_t) (((q31_t) yt * sinVal) >> 16)));
  264. pSrc[2U * l + 1U] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
  265. ((int16_t) (((q31_t) xt * sinVal) >> 16)));
  266. } // butterfly loop end
  267. } // groups loop end
  268. twidCoefModifier = twidCoefModifier << 1U;
  269. } // stages loop end
  270. n1 = n2;
  271. n2 = n2 >> 1;
  272. ia = 0;
  273. // loop for groups
  274. for (j = 0; j < n2; j++)
  275. {
  276. cosVal = pCoef[ia * 2];
  277. sinVal = pCoef[(ia * 2) + 1];
  278. ia = ia + twidCoefModifier;
  279. // loop for butterfly
  280. for (i = j; i < fftLen; i += n1)
  281. {
  282. l = i + n2;
  283. xt = pSrc[2 * i] - pSrc[2 * l];
  284. pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
  285. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  286. pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
  287. pSrc[2U * l] = xt;
  288. pSrc[2U * l + 1U] = yt;
  289. } // butterfly loop end
  290. } // groups loop end
  291. twidCoefModifier = twidCoefModifier << 1U;
  292. #endif // #if defined (ARM_MATH_DSP)
  293. }
  294. void arm_radix2_butterfly_inverse_q15(
  295. q15_t * pSrc,
  296. uint32_t fftLen,
  297. q15_t * pCoef,
  298. uint16_t twidCoefModifier)
  299. {
  300. #if defined (ARM_MATH_DSP)
  301. unsigned i, j, k, l;
  302. unsigned n1, n2, ia;
  303. q15_t in;
  304. q31_t T, S, R;
  305. q31_t coeff, out1, out2;
  306. //N = fftLen;
  307. n2 = fftLen;
  308. n1 = n2;
  309. n2 = n2 >> 1;
  310. ia = 0;
  311. // loop for groups
  312. for (i = 0; i < n2; i++)
  313. {
  314. coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
  315. ia = ia + twidCoefModifier;
  316. l = i + n2;
  317. T = _SIMD32_OFFSET(pSrc + (2 * i));
  318. in = ((int16_t) (T & 0xFFFF)) >> 1;
  319. T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
  320. S = _SIMD32_OFFSET(pSrc + (2 * l));
  321. in = ((int16_t) (S & 0xFFFF)) >> 1;
  322. S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
  323. R = __QSUB16(T, S);
  324. _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
  325. #ifndef ARM_MATH_BIG_ENDIAN
  326. out1 = __SMUSD(coeff, R) >> 16;
  327. out2 = __SMUADX(coeff, R);
  328. #else
  329. out1 = __SMUADX(R, coeff) >> 16U;
  330. out2 = __SMUSD(__QSUB(0, coeff), R);
  331. #endif // #ifndef ARM_MATH_BIG_ENDIAN
  332. _SIMD32_OFFSET(pSrc + (2U * l)) =
  333. (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
  334. coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
  335. ia = ia + twidCoefModifier;
  336. // loop for butterfly
  337. i++;
  338. l++;
  339. T = _SIMD32_OFFSET(pSrc + (2 * i));
  340. in = ((int16_t) (T & 0xFFFF)) >> 1;
  341. T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
  342. S = _SIMD32_OFFSET(pSrc + (2 * l));
  343. in = ((int16_t) (S & 0xFFFF)) >> 1;
  344. S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
  345. R = __QSUB16(T, S);
  346. _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
  347. #ifndef ARM_MATH_BIG_ENDIAN
  348. out1 = __SMUSD(coeff, R) >> 16;
  349. out2 = __SMUADX(coeff, R);
  350. #else
  351. out1 = __SMUADX(R, coeff) >> 16U;
  352. out2 = __SMUSD(__QSUB(0, coeff), R);
  353. #endif // #ifndef ARM_MATH_BIG_ENDIAN
  354. _SIMD32_OFFSET(pSrc + (2U * l)) =
  355. (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
  356. } // groups loop end
  357. twidCoefModifier = twidCoefModifier << 1U;
  358. // loop for stage
  359. for (k = fftLen / 2; k > 2; k = k >> 1)
  360. {
  361. n1 = n2;
  362. n2 = n2 >> 1;
  363. ia = 0;
  364. // loop for groups
  365. for (j = 0; j < n2; j++)
  366. {
  367. coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
  368. ia = ia + twidCoefModifier;
  369. // loop for butterfly
  370. for (i = j; i < fftLen; i += n1)
  371. {
  372. l = i + n2;
  373. T = _SIMD32_OFFSET(pSrc + (2 * i));
  374. S = _SIMD32_OFFSET(pSrc + (2 * l));
  375. R = __QSUB16(T, S);
  376. _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
  377. #ifndef ARM_MATH_BIG_ENDIAN
  378. out1 = __SMUSD(coeff, R) >> 16;
  379. out2 = __SMUADX(coeff, R);
  380. #else
  381. out1 = __SMUADX(R, coeff) >> 16U;
  382. out2 = __SMUSD(__QSUB(0, coeff), R);
  383. #endif // #ifndef ARM_MATH_BIG_ENDIAN
  384. _SIMD32_OFFSET(pSrc + (2U * l)) =
  385. (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
  386. i += n1;
  387. l = i + n2;
  388. T = _SIMD32_OFFSET(pSrc + (2 * i));
  389. S = _SIMD32_OFFSET(pSrc + (2 * l));
  390. R = __QSUB16(T, S);
  391. _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
  392. #ifndef ARM_MATH_BIG_ENDIAN
  393. out1 = __SMUSD(coeff, R) >> 16;
  394. out2 = __SMUADX(coeff, R);
  395. #else
  396. out1 = __SMUADX(R, coeff) >> 16U;
  397. out2 = __SMUSD(__QSUB(0, coeff), R);
  398. #endif // #ifndef ARM_MATH_BIG_ENDIAN
  399. _SIMD32_OFFSET(pSrc + (2U * l)) =
  400. (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
  401. } // butterfly loop end
  402. } // groups loop end
  403. twidCoefModifier = twidCoefModifier << 1U;
  404. } // stages loop end
  405. n1 = n2;
  406. n2 = n2 >> 1;
  407. ia = 0;
  408. // loop for groups
  409. for (j = 0; j < n2; j++)
  410. {
  411. coeff = _SIMD32_OFFSET(pCoef + (ia * 2U));
  412. ia = ia + twidCoefModifier;
  413. // loop for butterfly
  414. for (i = j; i < fftLen; i += n1)
  415. {
  416. l = i + n2;
  417. T = _SIMD32_OFFSET(pSrc + (2 * i));
  418. S = _SIMD32_OFFSET(pSrc + (2 * l));
  419. R = __QSUB16(T, S);
  420. _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
  421. _SIMD32_OFFSET(pSrc + (2U * l)) = R;
  422. } // butterfly loop end
  423. } // groups loop end
  424. twidCoefModifier = twidCoefModifier << 1U;
  425. #else
  426. unsigned i, j, k, l;
  427. unsigned n1, n2, ia;
  428. q15_t xt, yt, cosVal, sinVal;
  429. //N = fftLen;
  430. n2 = fftLen;
  431. n1 = n2;
  432. n2 = n2 >> 1;
  433. ia = 0;
  434. // loop for groups
  435. for (j = 0; j < n2; j++)
  436. {
  437. cosVal = pCoef[ia * 2];
  438. sinVal = pCoef[(ia * 2) + 1];
  439. ia = ia + twidCoefModifier;
  440. // loop for butterfly
  441. for (i = j; i < fftLen; i += n1)
  442. {
  443. l = i + n2;
  444. xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U);
  445. pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U;
  446. yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U);
  447. pSrc[2 * i + 1] =
  448. ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U;
  449. pSrc[2U * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
  450. ((int16_t) (((q31_t) yt * sinVal) >> 16)));
  451. pSrc[2U * l + 1U] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
  452. ((int16_t) (((q31_t) xt * sinVal) >> 16)));
  453. } // butterfly loop end
  454. } // groups loop end
  455. twidCoefModifier = twidCoefModifier << 1U;
  456. // loop for stage
  457. for (k = fftLen / 2; k > 2; k = k >> 1)
  458. {
  459. n1 = n2;
  460. n2 = n2 >> 1;
  461. ia = 0;
  462. // loop for groups
  463. for (j = 0; j < n2; j++)
  464. {
  465. cosVal = pCoef[ia * 2];
  466. sinVal = pCoef[(ia * 2) + 1];
  467. ia = ia + twidCoefModifier;
  468. // loop for butterfly
  469. for (i = j; i < fftLen; i += n1)
  470. {
  471. l = i + n2;
  472. xt = pSrc[2 * i] - pSrc[2 * l];
  473. pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U;
  474. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  475. pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U;
  476. pSrc[2U * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
  477. ((int16_t) (((q31_t) yt * sinVal) >> 16)));
  478. pSrc[2U * l + 1U] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
  479. ((int16_t) (((q31_t) xt * sinVal) >> 16)));
  480. } // butterfly loop end
  481. } // groups loop end
  482. twidCoefModifier = twidCoefModifier << 1U;
  483. } // stages loop end
  484. n1 = n2;
  485. n2 = n2 >> 1;
  486. ia = 0;
  487. cosVal = pCoef[ia * 2];
  488. sinVal = pCoef[(ia * 2) + 1];
  489. ia = ia + twidCoefModifier;
  490. // loop for butterfly
  491. for (i = 0; i < fftLen; i += n1)
  492. {
  493. l = i + n2;
  494. xt = pSrc[2 * i] - pSrc[2 * l];
  495. pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
  496. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  497. pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
  498. pSrc[2U * l] = xt;
  499. pSrc[2U * l + 1U] = yt;
  500. } // groups loop end
  501. #endif // #if defined (ARM_MATH_DSP)
  502. }