Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

math_helper.c 9.5KB

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. }