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