arm_bitreversal.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /* ----------------------------------------------------------------------
  2. * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
  3. *
  4. * $Date: 31. July 2014
  5. * $Revision: V1.4.4
  6. *
  7. * Project: CMSIS DSP Library
  8. * Title: arm_bitreversal.c
  9. *
  10. * Description: This file has common tables like Bitreverse, reciprocal etc which are used across different functions
  11. *
  12. * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions
  16. * are met:
  17. * - Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright
  20. * notice, this list of conditions and the following disclaimer in
  21. * the documentation and/or other materials provided with the
  22. * distribution.
  23. * - Neither the name of ARM LIMITED nor the names of its contributors
  24. * may be used to endorse or promote products derived from this
  25. * software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  28. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  29. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  30. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  31. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  32. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  33. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. * -------------------------------------------------------------------- */
  40. #include "arm_math.h"
  41. #include "arm_common_tables.h"
  42. /*
  43. * @brief In-place bit reversal function.
  44. * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
  45. * @param[in] fftSize length of the FFT.
  46. * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table.
  47. * @param[in] *pBitRevTab points to the bit reversal table.
  48. * @return none.
  49. */
  50. void arm_bitreversal_f32(
  51. float32_t * pSrc,
  52. uint16_t fftSize,
  53. uint16_t bitRevFactor,
  54. uint16_t * pBitRevTab)
  55. {
  56. uint16_t fftLenBy2, fftLenBy2p1;
  57. uint16_t i, j;
  58. float32_t in;
  59. /* Initializations */
  60. j = 0u;
  61. fftLenBy2 = fftSize >> 1u;
  62. fftLenBy2p1 = (fftSize >> 1u) + 1u;
  63. /* Bit Reversal Implementation */
  64. for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
  65. {
  66. if(i < j)
  67. {
  68. /* pSrc[i] <-> pSrc[j]; */
  69. in = pSrc[2u * i];
  70. pSrc[2u * i] = pSrc[2u * j];
  71. pSrc[2u * j] = in;
  72. /* pSrc[i+1u] <-> pSrc[j+1u] */
  73. in = pSrc[(2u * i) + 1u];
  74. pSrc[(2u * i) + 1u] = pSrc[(2u * j) + 1u];
  75. pSrc[(2u * j) + 1u] = in;
  76. /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
  77. in = pSrc[2u * (i + fftLenBy2p1)];
  78. pSrc[2u * (i + fftLenBy2p1)] = pSrc[2u * (j + fftLenBy2p1)];
  79. pSrc[2u * (j + fftLenBy2p1)] = in;
  80. /* pSrc[i+fftLenBy2p1+1u] <-> pSrc[j+fftLenBy2p1+1u] */
  81. in = pSrc[(2u * (i + fftLenBy2p1)) + 1u];
  82. pSrc[(2u * (i + fftLenBy2p1)) + 1u] =
  83. pSrc[(2u * (j + fftLenBy2p1)) + 1u];
  84. pSrc[(2u * (j + fftLenBy2p1)) + 1u] = in;
  85. }
  86. /* pSrc[i+1u] <-> pSrc[j+1u] */
  87. in = pSrc[2u * (i + 1u)];
  88. pSrc[2u * (i + 1u)] = pSrc[2u * (j + fftLenBy2)];
  89. pSrc[2u * (j + fftLenBy2)] = in;
  90. /* pSrc[i+2u] <-> pSrc[j+2u] */
  91. in = pSrc[(2u * (i + 1u)) + 1u];
  92. pSrc[(2u * (i + 1u)) + 1u] = pSrc[(2u * (j + fftLenBy2)) + 1u];
  93. pSrc[(2u * (j + fftLenBy2)) + 1u] = in;
  94. /* Reading the index for the bit reversal */
  95. j = *pBitRevTab;
  96. /* Updating the bit reversal index depending on the fft length */
  97. pBitRevTab += bitRevFactor;
  98. }
  99. }
  100. /*
  101. * @brief In-place bit reversal function.
  102. * @param[in, out] *pSrc points to the in-place buffer of Q31 data type.
  103. * @param[in] fftLen length of the FFT.
  104. * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
  105. * @param[in] *pBitRevTab points to bit reversal table.
  106. * @return none.
  107. */
  108. void arm_bitreversal_q31(
  109. q31_t * pSrc,
  110. uint32_t fftLen,
  111. uint16_t bitRevFactor,
  112. uint16_t * pBitRevTable)
  113. {
  114. uint32_t fftLenBy2, fftLenBy2p1, i, j;
  115. q31_t in;
  116. /* Initializations */
  117. j = 0u;
  118. fftLenBy2 = fftLen / 2u;
  119. fftLenBy2p1 = (fftLen / 2u) + 1u;
  120. /* Bit Reversal Implementation */
  121. for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
  122. {
  123. if(i < j)
  124. {
  125. /* pSrc[i] <-> pSrc[j]; */
  126. in = pSrc[2u * i];
  127. pSrc[2u * i] = pSrc[2u * j];
  128. pSrc[2u * j] = in;
  129. /* pSrc[i+1u] <-> pSrc[j+1u] */
  130. in = pSrc[(2u * i) + 1u];
  131. pSrc[(2u * i) + 1u] = pSrc[(2u * j) + 1u];
  132. pSrc[(2u * j) + 1u] = in;
  133. /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
  134. in = pSrc[2u * (i + fftLenBy2p1)];
  135. pSrc[2u * (i + fftLenBy2p1)] = pSrc[2u * (j + fftLenBy2p1)];
  136. pSrc[2u * (j + fftLenBy2p1)] = in;
  137. /* pSrc[i+fftLenBy2p1+1u] <-> pSrc[j+fftLenBy2p1+1u] */
  138. in = pSrc[(2u * (i + fftLenBy2p1)) + 1u];
  139. pSrc[(2u * (i + fftLenBy2p1)) + 1u] =
  140. pSrc[(2u * (j + fftLenBy2p1)) + 1u];
  141. pSrc[(2u * (j + fftLenBy2p1)) + 1u] = in;
  142. }
  143. /* pSrc[i+1u] <-> pSrc[j+1u] */
  144. in = pSrc[2u * (i + 1u)];
  145. pSrc[2u * (i + 1u)] = pSrc[2u * (j + fftLenBy2)];
  146. pSrc[2u * (j + fftLenBy2)] = in;
  147. /* pSrc[i+2u] <-> pSrc[j+2u] */
  148. in = pSrc[(2u * (i + 1u)) + 1u];
  149. pSrc[(2u * (i + 1u)) + 1u] = pSrc[(2u * (j + fftLenBy2)) + 1u];
  150. pSrc[(2u * (j + fftLenBy2)) + 1u] = in;
  151. /* Reading the index for the bit reversal */
  152. j = *pBitRevTable;
  153. /* Updating the bit reversal index depending on the fft length */
  154. pBitRevTable += bitRevFactor;
  155. }
  156. }
  157. /*
  158. * @brief In-place bit reversal function.
  159. * @param[in, out] *pSrc points to the in-place buffer of Q15 data type.
  160. * @param[in] fftLen length of the FFT.
  161. * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
  162. * @param[in] *pBitRevTab points to bit reversal table.
  163. * @return none.
  164. */
  165. void arm_bitreversal_q15(
  166. q15_t * pSrc16,
  167. uint32_t fftLen,
  168. uint16_t bitRevFactor,
  169. uint16_t * pBitRevTab)
  170. {
  171. q31_t *pSrc = (q31_t *) pSrc16;
  172. q31_t in;
  173. uint32_t fftLenBy2, fftLenBy2p1;
  174. uint32_t i, j;
  175. /* Initializations */
  176. j = 0u;
  177. fftLenBy2 = fftLen / 2u;
  178. fftLenBy2p1 = (fftLen / 2u) + 1u;
  179. /* Bit Reversal Implementation */
  180. for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
  181. {
  182. if(i < j)
  183. {
  184. /* pSrc[i] <-> pSrc[j]; */
  185. /* pSrc[i+1u] <-> pSrc[j+1u] */
  186. in = pSrc[i];
  187. pSrc[i] = pSrc[j];
  188. pSrc[j] = in;
  189. /* pSrc[i + fftLenBy2p1] <-> pSrc[j + fftLenBy2p1]; */
  190. /* pSrc[i + fftLenBy2p1+1u] <-> pSrc[j + fftLenBy2p1+1u] */
  191. in = pSrc[i + fftLenBy2p1];
  192. pSrc[i + fftLenBy2p1] = pSrc[j + fftLenBy2p1];
  193. pSrc[j + fftLenBy2p1] = in;
  194. }
  195. /* pSrc[i+1u] <-> pSrc[j+fftLenBy2]; */
  196. /* pSrc[i+2] <-> pSrc[j+fftLenBy2+1u] */
  197. in = pSrc[i + 1u];
  198. pSrc[i + 1u] = pSrc[j + fftLenBy2];
  199. pSrc[j + fftLenBy2] = in;
  200. /* Reading the index for the bit reversal */
  201. j = *pBitRevTab;
  202. /* Updating the bit reversal index depending on the fft length */
  203. pBitRevTab += bitRevFactor;
  204. }
  205. }