

#include "arm_math.h"

/**    
 * @ingroup groupStats    
 */

/**    
 * @addtogroup mean    
 * @{    
 */

/**    
 * @brief Mean value of a Q7 vector.    
 * @param[in]       *pSrc points to the input vector    
 * @param[in]       blockSize length of the input vector    
 * @param[out]      *pResult mean value returned here    
 * @return none.    
 *    
 * @details    
 * <b>Scaling and Overflow Behavior:</b>    
 * \par    
 * The function is implemented using a 32-bit internal accumulator.     
 * The input is represented in 1.7 format and is accumulated in a 32-bit    
 * accumulator in 25.7 format.    
 * There is no risk of internal overflow with this approach, and the     
 * full precision of intermediate result is preserved.     
 * Finally, the accumulator is truncated to yield a result of 1.7 format.    
 *    
 */


void arm_mean_q7(
  q7_t * pSrc,
  uint32_t blockSize,
  q7_t * pResult)
{
  q31_t sum = 0;                                 /* Temporary result storage */
  uint32_t blkCnt;                               /* loop counter */

#ifndef ARM_MATH_CM0_FAMILY

  /* Run the below code for Cortex-M4 and Cortex-M3 */
  q31_t in;

  /*loop Unrolling */
  blkCnt = blockSize >> 2u;

  /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.    
   ** a second loop below computes the remaining 1 to 3 samples. */
  while(blkCnt > 0u)
  {
    /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
    in = *__SIMD32(pSrc)++;

    sum += ((in << 24) >> 24);
    sum += ((in << 16) >> 24);
    sum += ((in << 8) >> 24);
    sum += (in >> 24);

    /* Decrement the loop counter */
    blkCnt--;
  }

  /* If the blockSize is not a multiple of 4, compute any remaining output samples here.    
   ** No loop unrolling is used. */
  blkCnt = blockSize % 0x4u;

#else

  /* Run the below code for Cortex-M0 */

  /* Loop over blockSize number of values */
  blkCnt = blockSize;

#endif /* #ifndef ARM_MATH_CM0_FAMILY */

  while(blkCnt > 0u)
  {
    /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
    sum += *pSrc++;

    /* Decrement the loop counter */
    blkCnt--;
  }

  /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize  */
  /* Store the result to the destination */
  *pResult = (q7_t) (sum / (int32_t) blockSize);
}

/**    
 * @} end of mean group    
 */
