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