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 */