/ Drivers / CMSIS / DSP / Source / SupportFunctions / arm_q7_to_float.c
arm_q7_to_float.c
  1  /* ----------------------------------------------------------------------
  2   * Project:      CMSIS DSP Library
  3   * Title:        arm_q7_to_float.c
  4   * Description:  Converts the elements of the Q7 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 q7_to_x  Convert 8-bit fixed point value
 37   */
 38  
 39  /**
 40    @addtogroup q7_to_x
 41    @{
 42   */
 43  
 44  /**
 45    @brief         Converts the elements of the Q7 vector to floating-point vector.
 46    @param[in]     pSrc       points to the Q7 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] / 128;   0 <= n < blockSize.
 55    </pre>
 56   */
 57  #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
 58  void arm_q7_to_float(
 59    const q7_t * pSrc,
 60    float32_t * pDst,
 61    uint32_t blockSize)
 62  {
 63      uint32_t  blkCnt;           /* loop counters */
 64      q7x16_t vecDst;
 65      q7_t const *pSrcVec;
 66  
 67      pSrcVec = (q7_t const *) pSrc;
 68      blkCnt = blockSize >> 2;
 69      while (blkCnt > 0U)
 70      {
 71          /* C = (float32_t) A / 32768 */
 72          /* convert from q7 to float and then store the results in the destination buffer */
 73          vecDst = vldrbq_s32(pSrcVec);    
 74          pSrcVec += 4;
 75          vstrwq(pDst, vcvtq_n_f32_s32((int32x4_t)vecDst, 7));   
 76          pDst += 4;
 77          /*
 78           * Decrement the blockSize loop counter
 79           */
 80          blkCnt--;
 81      }
 82  
 83    blkCnt = blockSize & 3;
 84    while (blkCnt > 0U)
 85    {
 86      /* C = (float32_t) A / 128 */
 87  
 88      /* Convert from q7 to float and store result in destination buffer */
 89      *pDst++ = ((float32_t) * pSrcVec++ / 128.0f);
 90  
 91      /* Decrement loop counter */
 92      blkCnt--;
 93    }
 94  }
 95  #else
 96  #if defined(ARM_MATH_NEON)
 97  void arm_q7_to_float(
 98    const q7_t * pSrc,
 99    float32_t * pDst,
100    uint32_t blockSize)
101  {
102    const q7_t *pIn = pSrc;                              /* Src pointer */
103    uint32_t blkCnt;                               /* loop counter */
104  
105    int8x16_t inV;
106    int16x8_t inVLO, inVHI;
107    int32x4_t inVLL, inVLH, inVHL, inVHH;
108    float32x4_t outV;
109  
110    blkCnt = blockSize >> 4U;
111  
112    /* Compute 16 outputs at a time.
113     ** a second loop below computes the remaining 1 to 15 samples. */
114    while (blkCnt > 0U)
115    {
116      /* C = (float32_t) A / 128 */
117      /* Convert from q7 to float and then store the results in the destination buffer */
118      inV = vld1q_s8(pIn);
119      pIn += 16;
120  
121      inVLO = vmovl_s8(vget_low_s8(inV));
122      inVHI = vmovl_s8(vget_high_s8(inV));
123  
124      inVLL = vmovl_s16(vget_low_s16(inVLO));
125      inVLH = vmovl_s16(vget_high_s16(inVLO));
126      inVHL = vmovl_s16(vget_low_s16(inVHI));
127      inVHH = vmovl_s16(vget_high_s16(inVHI));
128  
129      outV = vcvtq_n_f32_s32(inVLL,7);
130      vst1q_f32(pDst, outV);
131      pDst += 4;
132  
133      outV = vcvtq_n_f32_s32(inVLH,7);
134      vst1q_f32(pDst, outV);
135      pDst += 4;
136  
137      outV = vcvtq_n_f32_s32(inVHL,7);
138      vst1q_f32(pDst, outV);
139      pDst += 4;
140  
141      outV = vcvtq_n_f32_s32(inVHH,7);
142      vst1q_f32(pDst, outV);
143      pDst += 4;
144  
145      /* Decrement the loop counter */
146      blkCnt--;
147    }
148  
149    /* If the blockSize is not a multiple of 16, compute any remaining output samples here.
150     ** No loop unrolling is used. */
151    blkCnt = blockSize & 0xF;
152  
153    while (blkCnt > 0U)
154    {
155      /* C = (float32_t) A / 128 */
156      /* Convert from q7 to float and then store the results in the destination buffer */
157      *pDst++ = ((float32_t) * pIn++ / 128.0f);
158  
159      /* Decrement the loop counter */
160      blkCnt--;
161    }
162  }
163  #else
164  void arm_q7_to_float(
165    const q7_t * pSrc,
166          float32_t * pDst,
167          uint32_t blockSize)
168  {
169          uint32_t blkCnt;                               /* Loop counter */
170    const q7_t *pIn = pSrc;                              /* Source pointer */
171  
172  #if defined (ARM_MATH_LOOPUNROLL)
173  
174    /* Loop unrolling: Compute 4 outputs at a time */
175    blkCnt = blockSize >> 2U;
176  
177    while (blkCnt > 0U)
178    {
179      /* C = (float32_t) A / 128 */
180  
181      /* Convert from q7 to float and store result in destination buffer */
182      *pDst++ = ((float32_t) * pIn++ / 128.0f);
183      *pDst++ = ((float32_t) * pIn++ / 128.0f);
184      *pDst++ = ((float32_t) * pIn++ / 128.0f);
185      *pDst++ = ((float32_t) * pIn++ / 128.0f);
186  
187      /* Decrement loop counter */
188      blkCnt--;
189    }
190  
191    /* Loop unrolling: Compute remaining outputs */
192    blkCnt = blockSize % 0x4U;
193  
194  #else
195  
196    /* Initialize blkCnt with number of samples */
197    blkCnt = blockSize;
198  
199  #endif /* #if defined (ARM_MATH_LOOPUNROLL) */
200  
201    while (blkCnt > 0U)
202    {
203      /* C = (float32_t) A / 128 */
204  
205      /* Convert from q7 to float and store result in destination buffer */
206      *pDst++ = ((float32_t) * pIn++ / 128.0f);
207  
208      /* Decrement loop counter */
209      blkCnt--;
210    }
211  
212  }
213  #endif /* #if defined(ARM_MATH_NEON) */
214  #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
215  
216  /**
217    @} end of q7_to_x group
218   */