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.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  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, EnergyError = 0.0;
  50. uint32_t i;
  51. float SNR;
  52. int temp;
  53. int *test;
  54. for (i = 0; i < buffSize; i++)
  55. {
  56. /* Checking for a NAN value in pRef array */
  57. test = (int *)(&pRef[i]);
  58. temp = *test;
  59. if(temp == 0x7FC00000)
  60. {
  61. return(0);
  62. }
  63. /* Checking for a NAN value in pTest array */
  64. test = (int *)(&pTest[i]);
  65. temp = *test;
  66. if(temp == 0x7FC00000)
  67. {
  68. return(0);
  69. }
  70. EnergySignal += pRef[i] * pRef[i];
  71. EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
  72. }
  73. /* Checking for a NAN value in EnergyError */
  74. test = (int *)(&EnergyError);
  75. temp = *test;
  76. if(temp == 0x7FC00000)
  77. {
  78. return(0);
  79. }
  80. SNR = 10 * log10 (EnergySignal / EnergyError);
  81. return (SNR);
  82. }
  83. /**
  84. * @brief Provide guard bits for Input buffer
  85. * @param q15_t* Pointer to input buffer
  86. * @param uint32_t blockSize
  87. * @param uint32_t guard_bits
  88. * @return none
  89. * The function Provides the guard bits for the buffer
  90. * to avoid overflow
  91. */
  92. void arm_provide_guard_bits_q15 (q15_t * input_buf, uint32_t blockSize,
  93. uint32_t guard_bits)
  94. {
  95. uint32_t i;
  96. for (i = 0; i < blockSize; i++)
  97. {
  98. input_buf[i] = input_buf[i] >> guard_bits;
  99. }
  100. }
  101. /**
  102. * @brief Converts float to fixed in q12.20 format
  103. * @param uint32_t number of samples in the buffer
  104. * @return none
  105. * The function converts floating point values to fixed point(q12.20) values
  106. */
  107. void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples)
  108. {
  109. uint32_t i;
  110. for (i = 0; i < numSamples; i++)
  111. {
  112. /* 1048576.0f corresponds to pow(2, 20) */
  113. pOut[i] = (q31_t) (pIn[i] * 1048576.0f);
  114. pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  115. if (pIn[i] == (float) 1.0)
  116. {
  117. pOut[i] = 0x000FFFFF;
  118. }
  119. }
  120. }
  121. /**
  122. * @brief Compare MATLAB Reference Output and ARM Test output
  123. * @param q15_t* Pointer to Ref buffer
  124. * @param q15_t* Pointer to Test buffer
  125. * @param uint32_t number of samples in the buffer
  126. * @return none
  127. */
  128. uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples)
  129. {
  130. uint32_t i;
  131. int32_t diff, diffCrnt = 0;
  132. uint32_t maxDiff = 0;
  133. for (i = 0; i < numSamples; i++)
  134. {
  135. diff = pIn[i] - pOut[i];
  136. diffCrnt = (diff > 0) ? diff : -diff;
  137. if(diffCrnt > maxDiff)
  138. {
  139. maxDiff = diffCrnt;
  140. }
  141. }
  142. return(maxDiff);
  143. }
  144. /**
  145. * @brief Compare MATLAB Reference Output and ARM Test output
  146. * @param q31_t* Pointer to Ref buffer
  147. * @param q31_t* Pointer to Test buffer
  148. * @param uint32_t number of samples in the buffer
  149. * @return none
  150. */
  151. uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples)
  152. {
  153. uint32_t i;
  154. int32_t diff, diffCrnt = 0;
  155. uint32_t maxDiff = 0;
  156. for (i = 0; i < numSamples; i++)
  157. {
  158. diff = pIn[i] - pOut[i];
  159. diffCrnt = (diff > 0) ? diff : -diff;
  160. if(diffCrnt > maxDiff)
  161. {
  162. maxDiff = diffCrnt;
  163. }
  164. }
  165. return(maxDiff);
  166. }
  167. /**
  168. * @brief Provide guard bits for Input buffer
  169. * @param q31_t* Pointer to input buffer
  170. * @param uint32_t blockSize
  171. * @param uint32_t guard_bits
  172. * @return none
  173. * The function Provides the guard bits for the buffer
  174. * to avoid overflow
  175. */
  176. void arm_provide_guard_bits_q31 (q31_t * input_buf,
  177. uint32_t blockSize,
  178. uint32_t guard_bits)
  179. {
  180. uint32_t i;
  181. for (i = 0; i < blockSize; i++)
  182. {
  183. input_buf[i] = input_buf[i] >> guard_bits;
  184. }
  185. }
  186. /**
  187. * @brief Provide guard bits for Input buffer
  188. * @param q31_t* Pointer to input buffer
  189. * @param uint32_t blockSize
  190. * @param uint32_t guard_bits
  191. * @return none
  192. * The function Provides the guard bits for the buffer
  193. * to avoid overflow
  194. */
  195. void arm_provide_guard_bits_q7 (q7_t * input_buf,
  196. uint32_t blockSize,
  197. uint32_t guard_bits)
  198. {
  199. uint32_t i;
  200. for (i = 0; i < blockSize; i++)
  201. {
  202. input_buf[i] = input_buf[i] >> guard_bits;
  203. }
  204. }
  205. /**
  206. * @brief Caluclates number of guard bits
  207. * @param uint32_t number of additions
  208. * @return none
  209. * The function Caluclates the number of guard bits
  210. * depending on the numtaps
  211. */
  212. uint32_t arm_calc_guard_bits (uint32_t num_adds)
  213. {
  214. uint32_t i = 1, j = 0;
  215. if (num_adds == 1)
  216. {
  217. return (0);
  218. }
  219. while (i < num_adds)
  220. {
  221. i = i * 2;
  222. j++;
  223. }
  224. return (j);
  225. }
  226. /**
  227. * @brief Converts Q15 to floating-point
  228. * @param uint32_t number of samples in the buffer
  229. * @return none
  230. */
  231. void arm_apply_guard_bits (float32_t * pIn,
  232. uint32_t numSamples,
  233. uint32_t guard_bits)
  234. {
  235. uint32_t i;
  236. for (i = 0; i < numSamples; i++)
  237. {
  238. pIn[i] = pIn[i] * arm_calc_2pow(guard_bits);
  239. }
  240. }
  241. /**
  242. * @brief Calculates pow(2, numShifts)
  243. * @param uint32_t number of shifts
  244. * @return pow(2, numShifts)
  245. */
  246. uint32_t arm_calc_2pow(uint32_t numShifts)
  247. {
  248. uint32_t i, val = 1;
  249. for (i = 0; i < numShifts; i++)
  250. {
  251. val = val * 2;
  252. }
  253. return(val);
  254. }
  255. /**
  256. * @brief Converts float to fixed q14
  257. * @param uint32_t number of samples in the buffer
  258. * @return none
  259. * The function converts floating point values to fixed point values
  260. */
  261. void arm_float_to_q14 (float *pIn, q15_t * pOut,
  262. uint32_t numSamples)
  263. {
  264. uint32_t i;
  265. for (i = 0; i < numSamples; i++)
  266. {
  267. /* 16384.0f corresponds to pow(2, 14) */
  268. pOut[i] = (q15_t) (pIn[i] * 16384.0f);
  269. pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  270. if (pIn[i] == (float) 2.0)
  271. {
  272. pOut[i] = 0x7FFF;
  273. }
  274. }
  275. }
  276. /**
  277. * @brief Converts float to fixed q30 format
  278. * @param uint32_t number of samples in the buffer
  279. * @return none
  280. * The function converts floating point values to fixed point values
  281. */
  282. void arm_float_to_q30 (float *pIn, q31_t * pOut,
  283. uint32_t numSamples)
  284. {
  285. uint32_t i;
  286. for (i = 0; i < numSamples; i++)
  287. {
  288. /* 1073741824.0f corresponds to pow(2, 30) */
  289. pOut[i] = (q31_t) (pIn[i] * 1073741824.0f);
  290. pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  291. if (pIn[i] == (float) 2.0)
  292. {
  293. pOut[i] = 0x7FFFFFFF;
  294. }
  295. }
  296. }
  297. /**
  298. * @brief Converts float to fixed q30 format
  299. * @param uint32_t number of samples in the buffer
  300. * @return none
  301. * The function converts floating point values to fixed point values
  302. */
  303. void arm_float_to_q29 (float *pIn, q31_t * pOut,
  304. uint32_t numSamples)
  305. {
  306. uint32_t i;
  307. for (i = 0; i < numSamples; i++)
  308. {
  309. /* 1073741824.0f corresponds to pow(2, 30) */
  310. pOut[i] = (q31_t) (pIn[i] * 536870912.0f);
  311. pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  312. if (pIn[i] == (float) 4.0)
  313. {
  314. pOut[i] = 0x7FFFFFFF;
  315. }
  316. }
  317. }
  318. /**
  319. * @brief Converts float to fixed q28 format
  320. * @param uint32_t number of samples in the buffer
  321. * @return none
  322. * The function converts floating point values to fixed point values
  323. */
  324. void arm_float_to_q28 (float *pIn, q31_t * pOut,
  325. uint32_t numSamples)
  326. {
  327. uint32_t i;
  328. for (i = 0; i < numSamples; i++)
  329. {
  330. /* 268435456.0f corresponds to pow(2, 28) */
  331. pOut[i] = (q31_t) (pIn[i] * 268435456.0f);
  332. pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  333. if (pIn[i] == (float) 8.0)
  334. {
  335. pOut[i] = 0x7FFFFFFF;
  336. }
  337. }
  338. }
  339. /**
  340. * @brief Clip the float values to +/- 1
  341. * @param pIn input buffer
  342. * @param numSamples number of samples in the buffer
  343. * @return none
  344. * The function converts floating point values to fixed point values
  345. */
  346. void arm_clip_f32 (float *pIn, uint32_t numSamples)
  347. {
  348. uint32_t i;
  349. for (i = 0; i < numSamples; i++)
  350. {
  351. if(pIn[i] > 1.0f)
  352. {
  353. pIn[i] = 1.0;
  354. }
  355. else if( pIn[i] < -1.0f)
  356. {
  357. pIn[i] = -1.0;
  358. }
  359. }
  360. }