Subversion Repositories FuelGauge

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* ----------------------------------------------------------------------
  2. * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
  3. *
  4. * $Date:        17. January 2013
  5. * $Revision:    V1.4.0  b
  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. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions
  17. * are met:
  18. *   - Redistributions of source code must retain the above copyright
  19. *     notice, this list of conditions and the following disclaimer.
  20. *   - Redistributions in binary form must reproduce the above copyright
  21. *     notice, this list of conditions and the following disclaimer in
  22. *     the documentation and/or other materials provided with the
  23. *     distribution.
  24. *   - Neither the name of ARM LIMITED nor the names of its contributors
  25. *     may be used to endorse or promote products derived from this
  26. *     software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  29. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  30. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  31. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  32. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  33. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  34. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  36. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  37. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  38. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  39. * POSSIBILITY OF SUCH DAMAGE.
  40. * -------------------------------------------------------------------- */
  41.  
  42. /* ----------------------------------------------------------------------
  43. *               Include standard header files
  44. * -------------------------------------------------------------------- */
  45. #include<math.h>
  46.  
  47. /* ----------------------------------------------------------------------
  48. *               Include project header files
  49. * -------------------------------------------------------------------- */
  50. #include "math_helper.h"
  51.  
  52. /**
  53.  * @brief  Caluclation of SNR
  54.  * @param[in]  pRef     Pointer to the reference buffer
  55.  * @param[in]  pTest    Pointer to the test buffer
  56.  * @param[in]  buffSize total number of samples
  57.  * @return     SNR
  58.  * The function Caluclates signal to noise ratio for the reference output
  59.  * and test output
  60.  */
  61.  
  62. float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize)
  63. {
  64.   float EnergySignal = 0.0, EnergyError = 0.0;
  65.   uint32_t i;
  66.   float SNR;
  67.   int temp;
  68.   int *test;
  69.  
  70.   for (i = 0; i < buffSize; i++)
  71.     {
  72.           /* Checking for a NAN value in pRef array */
  73.           test =   (int *)(&pRef[i]);
  74.       temp =  *test;
  75.  
  76.           if (temp == 0x7FC00000)
  77.           {
  78.                         return(0);
  79.           }
  80.  
  81.           /* Checking for a NAN value in pTest array */
  82.           test =   (int *)(&pTest[i]);
  83.       temp =  *test;
  84.  
  85.           if (temp == 0x7FC00000)
  86.           {
  87.                         return(0);
  88.           }
  89.       EnergySignal += pRef[i] * pRef[i];
  90.       EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
  91.     }
  92.  
  93.         /* Checking for a NAN value in EnergyError */
  94.         test =   (int *)(&EnergyError);
  95.     temp =  *test;
  96.  
  97.     if (temp == 0x7FC00000)
  98.     {
  99.                 return(0);
  100.     }
  101.  
  102.  
  103.   SNR = 10 * log10 (EnergySignal / EnergyError);
  104.  
  105.   return (SNR);
  106.  
  107. }
  108.  
  109.  
  110. /**
  111.  * @brief  Provide guard bits for Input buffer
  112.  * @param[in,out]  input_buf   Pointer to input buffer
  113.  * @param[in]       blockSize  block Size
  114.  * @param[in]       guard_bits guard bits
  115.  * @return none
  116.  * The function Provides the guard bits for the buffer
  117.  * to avoid overflow
  118.  */
  119.  
  120. void arm_provide_guard_bits_q15 (q15_t * input_buf, uint32_t blockSize,
  121.                             uint32_t guard_bits)
  122. {
  123.   uint32_t i;
  124.  
  125.   for (i = 0; i < blockSize; i++)
  126.     {
  127.       input_buf[i] = input_buf[i] >> guard_bits;
  128.     }
  129. }
  130.  
  131. /**
  132.  * @brief  Converts float to fixed in q12.20 format
  133.  * @param[in]  pIn         pointer to input buffer
  134.  * @param[out] pOut        pointer to outputbuffer
  135.  * @param[in]  numSamples  number of samples in the input buffer
  136.  * @return none
  137.  * The function converts floating point values to fixed point(q12.20) values
  138.  */
  139.  
  140. void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples)
  141. {
  142.   uint32_t i;
  143.  
  144.   for (i = 0; i < numSamples; i++)
  145.     {
  146.           /* 1048576.0f corresponds to pow(2, 20) */
  147.       pOut[i] = (q31_t) (pIn[i] * 1048576.0f);
  148.  
  149.       pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  150.  
  151.       if (pIn[i] == (float) 1.0)
  152.         {
  153.           pOut[i] = 0x000FFFFF;
  154.         }
  155.     }
  156. }
  157.  
  158. /**
  159.  * @brief  Compare MATLAB Reference Output and ARM Test output
  160.  * @param[in]  pIn         Pointer to Ref buffer
  161.  * @param[in]  pOut        Pointer to Test buffer
  162.  * @param[in]  numSamples  number of samples in the buffer
  163.  * @return maximum difference
  164.  */
  165.  
  166. uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t *pOut, uint32_t numSamples)
  167. {
  168.   uint32_t i;
  169.   int32_t diff, diffCrnt = 0;
  170.   uint32_t maxDiff = 0;
  171.  
  172.   for (i = 0; i < numSamples; i++)
  173.   {
  174.         diff = pIn[i] - pOut[i];
  175.         diffCrnt = (diff > 0) ? diff : -diff;
  176.  
  177.         if (diffCrnt > maxDiff)
  178.         {
  179.                 maxDiff = diffCrnt;
  180.         }
  181.   }
  182.  
  183.   return(maxDiff);
  184. }
  185.  
  186. /**
  187.  * @brief  Compare MATLAB Reference Output and ARM Test output
  188.  * @param[in]  pIn         Pointer to Ref buffer
  189.  * @param[in]  pOut        Pointer to Test buffer
  190.  * @param[in]  numSamples number of samples in the buffer
  191.  * @return maximum difference
  192.  */
  193.  
  194. uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples)
  195. {
  196.   uint32_t i;
  197.   int32_t diff, diffCrnt = 0;
  198.   uint32_t maxDiff = 0;
  199.  
  200.   for (i = 0; i < numSamples; i++)
  201.   {
  202.         diff = pIn[i] - pOut[i];
  203.         diffCrnt = (diff > 0) ? diff : -diff;
  204.  
  205.         if (diffCrnt > maxDiff)
  206.         {
  207.                 maxDiff = diffCrnt;
  208.         }
  209.   }
  210.  
  211.   return(maxDiff);
  212. }
  213.  
  214. /**
  215.  * @brief  Provide guard bits for Input buffer
  216.  * @param[in,out]  input_buf   Pointer to input buffer
  217.  * @param[in]       blockSize  block Size
  218.  * @param[in]       guard_bits guard bits
  219.  * @return none
  220.  * The function Provides the guard bits for the buffer
  221.  * to avoid overflow
  222.  */
  223.  
  224. void arm_provide_guard_bits_q31 (q31_t * input_buf,
  225.                                                                  uint32_t blockSize,
  226.                                  uint32_t guard_bits)
  227. {
  228.   uint32_t i;
  229.  
  230.   for (i = 0; i < blockSize; i++)
  231.     {
  232.       input_buf[i] = input_buf[i] >> guard_bits;
  233.     }
  234. }
  235.  
  236. /**
  237.  * @brief  Provide guard bits for Input buffer
  238.  * @param[in,out]  input_buf   Pointer to input buffer
  239.  * @param[in]       blockSize  block Size
  240.  * @param[in]       guard_bits guard bits
  241.  * @return none
  242.  * The function Provides the guard bits for the buffer
  243.  * to avoid overflow
  244.  */
  245.  
  246. void arm_provide_guard_bits_q7 (q7_t * input_buf,
  247.                                                                 uint32_t blockSize,
  248.                                 uint32_t guard_bits)
  249. {
  250.   uint32_t i;
  251.  
  252.   for (i = 0; i < blockSize; i++)
  253.     {
  254.       input_buf[i] = input_buf[i] >> guard_bits;
  255.     }
  256. }
  257.  
  258.  
  259.  
  260. /**
  261.  * @brief  Caluclates number of guard bits
  262.  * @param[in]  num_adds         number of additions
  263.  * @return guard bits
  264.  * The function Caluclates the number of guard bits
  265.  * depending on the numtaps
  266.  */
  267.  
  268. uint32_t arm_calc_guard_bits (uint32_t num_adds)
  269. {
  270.   uint32_t i = 1, j = 0;
  271.  
  272.   if (num_adds == 1)
  273.     {
  274.       return (0);
  275.     }
  276.  
  277.   while (i < num_adds)
  278.     {
  279.       i = i * 2;
  280.       j++;
  281.     }
  282.  
  283.   return (j);
  284. }
  285.  
  286. /**
  287.  * @brief  Apply guard bits to buffer
  288.  * @param[in,out]  pIn         pointer to input buffer
  289.  * @param[in]      numSamples  number of samples in the input buffer
  290.  * @param[in]      guard_bits  guard bits
  291.  * @return none
  292.  */
  293.  
  294. void arm_apply_guard_bits (float32_t *pIn,
  295.                                                    uint32_t numSamples,
  296.                                                    uint32_t guard_bits)
  297. {
  298.   uint32_t i;
  299.  
  300.   for (i = 0; i < numSamples; i++)
  301.     {
  302.       pIn[i] = pIn[i] * arm_calc_2pow(guard_bits);
  303.     }
  304. }
  305.  
  306. /**
  307.  * @brief  Calculates pow(2, numShifts)
  308.  * @param[in]  numShifts        number of shifts
  309.  * @return pow(2, numShifts)
  310.  */
  311. uint32_t arm_calc_2pow(uint32_t numShifts)
  312. {
  313.  
  314.   uint32_t i, val = 1;
  315.  
  316.   for (i = 0; i < numShifts; i++)
  317.     {
  318.       val = val * 2;
  319.     }
  320.  
  321.   return(val);
  322. }
  323.  
  324.  
  325.  
  326. /**
  327.  * @brief  Converts float to fixed q14
  328.  * @param[in]  pIn         pointer to input buffer
  329.  * @param[out] pOut        pointer to output buffer
  330.  * @param[in]  numSamples  number of samples in the buffer
  331.  * @return none
  332.  * The function converts floating point values to fixed point values
  333.  */
  334.  
  335. void arm_float_to_q14 (float *pIn, q15_t *pOut, uint32_t numSamples)
  336. {
  337.   uint32_t i;
  338.  
  339.   for (i = 0; i < numSamples; i++)
  340.     {
  341.           /* 16384.0f corresponds to pow(2, 14) */
  342.       pOut[i] = (q15_t) (pIn[i] * 16384.0f);
  343.  
  344.       pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  345.  
  346.       if (pIn[i] == (float) 2.0)
  347.         {
  348.           pOut[i] = 0x7FFF;
  349.         }
  350.  
  351.     }
  352.  
  353. }
  354.  
  355.  
  356. /**
  357.  * @brief  Converts float to fixed q30 format
  358.  * @param[in]  pIn         pointer to input buffer
  359.  * @param[out] pOut        pointer to output buffer
  360.  * @param[in]  numSamples  number of samples in the buffer
  361.  * @return none
  362.  * The function converts floating point values to fixed point values
  363.  */
  364.  
  365. void arm_float_to_q30 (float *pIn, q31_t * pOut, uint32_t numSamples)
  366. {
  367.   uint32_t i;
  368.  
  369.   for (i = 0; i < numSamples; i++)
  370.     {
  371.           /* 1073741824.0f corresponds to pow(2, 30) */
  372.       pOut[i] = (q31_t) (pIn[i] * 1073741824.0f);
  373.  
  374.       pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  375.  
  376.       if (pIn[i] == (float) 2.0)
  377.         {
  378.           pOut[i] = 0x7FFFFFFF;
  379.         }
  380.     }
  381. }
  382.  
  383. /**
  384.  * @brief  Converts float to fixed q30 format
  385.  * @param[in]  pIn         pointer to input buffer
  386.  * @param[out] pOut        pointer to output buffer
  387.  * @param[in]  numSamples  number of samples in the buffer
  388.  * @return none
  389.  * The function converts floating point values to fixed point values
  390.  */
  391.  
  392. void arm_float_to_q29 (float *pIn, q31_t *pOut, uint32_t numSamples)
  393. {
  394.   uint32_t i;
  395.  
  396.   for (i = 0; i < numSamples; i++)
  397.     {
  398.           /* 1073741824.0f corresponds to pow(2, 30) */
  399.       pOut[i] = (q31_t) (pIn[i] * 536870912.0f);
  400.  
  401.       pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  402.  
  403.       if (pIn[i] == (float) 4.0)
  404.         {
  405.           pOut[i] = 0x7FFFFFFF;
  406.         }
  407.     }
  408. }
  409.  
  410.  
  411. /**
  412.  * @brief  Converts float to fixed q28 format
  413.  * @param[in]  pIn         pointer to input buffer
  414.  * @param[out] pOut        pointer to output buffer
  415.  * @param[in]  numSamples  number of samples in the buffer
  416.  * @return none
  417.  * The function converts floating point values to fixed point values
  418.  */
  419.  
  420. void arm_float_to_q28 (float *pIn, q31_t *pOut, uint32_t numSamples)
  421. {
  422.   uint32_t i;
  423.  
  424.   for (i = 0; i < numSamples; i++)
  425.     {
  426.         /* 268435456.0f corresponds to pow(2, 28) */
  427.       pOut[i] = (q31_t) (pIn[i] * 268435456.0f);
  428.  
  429.       pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
  430.  
  431.       if (pIn[i] == (float) 8.0)
  432.         {
  433.           pOut[i] = 0x7FFFFFFF;
  434.         }
  435.     }
  436. }
  437.  
  438. /**
  439.  * @brief  Clip the float values to +/- 1
  440.  * @param[in,out]  pIn           input buffer
  441.  * @param[in]      numSamples    number of samples in the buffer
  442.  * @return none
  443.  * The function converts floating point values to fixed point values
  444.  */
  445.  
  446. void arm_clip_f32 (float *pIn, uint32_t numSamples)
  447. {
  448.   uint32_t i;
  449.  
  450.   for (i = 0; i < numSamples; i++)
  451.     {
  452.       if (pIn[i] > 1.0f)
  453.           {
  454.             pIn[i] = 1.0;
  455.           }
  456.           else if ( pIn[i] < -1.0f)
  457.           {
  458.             pIn[i] = -1.0;
  459.           }
  460.  
  461.     }
  462. }
  463.  
  464.  
  465.  
  466.  
  467.