/ Drivers / CMSIS / DSP / Source / SupportFunctions / arm_q15_to_f16.c
arm_q15_to_f16.c
  1  /* ----------------------------------------------------------------------
  2   * Project:      CMSIS DSP Library
  3   * Title:        arm_q15_to_float.c
  4   * Description:  Converts the elements of the Q15 vector to floating-point vector
  5   *
  6   * $Date:        23 April 2021
  7   * $Revision:    V1.9.0
  8   *
  9   * Target Processor: Cortex-M and Cortex-A cores
 10   * -------------------------------------------------------------------- */
 11  /*
 12   * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
 13   *
 14   * SPDX-License-Identifier: Apache-2.0
 15   *
 16   * Licensed under the Apache License, Version 2.0 (the License); you may
 17   * not use this file except in compliance with the License.
 18   * You may obtain a copy of the License at
 19   *
 20   * www.apache.org/licenses/LICENSE-2.0
 21   *
 22   * Unless required by applicable law or agreed to in writing, software
 23   * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 24   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 25   * See the License for the specific language governing permissions and
 26   * limitations under the License.
 27   */
 28  
 29  #include "dsp/support_functions_f16.h"
 30  
 31  #if defined(ARM_FLOAT16_SUPPORTED)
 32  
 33  
 34  /**
 35    @ingroup groupSupport
 36   */
 37  
 38  /**
 39   * @defgroup q15_to_x  Convert 16-bit fixed point value
 40   */
 41  
 42  /**
 43    @addtogroup q15_to_x
 44    @{
 45   */
 46  
 47  /**
 48    @brief         Converts the elements of the Q15 vector to f16 vector.
 49    @param[in]     pSrc       points to the Q15 input vector
 50    @param[out]    pDst       points to the f16 output vector
 51    @param[in]     blockSize  number of samples in each vector
 52    @return        none
 53  
 54    @par           Details
 55                     The equation used for the conversion process is:
 56    <pre>
 57        pDst[n] = (float16_t) pSrc[n] / 32768;   0 <= n < blockSize.
 58    </pre>
 59   */
 60  
 61  #if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
 62  
 63  void arm_q15_to_f16(
 64    const q15_t * pSrc,
 65    float16_t * pDst,
 66    uint32_t blockSize)
 67  {
 68      int32_t  blkCnt;           /* loop counters */
 69      q15x8_t vecDst;
 70      q15_t const *pSrcVec;
 71  
 72      pSrcVec = (q15_t const *) pSrc;
 73      blkCnt = blockSize >> 3;
 74      while (blkCnt > 0)
 75      {
 76          /* C = (float16_t) A / 32768 */
 77          /* convert from q15 to float and then store the results in the destination buffer */
 78          vecDst = vld1q(pSrcVec);   pSrcVec += 8;
 79          vstrhq(pDst, vcvtq_n_f16_s16(vecDst, 15));  pDst += 8;
 80          /*
 81           * Decrement the blockSize loop counter
 82           */
 83          blkCnt--;
 84      }
 85      /*
 86       * tail
 87       * (will be merged thru tail predication)
 88       */
 89      blkCnt = blockSize & 7;
 90      if (blkCnt > 0)
 91      {
 92          mve_pred16_t p0 = vctp16q(blkCnt);
 93          vecDst = vld1q(pSrcVec);   pSrcVec += 8;
 94          vstrhq_p(pDst, vcvtq_n_f16_s16(vecDst, 15), p0);
 95      }
 96  }
 97  #else
 98  
 99  void arm_q15_to_f16(
100    const q15_t * pSrc,
101          float16_t * pDst,
102          uint32_t blockSize)
103  {
104          uint32_t blkCnt;                               /* Loop counter */
105    const q15_t *pIn = pSrc;                             /* Source pointer */
106  
107  #if defined (ARM_MATH_LOOPUNROLL)
108  
109    /* Loop unrolling: Compute 4 outputs at a time */
110    blkCnt = blockSize >> 2U;
111  
112    while (blkCnt > 0U)
113    {
114      /* C = (float16_t) A / 32768 */
115  
116      /* Convert from q15 to float and store result in destination buffer */
117      *pDst++ = ((_Float16) * pIn++ / 32768.0f16);
118      *pDst++ = ((_Float16) * pIn++ / 32768.0f16);
119      *pDst++ = ((_Float16) * pIn++ / 32768.0f16);
120      *pDst++ = ((_Float16) * pIn++ / 32768.0f16);
121  
122      /* Decrement loop counter */
123      blkCnt--;
124    }
125  
126    /* Loop unrolling: Compute remaining outputs */
127    blkCnt = blockSize % 0x4U;
128  
129  #else
130  
131    /* Initialize blkCnt with number of samples */
132    blkCnt = blockSize;
133  
134  #endif /* #if defined (ARM_MATH_LOOPUNROLL) */
135  
136    while (blkCnt > 0U)
137    {
138      /* C = (float16_t) A / 32768 */
139  
140      /* Convert from q15 to float and store result in destination buffer */
141      *pDst++ = ((_Float16) *pIn++ / 32768.0f16);
142  
143      /* Decrement loop counter */
144      blkCnt--;
145    }
146  
147  }
148  #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
149  
150  /**
151    @} end of q15_to_x group
152   */
153  
154  #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */ 
155