/ Drivers / CMSIS / DSP / Source / SupportFunctions / arm_q15_to_float.c
arm_q15_to_float.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.h"
 30  
 31  /**
 32    @ingroup groupSupport
 33   */
 34  
 35  /**
 36   * @defgroup q15_to_x  Convert 16-bit fixed point value
 37   */
 38  
 39  /**
 40    @addtogroup q15_to_x
 41    @{
 42   */
 43  
 44  /**
 45    @brief         Converts the elements of the Q15 vector to floating-point vector.
 46    @param[in]     pSrc       points to the Q15 input vector
 47    @param[out]    pDst       points to the floating-point output vector
 48    @param[in]     blockSize  number of samples in each vector
 49    @return        none
 50  
 51    @par           Details
 52                     The equation used for the conversion process is:
 53    <pre>
 54        pDst[n] = (float32_t) pSrc[n] / 32768;   0 <= n < blockSize.
 55    </pre>
 56   */
 57  
 58  #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
 59  void arm_q15_to_float(
 60    const q15_t * pSrc,
 61    float32_t * pDst,
 62    uint32_t blockSize)
 63  {
 64    uint32_t blkCnt;
 65  
 66    q15x8_t vecDst;
 67    q15_t const *pSrcVec;
 68  
 69    pSrcVec = (q15_t const *) pSrc;
 70    blkCnt = blockSize >> 2;
 71    while (blkCnt > 0U)
 72    {
 73        /* C = (float32_t) A / 32768 */
 74        /* convert from q15 to float and then store the results in the destination buffer */
 75        vecDst = vldrhq_s32(pSrcVec);
 76        pSrcVec += 4;
 77        vstrwq(pDst, vcvtq_n_f32_s32((int32x4_t)vecDst, 15));
 78        pDst += 4;
 79        /*
 80         * Decrement the blockSize loop counter
 81         */
 82        blkCnt--;
 83    }
 84  
 85    blkCnt = blockSize & 3;
 86    while (blkCnt > 0U)
 87    {
 88      /* C = (float32_t) A / 32768 */
 89  
 90      /* Convert from q15 to float and store result in destination buffer */
 91      *pDst++ = ((float32_t) *pSrcVec++ / 32768.0f);
 92  
 93      /* Decrement loop counter */
 94      blkCnt--;
 95    }
 96  }
 97  #else
 98  #if defined(ARM_MATH_NEON_EXPERIMENTAL)
 99  void arm_q15_to_float(
100    const q15_t * pSrc,
101    float32_t * pDst,
102    uint32_t blockSize)
103  {
104    const q15_t *pIn = pSrc;                             /* Src pointer */
105    uint32_t blkCnt;                               /* loop counter */
106  
107    int16x8_t inV;
108    int32x4_t inV0, inV1;
109    float32x4_t outV;
110  
111    blkCnt = blockSize >> 3U;
112  
113    /* Compute 8 outputs at a time.
114     ** a second loop below computes the remaining 1 to 7 samples. */
115    while (blkCnt > 0U)
116    {
117      /* C = (float32_t) A / 32768 */
118      /* convert from q15 to float and then store the results in the destination buffer */
119      inV = vld1q_s16(pIn);
120      pIn += 8;
121  
122      inV0 = vmovl_s16(vget_low_s16(inV));
123      inV1 = vmovl_s16(vget_high_s16(inV));
124  
125      outV = vcvtq_n_f32_s32(inV0,15);
126      vst1q_f32(pDst, outV);
127      pDst += 4;
128  
129      outV = vcvtq_n_f32_s32(inV1,15);
130      vst1q_f32(pDst, outV);
131      pDst += 4;
132  
133      /* Decrement the loop counter */
134      blkCnt--;
135    }
136  
137    /* If the blockSize is not a multiple of 8, compute any remaining output samples here.
138     ** No loop unrolling is used. */
139    blkCnt = blockSize & 7;
140  
141  
142    while (blkCnt > 0U)
143    {
144      /* C = (float32_t) A / 32768 */
145      /* convert from q15 to float and then store the results in the destination buffer */
146      *pDst++ = ((float32_t) * pIn++ / 32768.0f);
147  
148      /* Decrement the loop counter */
149      blkCnt--;
150    }
151  }
152  #else
153  void arm_q15_to_float(
154    const q15_t * pSrc,
155          float32_t * pDst,
156          uint32_t blockSize)
157  {
158          uint32_t blkCnt;                               /* Loop counter */
159    const q15_t *pIn = pSrc;                             /* Source pointer */
160  
161  #if defined (ARM_MATH_LOOPUNROLL)
162  
163    /* Loop unrolling: Compute 4 outputs at a time */
164    blkCnt = blockSize >> 2U;
165  
166    while (blkCnt > 0U)
167    {
168      /* C = (float32_t) A / 32768 */
169  
170      /* Convert from q15 to float and store result in destination buffer */
171      *pDst++ = ((float32_t) * pIn++ / 32768.0f);
172      *pDst++ = ((float32_t) * pIn++ / 32768.0f);
173      *pDst++ = ((float32_t) * pIn++ / 32768.0f);
174      *pDst++ = ((float32_t) * pIn++ / 32768.0f);
175  
176      /* Decrement loop counter */
177      blkCnt--;
178    }
179  
180    /* Loop unrolling: Compute remaining outputs */
181    blkCnt = blockSize % 0x4U;
182  
183  #else
184  
185    /* Initialize blkCnt with number of samples */
186    blkCnt = blockSize;
187  
188  #endif /* #if defined (ARM_MATH_LOOPUNROLL) */
189  
190    while (blkCnt > 0U)
191    {
192      /* C = (float32_t) A / 32768 */
193  
194      /* Convert from q15 to float and store result in destination buffer */
195      *pDst++ = ((float32_t) *pIn++ / 32768.0f);
196  
197      /* Decrement loop counter */
198      blkCnt--;
199    }
200  
201  }
202  #endif /* #if defined(ARM_MATH_NEON) */
203  #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
204  
205  /**
206    @} end of q15_to_x group
207   */