GNU Radio Manual and C++ API Reference  3.7.4
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
volk_32f_s32f_convert_16i.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_32f_s32f_convert_16i_u_H
2 #define INCLUDED_volk_32f_s32f_convert_16i_u_H
3 
4 #include <inttypes.h>
5 #include <stdio.h>
6 #include <math.h>
7 
8 #ifdef LV_HAVE_SSE2
9 #include <emmintrin.h>
10  /*!
11  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value
12  \param inputVector The floating point input data buffer
13  \param outputVector The 16 bit output data buffer
14  \param scalar The value multiplied against each point in the input buffer
15  \param num_points The number of data values to be converted
16  \note Input buffer does NOT need to be properly aligned
17  */
18 static inline void volk_32f_s32f_convert_16i_u_sse2(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
19  unsigned int number = 0;
20 
21  const unsigned int eighthPoints = num_points / 8;
22 
23  const float* inputVectorPtr = (const float*)inputVector;
24  int16_t* outputVectorPtr = outputVector;
25 
26  float min_val = -32768;
27  float max_val = 32767;
28  float r;
29 
30  __m128 vScalar = _mm_set_ps1(scalar);
31  __m128 inputVal1, inputVal2;
32  __m128i intInputVal1, intInputVal2;
33  __m128 ret1, ret2;
34  __m128 vmin_val = _mm_set_ps1(min_val);
35  __m128 vmax_val = _mm_set_ps1(max_val);
36 
37  for(;number < eighthPoints; number++){
38  inputVal1 = _mm_loadu_ps(inputVectorPtr); inputVectorPtr += 4;
39  inputVal2 = _mm_loadu_ps(inputVectorPtr); inputVectorPtr += 4;
40 
41  // Scale and clip
42  ret1 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal1, vScalar), vmax_val), vmin_val);
43  ret2 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal2, vScalar), vmax_val), vmin_val);
44 
45  intInputVal1 = _mm_cvtps_epi32(ret1);
46  intInputVal2 = _mm_cvtps_epi32(ret2);
47 
48  intInputVal1 = _mm_packs_epi32(intInputVal1, intInputVal2);
49 
50  _mm_storeu_si128((__m128i*)outputVectorPtr, intInputVal1);
51  outputVectorPtr += 8;
52  }
53 
54  number = eighthPoints * 8;
55  for(; number < num_points; number++){
56  r = inputVector[number] * scalar;
57  if(r > max_val)
58  r = max_val;
59  else if(r < min_val)
60  r = min_val;
61  outputVector[number] = (int16_t)rintf(r);
62  }
63 }
64 #endif /* LV_HAVE_SSE2 */
65 
66 #ifdef LV_HAVE_SSE
67 #include <xmmintrin.h>
68  /*!
69  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value
70  \param inputVector The floating point input data buffer
71  \param outputVector The 16 bit output data buffer
72  \param scalar The value multiplied against each point in the input buffer
73  \param num_points The number of data values to be converted
74  \note Input buffer does NOT need to be properly aligned
75  */
76 static inline void volk_32f_s32f_convert_16i_u_sse(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
77  unsigned int number = 0;
78 
79  const unsigned int quarterPoints = num_points / 4;
80 
81  const float* inputVectorPtr = (const float*)inputVector;
82  int16_t* outputVectorPtr = outputVector;
83 
84  float min_val = -32768;
85  float max_val = 32767;
86  float r;
87 
88  __m128 vScalar = _mm_set_ps1(scalar);
89  __m128 ret;
90  __m128 vmin_val = _mm_set_ps1(min_val);
91  __m128 vmax_val = _mm_set_ps1(max_val);
92 
93  __VOLK_ATTR_ALIGNED(16) float outputFloatBuffer[4];
94 
95  for(;number < quarterPoints; number++){
96  ret = _mm_loadu_ps(inputVectorPtr);
97  inputVectorPtr += 4;
98 
99  // Scale and clip
100  ret = _mm_max_ps(_mm_min_ps(_mm_mul_ps(ret, vScalar), vmax_val), vmin_val);
101 
102  _mm_store_ps(outputFloatBuffer, ret);
103  *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[0]);
104  *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[1]);
105  *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[2]);
106  *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[3]);
107  }
108 
109  number = quarterPoints * 4;
110  for(; number < num_points; number++){
111  r = inputVector[number] * scalar;
112  if(r > max_val)
113  r = max_val;
114  else if(r < min_val)
115  r = min_val;
116  outputVector[number] = (int16_t)rintf(r);
117  }
118 }
119 #endif /* LV_HAVE_SSE */
120 
121 #ifdef LV_HAVE_GENERIC
122  /*!
123  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value
124  \param inputVector The floating point input data buffer
125  \param outputVector The 16 bit output data buffer
126  \param scalar The value multiplied against each point in the input buffer
127  \param num_points The number of data values to be converted
128  \note Input buffer does NOT need to be properly aligned
129  */
130 static inline void volk_32f_s32f_convert_16i_generic(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
131  int16_t* outputVectorPtr = outputVector;
132  const float* inputVectorPtr = inputVector;
133  unsigned int number = 0;
134  float min_val = -32768;
135  float max_val = 32767;
136  float r;
137 
138  for(number = 0; number < num_points; number++){
139  r = *inputVectorPtr++ * scalar;
140  if(r > max_val)
141  r = max_val;
142  else if(r < min_val)
143  r = min_val;
144  *outputVectorPtr++ = (int16_t)rintf(r);
145  }
146 }
147 #endif /* LV_HAVE_GENERIC */
148 
149 
150 
151 
152 #endif /* INCLUDED_volk_32f_s32f_convert_16i_u_H */
153 #ifndef INCLUDED_volk_32f_s32f_convert_16i_a_H
154 #define INCLUDED_volk_32f_s32f_convert_16i_a_H
155 
156 #include <volk/volk_common.h>
157 #include <inttypes.h>
158 #include <stdio.h>
159 #include <math.h>
160 
161 #ifdef LV_HAVE_SSE2
162 #include <emmintrin.h>
163  /*!
164  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value
165  \param inputVector The floating point input data buffer
166  \param outputVector The 16 bit output data buffer
167  \param scalar The value multiplied against each point in the input buffer
168  \param num_points The number of data values to be converted
169  */
170 static inline void volk_32f_s32f_convert_16i_a_sse2(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
171  unsigned int number = 0;
172 
173  const unsigned int eighthPoints = num_points / 8;
174 
175  const float* inputVectorPtr = (const float*)inputVector;
176  int16_t* outputVectorPtr = outputVector;
177 
178  float min_val = -32768;
179  float max_val = 32767;
180  float r;
181 
182  __m128 vScalar = _mm_set_ps1(scalar);
183  __m128 inputVal1, inputVal2;
184  __m128i intInputVal1, intInputVal2;
185  __m128 ret1, ret2;
186  __m128 vmin_val = _mm_set_ps1(min_val);
187  __m128 vmax_val = _mm_set_ps1(max_val);
188 
189  for(;number < eighthPoints; number++){
190  inputVal1 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
191  inputVal2 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
192 
193  // Scale and clip
194  ret1 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal1, vScalar), vmax_val), vmin_val);
195  ret2 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal2, vScalar), vmax_val), vmin_val);
196 
197  intInputVal1 = _mm_cvtps_epi32(ret1);
198  intInputVal2 = _mm_cvtps_epi32(ret2);
199 
200  intInputVal1 = _mm_packs_epi32(intInputVal1, intInputVal2);
201 
202  _mm_store_si128((__m128i*)outputVectorPtr, intInputVal1);
203  outputVectorPtr += 8;
204  }
205 
206  number = eighthPoints * 8;
207  for(; number < num_points; number++){
208  r = inputVector[number] * scalar;
209  if(r > max_val)
210  r = max_val;
211  else if(r < min_val)
212  r = min_val;
213  outputVector[number] = (int16_t)rintf(r);
214  }
215 }
216 #endif /* LV_HAVE_SSE2 */
217 
218 #ifdef LV_HAVE_SSE
219 #include <xmmintrin.h>
220  /*!
221  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value
222  \param inputVector The floating point input data buffer
223  \param outputVector The 16 bit output data buffer
224  \param scalar The value multiplied against each point in the input buffer
225  \param num_points The number of data values to be converted
226  */
227 static inline void volk_32f_s32f_convert_16i_a_sse(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
228  unsigned int number = 0;
229 
230  const unsigned int quarterPoints = num_points / 4;
231 
232  const float* inputVectorPtr = (const float*)inputVector;
233  int16_t* outputVectorPtr = outputVector;
234 
235  float min_val = -32768;
236  float max_val = 32767;
237  float r;
238 
239  __m128 vScalar = _mm_set_ps1(scalar);
240  __m128 ret;
241  __m128 vmin_val = _mm_set_ps1(min_val);
242  __m128 vmax_val = _mm_set_ps1(max_val);
243 
244  __VOLK_ATTR_ALIGNED(16) float outputFloatBuffer[4];
245 
246  for(;number < quarterPoints; number++){
247  ret = _mm_load_ps(inputVectorPtr);
248  inputVectorPtr += 4;
249 
250  // Scale and clip
251  ret = _mm_max_ps(_mm_min_ps(_mm_mul_ps(ret, vScalar), vmax_val), vmin_val);
252 
253  _mm_store_ps(outputFloatBuffer, ret);
254  *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[0]);
255  *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[1]);
256  *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[2]);
257  *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[3]);
258  }
259 
260  number = quarterPoints * 4;
261  for(; number < num_points; number++){
262  r = inputVector[number] * scalar;
263  if(r > max_val)
264  r = max_val;
265  else if(r < min_val)
266  r = min_val;
267  outputVector[number] = (int16_t)rintf(r);
268  }
269 }
270 #endif /* LV_HAVE_SSE */
271 
272 #ifdef LV_HAVE_GENERIC
273  /*!
274  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value
275  \param inputVector The floating point input data buffer
276  \param outputVector The 16 bit output data buffer
277  \param scalar The value multiplied against each point in the input buffer
278  \param num_points The number of data values to be converted
279  */
280 static inline void volk_32f_s32f_convert_16i_a_generic(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
281  int16_t* outputVectorPtr = outputVector;
282  const float* inputVectorPtr = inputVector;
283  unsigned int number = 0;
284  float min_val = -32768;
285  float max_val = 32767;
286  float r;
287 
288  for(number = 0; number < num_points; number++){
289  r = *inputVectorPtr++ * scalar;
290  if(r < min_val)
291  r = min_val;
292  else if(r > max_val)
293  r = max_val;
294  *outputVectorPtr++ = (int16_t)rintf(r);
295  }
296 }
297 #endif /* LV_HAVE_GENERIC */
298 
299 
300 
301 
302 #endif /* INCLUDED_volk_32f_s32f_convert_16i_a_H */
static float rintf(float x)
Definition: gnuradio/volk/cmake/msvc/config.h:30
signed short int16_t
Definition: stdint.h:76
#define __VOLK_ATTR_ALIGNED(x)
Definition: volk_common.h:27