arm_cfft_radix2_f32.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. /* ----------------------------------------------------------------------
  2. * Project: CMSIS DSP Library
  3. * Title: arm_cfft_radix2_f32.c
  4. * Description: Radix-2 Decimation in Frequency CFFT & CIFFT Floating 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_f32(
  30. float32_t * pSrc,
  31. uint32_t fftLen,
  32. float32_t * pCoef,
  33. uint16_t twidCoefModifier);
  34. void arm_radix2_butterfly_inverse_f32(
  35. float32_t * pSrc,
  36. uint32_t fftLen,
  37. float32_t * pCoef,
  38. uint16_t twidCoefModifier,
  39. float32_t onebyfftLen);
  40. extern void arm_bitreversal_f32(
  41. float32_t * pSrc,
  42. uint16_t fftSize,
  43. uint16_t bitRevFactor,
  44. uint16_t * pBitRevTab);
  45. /**
  46. * @ingroup groupTransforms
  47. */
  48. /**
  49. * @addtogroup ComplexFFT
  50. * @{
  51. */
  52. /**
  53. * @details
  54. * @brief Radix-2 CFFT/CIFFT.
  55. * @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed
  56. * in the future.
  57. * @param[in] *S points to an instance of the floating-point Radix-2 CFFT/CIFFT structure.
  58. * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
  59. * @return none.
  60. */
  61. void arm_cfft_radix2_f32(
  62. const arm_cfft_radix2_instance_f32 * S,
  63. float32_t * pSrc)
  64. {
  65. if (S->ifftFlag == 1U)
  66. {
  67. /* Complex IFFT radix-2 */
  68. arm_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
  69. S->twidCoefModifier, S->onebyfftLen);
  70. }
  71. else
  72. {
  73. /* Complex FFT radix-2 */
  74. arm_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
  75. S->twidCoefModifier);
  76. }
  77. if (S->bitReverseFlag == 1U)
  78. {
  79. /* Bit Reversal */
  80. arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
  81. }
  82. }
  83. /**
  84. * @} end of ComplexFFT group
  85. */
  86. /* ----------------------------------------------------------------------
  87. ** Internal helper function used by the FFTs
  88. ** ------------------------------------------------------------------- */
  89. /*
  90. * @brief Core function for the floating-point CFFT butterfly process.
  91. * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
  92. * @param[in] fftLen length of the FFT.
  93. * @param[in] *pCoef points to the twiddle coefficient buffer.
  94. * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
  95. * @return none.
  96. */
  97. void arm_radix2_butterfly_f32(
  98. float32_t * pSrc,
  99. uint32_t fftLen,
  100. float32_t * pCoef,
  101. uint16_t twidCoefModifier)
  102. {
  103. uint32_t i, j, k, l;
  104. uint32_t n1, n2, ia;
  105. float32_t xt, yt, cosVal, sinVal;
  106. float32_t p0, p1, p2, p3;
  107. float32_t a0, a1;
  108. #if defined (ARM_MATH_DSP)
  109. /* Initializations for the first stage */
  110. n2 = fftLen >> 1;
  111. ia = 0;
  112. i = 0;
  113. // loop for groups
  114. for (k = n2; k > 0; k--)
  115. {
  116. cosVal = pCoef[ia * 2];
  117. sinVal = pCoef[(ia * 2) + 1];
  118. /* Twiddle coefficients index modifier */
  119. ia += twidCoefModifier;
  120. /* index calculation for the input as, */
  121. /* pSrc[i + 0], pSrc[i + fftLen/1] */
  122. l = i + n2;
  123. /* Butterfly implementation */
  124. a0 = pSrc[2 * i] + pSrc[2 * l];
  125. xt = pSrc[2 * i] - pSrc[2 * l];
  126. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  127. a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  128. p0 = xt * cosVal;
  129. p1 = yt * sinVal;
  130. p2 = yt * cosVal;
  131. p3 = xt * sinVal;
  132. pSrc[2 * i] = a0;
  133. pSrc[2 * i + 1] = a1;
  134. pSrc[2 * l] = p0 + p1;
  135. pSrc[2 * l + 1] = p2 - p3;
  136. i++;
  137. } // groups loop end
  138. twidCoefModifier <<= 1U;
  139. // loop for stage
  140. for (k = n2; k > 2; k = k >> 1)
  141. {
  142. n1 = n2;
  143. n2 = n2 >> 1;
  144. ia = 0;
  145. // loop for groups
  146. j = 0;
  147. do
  148. {
  149. cosVal = pCoef[ia * 2];
  150. sinVal = pCoef[(ia * 2) + 1];
  151. ia += twidCoefModifier;
  152. // loop for butterfly
  153. i = j;
  154. do
  155. {
  156. l = i + n2;
  157. a0 = pSrc[2 * i] + pSrc[2 * l];
  158. xt = pSrc[2 * i] - pSrc[2 * l];
  159. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  160. a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  161. p0 = xt * cosVal;
  162. p1 = yt * sinVal;
  163. p2 = yt * cosVal;
  164. p3 = xt * sinVal;
  165. pSrc[2 * i] = a0;
  166. pSrc[2 * i + 1] = a1;
  167. pSrc[2 * l] = p0 + p1;
  168. pSrc[2 * l + 1] = p2 - p3;
  169. i += n1;
  170. } while ( i < fftLen ); // butterfly loop end
  171. j++;
  172. } while ( j < n2); // groups loop end
  173. twidCoefModifier <<= 1U;
  174. } // stages loop end
  175. // loop for butterfly
  176. for (i = 0; i < fftLen; i += 2)
  177. {
  178. a0 = pSrc[2 * i] + pSrc[2 * i + 2];
  179. xt = pSrc[2 * i] - pSrc[2 * i + 2];
  180. yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
  181. a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
  182. pSrc[2 * i] = a0;
  183. pSrc[2 * i + 1] = a1;
  184. pSrc[2 * i + 2] = xt;
  185. pSrc[2 * i + 3] = yt;
  186. } // groups loop end
  187. #else
  188. n2 = fftLen;
  189. // loop for stage
  190. for (k = fftLen; k > 1; k = k >> 1)
  191. {
  192. n1 = n2;
  193. n2 = n2 >> 1;
  194. ia = 0;
  195. // loop for groups
  196. j = 0;
  197. do
  198. {
  199. cosVal = pCoef[ia * 2];
  200. sinVal = pCoef[(ia * 2) + 1];
  201. ia += twidCoefModifier;
  202. // loop for butterfly
  203. i = j;
  204. do
  205. {
  206. l = i + n2;
  207. a0 = pSrc[2 * i] + pSrc[2 * l];
  208. xt = pSrc[2 * i] - pSrc[2 * l];
  209. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  210. a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  211. p0 = xt * cosVal;
  212. p1 = yt * sinVal;
  213. p2 = yt * cosVal;
  214. p3 = xt * sinVal;
  215. pSrc[2 * i] = a0;
  216. pSrc[2 * i + 1] = a1;
  217. pSrc[2 * l] = p0 + p1;
  218. pSrc[2 * l + 1] = p2 - p3;
  219. i += n1;
  220. } while (i < fftLen);
  221. j++;
  222. } while (j < n2);
  223. twidCoefModifier <<= 1U;
  224. }
  225. #endif // #if defined (ARM_MATH_DSP)
  226. }
  227. void arm_radix2_butterfly_inverse_f32(
  228. float32_t * pSrc,
  229. uint32_t fftLen,
  230. float32_t * pCoef,
  231. uint16_t twidCoefModifier,
  232. float32_t onebyfftLen)
  233. {
  234. uint32_t i, j, k, l;
  235. uint32_t n1, n2, ia;
  236. float32_t xt, yt, cosVal, sinVal;
  237. float32_t p0, p1, p2, p3;
  238. float32_t a0, a1;
  239. #if defined (ARM_MATH_DSP)
  240. n2 = fftLen >> 1;
  241. ia = 0;
  242. // loop for groups
  243. for (i = 0; i < n2; i++)
  244. {
  245. cosVal = pCoef[ia * 2];
  246. sinVal = pCoef[(ia * 2) + 1];
  247. ia += twidCoefModifier;
  248. l = i + n2;
  249. a0 = pSrc[2 * i] + pSrc[2 * l];
  250. xt = pSrc[2 * i] - pSrc[2 * l];
  251. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  252. a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  253. p0 = xt * cosVal;
  254. p1 = yt * sinVal;
  255. p2 = yt * cosVal;
  256. p3 = xt * sinVal;
  257. pSrc[2 * i] = a0;
  258. pSrc[2 * i + 1] = a1;
  259. pSrc[2 * l] = p0 - p1;
  260. pSrc[2 * l + 1] = p2 + p3;
  261. } // groups loop end
  262. twidCoefModifier <<= 1U;
  263. // loop for stage
  264. for (k = fftLen / 2; k > 2; k = k >> 1)
  265. {
  266. n1 = n2;
  267. n2 = n2 >> 1;
  268. ia = 0;
  269. // loop for groups
  270. j = 0;
  271. do
  272. {
  273. cosVal = pCoef[ia * 2];
  274. sinVal = pCoef[(ia * 2) + 1];
  275. ia += twidCoefModifier;
  276. // loop for butterfly
  277. i = j;
  278. do
  279. {
  280. l = i + n2;
  281. a0 = pSrc[2 * i] + pSrc[2 * l];
  282. xt = pSrc[2 * i] - pSrc[2 * l];
  283. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  284. a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  285. p0 = xt * cosVal;
  286. p1 = yt * sinVal;
  287. p2 = yt * cosVal;
  288. p3 = xt * sinVal;
  289. pSrc[2 * i] = a0;
  290. pSrc[2 * i + 1] = a1;
  291. pSrc[2 * l] = p0 - p1;
  292. pSrc[2 * l + 1] = p2 + p3;
  293. i += n1;
  294. } while ( i < fftLen ); // butterfly loop end
  295. j++;
  296. } while (j < n2); // groups loop end
  297. twidCoefModifier <<= 1U;
  298. } // stages loop end
  299. // loop for butterfly
  300. for (i = 0; i < fftLen; i += 2)
  301. {
  302. a0 = pSrc[2 * i] + pSrc[2 * i + 2];
  303. xt = pSrc[2 * i] - pSrc[2 * i + 2];
  304. a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
  305. yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
  306. p0 = a0 * onebyfftLen;
  307. p2 = xt * onebyfftLen;
  308. p1 = a1 * onebyfftLen;
  309. p3 = yt * onebyfftLen;
  310. pSrc[2 * i] = p0;
  311. pSrc[2 * i + 1] = p1;
  312. pSrc[2 * i + 2] = p2;
  313. pSrc[2 * i + 3] = p3;
  314. } // butterfly loop end
  315. #else
  316. n2 = fftLen;
  317. // loop for stage
  318. for (k = fftLen; k > 2; k = k >> 1)
  319. {
  320. n1 = n2;
  321. n2 = n2 >> 1;
  322. ia = 0;
  323. // loop for groups
  324. j = 0;
  325. do
  326. {
  327. cosVal = pCoef[ia * 2];
  328. sinVal = pCoef[(ia * 2) + 1];
  329. ia = ia + twidCoefModifier;
  330. // loop for butterfly
  331. i = j;
  332. do
  333. {
  334. l = i + n2;
  335. a0 = pSrc[2 * i] + pSrc[2 * l];
  336. xt = pSrc[2 * i] - pSrc[2 * l];
  337. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  338. a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  339. p0 = xt * cosVal;
  340. p1 = yt * sinVal;
  341. p2 = yt * cosVal;
  342. p3 = xt * sinVal;
  343. pSrc[2 * i] = a0;
  344. pSrc[2 * i + 1] = a1;
  345. pSrc[2 * l] = p0 - p1;
  346. pSrc[2 * l + 1] = p2 + p3;
  347. i += n1;
  348. } while ( i < fftLen ); // butterfly loop end
  349. j++;
  350. } while ( j < n2 ); // groups loop end
  351. twidCoefModifier = twidCoefModifier << 1U;
  352. } // stages loop end
  353. n1 = n2;
  354. n2 = n2 >> 1;
  355. // loop for butterfly
  356. for (i = 0; i < fftLen; i += n1)
  357. {
  358. l = i + n2;
  359. a0 = pSrc[2 * i] + pSrc[2 * l];
  360. xt = pSrc[2 * i] - pSrc[2 * l];
  361. a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  362. yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  363. p0 = a0 * onebyfftLen;
  364. p2 = xt * onebyfftLen;
  365. p1 = a1 * onebyfftLen;
  366. p3 = yt * onebyfftLen;
  367. pSrc[2 * i] = p0;
  368. pSrc[2U * l] = p2;
  369. pSrc[2 * i + 1] = p1;
  370. pSrc[2U * l + 1U] = p3;
  371. } // butterfly loop end
  372. #endif // #if defined (ARM_MATH_DSP)
  373. }