You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /* ----------------------------------------------------------------------
  2. * Copyright (C) 2010 ARM Limited. All rights reserved.
  3. *
  4. * $Date: 29. November 2010
  5. * $Revision: V1.0.3
  6. *
  7. * Project: CMSIS DSP Library
  8. *
  9. * Title: math_helper.c
  10. *
  11. * Description: Definition of all helper functions required.
  12. *
  13. * Target Processor: Cortex-M4/Cortex-M3
  14. *
  15. * Version 1.0.3 2010/11/29
  16. * Re-organized the CMSIS folders and updated documentation.
  17. *
  18. * Version 1.0.2 2010/11/11
  19. * Documentation updated.
  20. *
  21. * Version 1.0.1 2010/10/05
  22. * Production release and review comments incorporated.
  23. *
  24. * Version 1.0.0 2010/09/20
  25. * Production release and review comments incorporated.
  26. *
  27. * Version 0.0.7 2010/06/10
  28. * Misra-C changes done
  29. * -------------------------------------------------------------------- */
  30. /* ----------------------------------------------------------------------
  31. * Include standard header files
  32. * -------------------------------------------------------------------- */
  33. #include <math.h>
  34. /* ----------------------------------------------------------------------
  35. * Include project header files
  36. * -------------------------------------------------------------------- */
  37. #include "math_helper.h"
  38. /**
  39. * @brief Caluclation of SNR
  40. * @param float* Pointer to the reference buffer
  41. * @param float* Pointer to the test buffer
  42. * @param uint32_t total number of samples
  43. * @return float SNR
  44. * The function Caluclates signal to noise ratio for the reference output
  45. * and test output
  46. */
  47. float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize)
  48. {
  49. float EnergySignal = 0.0;
  50. float EnergyError = 0.0;
  51. uint32_t i;
  52. float SNR;
  53. int temp;
  54. int *test;
  55. for (i = 0; i < buffSize; i++) {
  56. /* Checking for a NAN value in pRef array */
  57. test = (int *)(&pRef[i]);
  58. temp = *test;
  59. if (temp == 0x7FC00000) {
  60. return(0);
  61. }
  62. /* Checking for a NAN value in pTest array */
  63. test = (int *)(&pTest[i]);
  64. temp = *test;
  65. if (temp == 0x7FC00000) {
  66. return(0);
  67. }
  68. EnergySignal += pRef[i] * pRef[i];
  69. EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
  70. }
  71. /* Checking for a NAN value in EnergyError */
  72. test = (int *)(&EnergyError);
  73. temp = *test;
  74. if(temp == 0x7FC00000) {
  75. return(0);
  76. }
  77. SNR = 10 * log10f(EnergySignal / EnergyError);
  78. return (SNR);
  79. }
  80. /**
  81. * @brief Provide guard bits for Input buffer
  82. * @param q15_t* Pointer to input buffer
  83. * @param uint32_t blockSize
  84. * @param uint32_t guard_bits
  85. * @return none
  86. * The function Provides the guard bits for the buffer
  87. * to avoid overflow
  88. */
  89. void arm_provide_guard_bits_q15 (q15_t * input_buf, uint32_t blockSize,
  90. uint32_t guard_bits)
  91. {
  92. uint32_t i;
  93. for (i = 0; i < blockSize; i++)
  94. {
  95. input_buf[i] = input_buf[i] >> guard_bits;
  96. }
  97. }
  98. /**
  99. * @brief Converts float to fixed in q12.20 format
  100. * @param uint32_t number of samples in the buffer
  101. * @return none
  102. * The function converts floating point values to fixed point(q12.20) values
  103. */
  104. void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples)
  105. {
  106. uint32_t i;
  107. for (i = 0; i < numSamples; i++) {
  108. /* 1048576.0f corresponds to pow(2, 20) */
  109. pOut[i] = (q31_t) (pIn[i] * 1048576.0f);
  110. pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  111. if (pIn[i] == (float) 1.0) {
  112. pOut[i] = 0x000FFFFF;
  113. }
  114. }
  115. }
  116. /**
  117. * @brief Compare MATLAB Reference Output and ARM Test output
  118. * @param q15_t* Pointer to Ref buffer
  119. * @param q15_t* Pointer to Test buffer
  120. * @param uint32_t number of samples in the buffer
  121. * @return none
  122. */
  123. uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples)
  124. {
  125. uint32_t i;
  126. int32_t diff, diffCrnt = 0;
  127. uint32_t maxDiff = 0;
  128. for (i = 0; i < numSamples; i++)
  129. {
  130. diff = pIn[i] - pOut[i];
  131. diffCrnt = (diff > 0) ? diff : -diff;
  132. if(diffCrnt > maxDiff)
  133. {
  134. maxDiff = diffCrnt;
  135. }
  136. }
  137. return(maxDiff);
  138. }
  139. /**
  140. * @brief Compare MATLAB Reference Output and ARM Test output
  141. * @param q31_t* Pointer to Ref buffer
  142. * @param q31_t* Pointer to Test buffer
  143. * @param uint32_t number of samples in the buffer
  144. * @return none
  145. */
  146. uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples)
  147. {
  148. uint32_t i;
  149. int32_t diff, diffCrnt = 0;
  150. uint32_t maxDiff = 0;
  151. for (i = 0; i < numSamples; i++)
  152. {
  153. diff = pIn[i] - pOut[i];
  154. diffCrnt = (diff > 0) ? diff : -diff;
  155. if(diffCrnt > maxDiff)
  156. {
  157. maxDiff = diffCrnt;
  158. }
  159. }
  160. return(maxDiff);
  161. }
  162. /**
  163. * @brief Provide guard bits for Input buffer
  164. * @param q31_t* Pointer to input buffer
  165. * @param uint32_t blockSize
  166. * @param uint32_t guard_bits
  167. * @return none
  168. * The function Provides the guard bits for the buffer
  169. * to avoid overflow
  170. */
  171. void arm_provide_guard_bits_q31 (q31_t * input_buf,
  172. uint32_t blockSize,
  173. uint32_t guard_bits)
  174. {
  175. uint32_t i;
  176. for (i = 0; i < blockSize; i++)
  177. {
  178. input_buf[i] = input_buf[i] >> guard_bits;
  179. }
  180. }
  181. /**
  182. * @brief Provide guard bits for Input buffer
  183. * @param q31_t* Pointer to input buffer
  184. * @param uint32_t blockSize
  185. * @param uint32_t guard_bits
  186. * @return none
  187. * The function Provides the guard bits for the buffer
  188. * to avoid overflow
  189. */
  190. void arm_provide_guard_bits_q7 (q7_t * input_buf,
  191. uint32_t blockSize,
  192. uint32_t guard_bits)
  193. {
  194. uint32_t i;
  195. for (i = 0; i < blockSize; i++)
  196. {
  197. input_buf[i] = input_buf[i] >> guard_bits;
  198. }
  199. }
  200. /**
  201. * @brief Caluclates number of guard bits
  202. * @param uint32_t number of additions
  203. * @return none
  204. * The function Caluclates the number of guard bits
  205. * depending on the numtaps
  206. */
  207. uint32_t arm_calc_guard_bits (uint32_t num_adds)
  208. {
  209. uint32_t i = 1, j = 0;
  210. if (num_adds == 1)
  211. {
  212. return (0);
  213. }
  214. while (i < num_adds)
  215. {
  216. i = i * 2;
  217. j++;
  218. }
  219. return (j);
  220. }
  221. /**
  222. * @brief Converts Q15 to floating-point
  223. * @param uint32_t number of samples in the buffer
  224. * @return none
  225. */
  226. void arm_apply_guard_bits (float32_t * pIn,
  227. uint32_t numSamples,
  228. uint32_t guard_bits)
  229. {
  230. uint32_t i;
  231. for (i = 0; i < numSamples; i++)
  232. {
  233. pIn[i] = pIn[i] * arm_calc_2pow(guard_bits);
  234. }
  235. }
  236. /**
  237. * @brief Calculates pow(2, numShifts)
  238. * @param uint32_t number of shifts
  239. * @return pow(2, numShifts)
  240. */
  241. uint32_t arm_calc_2pow(uint32_t numShifts)
  242. {
  243. uint32_t i, val = 1;
  244. for (i = 0; i < numShifts; i++)
  245. {
  246. val = val * 2;
  247. }
  248. return(val);
  249. }
  250. /**
  251. * @brief Converts float to fixed q14
  252. * @param uint32_t number of samples in the buffer
  253. * @return none
  254. * The function converts floating point values to fixed point values
  255. */
  256. void arm_float_to_q14 (float *pIn, q15_t * pOut,
  257. uint32_t numSamples)
  258. {
  259. uint32_t i;
  260. for (i = 0; i < numSamples; i++)
  261. {
  262. /* 16384.0f corresponds to pow(2, 14) */
  263. pOut[i] = (q15_t) (pIn[i] * 16384.0f);
  264. pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  265. if (pIn[i] == (float) 2.0)
  266. {
  267. pOut[i] = 0x7FFF;
  268. }
  269. }
  270. }
  271. /**
  272. * @brief Converts float to fixed q30 format
  273. * @param uint32_t number of samples in the buffer
  274. * @return none
  275. * The function converts floating point values to fixed point values
  276. */
  277. void arm_float_to_q30 (float *pIn, q31_t * pOut,
  278. uint32_t numSamples)
  279. {
  280. uint32_t i;
  281. for (i = 0; i < numSamples; i++)
  282. {
  283. /* 1073741824.0f corresponds to pow(2, 30) */
  284. pOut[i] = (q31_t) (pIn[i] * 1073741824.0f);
  285. pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  286. if (pIn[i] == (float) 2.0)
  287. {
  288. pOut[i] = 0x7FFFFFFF;
  289. }
  290. }
  291. }
  292. /**
  293. * @brief Converts float to fixed q30 format
  294. * @param uint32_t number of samples in the buffer
  295. * @return none
  296. * The function converts floating point values to fixed point values
  297. */
  298. void arm_float_to_q29 (float *pIn, q31_t * pOut,
  299. uint32_t numSamples)
  300. {
  301. uint32_t i;
  302. for (i = 0; i < numSamples; i++)
  303. {
  304. /* 1073741824.0f corresponds to pow(2, 30) */
  305. pOut[i] = (q31_t) (pIn[i] * 536870912.0f);
  306. pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  307. if (pIn[i] == (float) 4.0)
  308. {
  309. pOut[i] = 0x7FFFFFFF;
  310. }
  311. }
  312. }
  313. /**
  314. * @brief Converts float to fixed q28 format
  315. * @param uint32_t number of samples in the buffer
  316. * @return none
  317. * The function converts floating point values to fixed point values
  318. */
  319. void arm_float_to_q28 (float *pIn, q31_t * pOut,
  320. uint32_t numSamples)
  321. {
  322. uint32_t i;
  323. for (i = 0; i < numSamples; i++)
  324. {
  325. /* 268435456.0f corresponds to pow(2, 28) */
  326. pOut[i] = (q31_t) (pIn[i] * 268435456.0f);
  327. pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  328. if (pIn[i] == (float) 8.0)
  329. {
  330. pOut[i] = 0x7FFFFFFF;
  331. }
  332. }
  333. }
  334. /**
  335. * @brief Clip the float values to +/- 1
  336. * @param pIn input buffer
  337. * @param numSamples number of samples in the buffer
  338. * @return none
  339. * The function converts floating point values to fixed point values
  340. */
  341. void arm_clip_f32 (float *pIn, uint32_t numSamples)
  342. {
  343. uint32_t i;
  344. for (i = 0; i < numSamples; i++)
  345. {
  346. if(pIn[i] > 1.0f)
  347. {
  348. pIn[i] = 1.0;
  349. }
  350. else if( pIn[i] < -1.0f)
  351. {
  352. pIn[i] = -1.0;
  353. }
  354. }
  355. }