arm_cfft_radix2_q15.c 16 KB

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