GNU Radio Manual and C++ API Reference  3.7.6.1
The Free & Open Software Radio Ecosystem
volk_32f_s32f_convert_8i.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2014 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INCLUDED_volk_32f_s32f_convert_8i_u_H
24 #define INCLUDED_volk_32f_s32f_convert_8i_u_H
25 
26 #include <inttypes.h>
27 #include <stdio.h>
28 
29 #ifdef LV_HAVE_SSE2
30 #include <emmintrin.h>
31  /*!
32  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value
33  \param inputVector The floating point input data buffer
34  \param outputVector The 8 bit output data buffer
35  \param scalar The value multiplied against each point in the input buffer
36  \param num_points The number of data values to be converted
37  \note Input buffer does NOT need to be properly aligned
38  */
39 static inline void volk_32f_s32f_convert_8i_u_sse2(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
40  unsigned int number = 0;
41 
42  const unsigned int sixteenthPoints = num_points / 16;
43 
44  const float* inputVectorPtr = (const float*)inputVector;
45  int8_t* outputVectorPtr = outputVector;
46 
47  float min_val = -128;
48  float max_val = 127;
49  float r;
50 
51  __m128 vScalar = _mm_set_ps1(scalar);
52  __m128 inputVal1, inputVal2, inputVal3, inputVal4;
53  __m128i intInputVal1, intInputVal2, intInputVal3, intInputVal4;
54  __m128 vmin_val = _mm_set_ps1(min_val);
55  __m128 vmax_val = _mm_set_ps1(max_val);
56 
57  for(;number < sixteenthPoints; number++){
58  inputVal1 = _mm_loadu_ps(inputVectorPtr); inputVectorPtr += 4;
59  inputVal2 = _mm_loadu_ps(inputVectorPtr); inputVectorPtr += 4;
60  inputVal3 = _mm_loadu_ps(inputVectorPtr); inputVectorPtr += 4;
61  inputVal4 = _mm_loadu_ps(inputVectorPtr); inputVectorPtr += 4;
62 
63  inputVal1 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal1, vScalar), vmax_val), vmin_val);
64  inputVal2 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal2, vScalar), vmax_val), vmin_val);
65  inputVal3 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal3, vScalar), vmax_val), vmin_val);
66  inputVal4 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal4, vScalar), vmax_val), vmin_val);
67 
68  intInputVal1 = _mm_cvtps_epi32(inputVal1);
69  intInputVal2 = _mm_cvtps_epi32(inputVal2);
70  intInputVal3 = _mm_cvtps_epi32(inputVal3);
71  intInputVal4 = _mm_cvtps_epi32(inputVal4);
72 
73  intInputVal1 = _mm_packs_epi32(intInputVal1, intInputVal2);
74  intInputVal3 = _mm_packs_epi32(intInputVal3, intInputVal4);
75 
76  intInputVal1 = _mm_packs_epi16(intInputVal1, intInputVal3);
77 
78  _mm_storeu_si128((__m128i*)outputVectorPtr, intInputVal1);
79  outputVectorPtr += 16;
80  }
81 
82  number = sixteenthPoints * 16;
83  for(; number < num_points; number++){
84  r = inputVector[number] * scalar;
85  if(r > max_val)
86  r = max_val;
87  else if(r < min_val)
88  r = min_val;
89  outputVector[number] = (int16_t)(r);
90  }
91 }
92 #endif /* LV_HAVE_SSE2 */
93 
94 #ifdef LV_HAVE_SSE
95 #include <xmmintrin.h>
96  /*!
97  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value
98  \param inputVector The floating point input data buffer
99  \param outputVector The 8 bit output data buffer
100  \param scalar The value multiplied against each point in the input buffer
101  \param num_points The number of data values to be converted
102  \note Input buffer does NOT need to be properly aligned
103  */
104 static inline void volk_32f_s32f_convert_8i_u_sse(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
105  unsigned int number = 0;
106 
107  const unsigned int quarterPoints = num_points / 4;
108 
109  const float* inputVectorPtr = (const float*)inputVector;
110  int8_t* outputVectorPtr = outputVector;
111 
112  float min_val = -128;
113  float max_val = 127;
114  float r;
115 
116  __m128 vScalar = _mm_set_ps1(scalar);
117  __m128 ret;
118  __m128 vmin_val = _mm_set_ps1(min_val);
119  __m128 vmax_val = _mm_set_ps1(max_val);
120 
121  __VOLK_ATTR_ALIGNED(16) float outputFloatBuffer[4];
122 
123  for(;number < quarterPoints; number++){
124  ret = _mm_loadu_ps(inputVectorPtr);
125  inputVectorPtr += 4;
126 
127  ret = _mm_max_ps(_mm_min_ps(_mm_mul_ps(ret, vScalar), vmax_val), vmin_val);
128 
129  _mm_store_ps(outputFloatBuffer, ret);
130  *outputVectorPtr++ = (int8_t)(outputFloatBuffer[0]);
131  *outputVectorPtr++ = (int8_t)(outputFloatBuffer[1]);
132  *outputVectorPtr++ = (int8_t)(outputFloatBuffer[2]);
133  *outputVectorPtr++ = (int8_t)(outputFloatBuffer[3]);
134  }
135 
136  number = quarterPoints * 4;
137  for(; number < num_points; number++){
138  r = inputVector[number] * scalar;
139  if(r > max_val)
140  r = max_val;
141  else if(r < min_val)
142  r = min_val;
143  outputVector[number] = (int16_t)(r);
144  }
145 }
146 #endif /* LV_HAVE_SSE */
147 
148 #ifdef LV_HAVE_GENERIC
149  /*!
150  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value
151  \param inputVector The floating point input data buffer
152  \param outputVector The 8 bit output data buffer
153  \param scalar The value multiplied against each point in the input buffer
154  \param num_points The number of data values to be converted
155  \note Input buffer does NOT need to be properly aligned
156  */
157 static inline void volk_32f_s32f_convert_8i_generic(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
158  int8_t* outputVectorPtr = outputVector;
159  const float* inputVectorPtr = inputVector;
160  unsigned int number = 0;
161  float min_val = -128;
162  float max_val = 127;
163  float r;
164 
165  for(number = 0; number < num_points; number++){
166  r = *inputVectorPtr++ * scalar;
167  if(r > max_val)
168  r = max_val;
169  else if(r < min_val)
170  r = min_val;
171  *outputVectorPtr++ = (int16_t)(r);
172  }
173 }
174 #endif /* LV_HAVE_GENERIC */
175 
176 
177 
178 
179 #endif /* INCLUDED_volk_32f_s32f_convert_8i_u_H */
180 #ifndef INCLUDED_volk_32f_s32f_convert_8i_a_H
181 #define INCLUDED_volk_32f_s32f_convert_8i_a_H
182 
183 #include <volk/volk_common.h>
184 #include <inttypes.h>
185 #include <stdio.h>
186 
187 #ifdef LV_HAVE_SSE2
188 #include <emmintrin.h>
189  /*!
190  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value
191  \param inputVector The floating point input data buffer
192  \param outputVector The 8 bit output data buffer
193  \param scalar The value multiplied against each point in the input buffer
194  \param num_points The number of data values to be converted
195  */
196 static inline void volk_32f_s32f_convert_8i_a_sse2(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
197  unsigned int number = 0;
198 
199  const unsigned int sixteenthPoints = num_points / 16;
200 
201  const float* inputVectorPtr = (const float*)inputVector;
202  int8_t* outputVectorPtr = outputVector;
203 
204  float min_val = -128;
205  float max_val = 127;
206  float r;
207 
208  __m128 vScalar = _mm_set_ps1(scalar);
209  __m128 inputVal1, inputVal2, inputVal3, inputVal4;
210  __m128i intInputVal1, intInputVal2, intInputVal3, intInputVal4;
211  __m128 vmin_val = _mm_set_ps1(min_val);
212  __m128 vmax_val = _mm_set_ps1(max_val);
213 
214  for(;number < sixteenthPoints; number++){
215  inputVal1 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
216  inputVal2 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
217  inputVal3 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
218  inputVal4 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
219 
220  inputVal1 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal1, vScalar), vmax_val), vmin_val);
221  inputVal2 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal2, vScalar), vmax_val), vmin_val);
222  inputVal3 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal3, vScalar), vmax_val), vmin_val);
223  inputVal4 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal4, vScalar), vmax_val), vmin_val);
224 
225  intInputVal1 = _mm_cvtps_epi32(inputVal1);
226  intInputVal2 = _mm_cvtps_epi32(inputVal2);
227  intInputVal3 = _mm_cvtps_epi32(inputVal3);
228  intInputVal4 = _mm_cvtps_epi32(inputVal4);
229 
230  intInputVal1 = _mm_packs_epi32(intInputVal1, intInputVal2);
231  intInputVal3 = _mm_packs_epi32(intInputVal3, intInputVal4);
232 
233  intInputVal1 = _mm_packs_epi16(intInputVal1, intInputVal3);
234 
235  _mm_store_si128((__m128i*)outputVectorPtr, intInputVal1);
236  outputVectorPtr += 16;
237  }
238 
239  number = sixteenthPoints * 16;
240  for(; number < num_points; number++){
241  r = inputVector[number] * scalar;
242  if(r > max_val)
243  r = max_val;
244  else if(r < min_val)
245  r = min_val;
246  outputVector[number] = (int8_t)(r);
247  }
248 }
249 #endif /* LV_HAVE_SSE2 */
250 
251 #ifdef LV_HAVE_SSE
252 #include <xmmintrin.h>
253  /*!
254  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value
255  \param inputVector The floating point input data buffer
256  \param outputVector The 8 bit output data buffer
257  \param scalar The value multiplied against each point in the input buffer
258  \param num_points The number of data values to be converted
259  */
260 static inline void volk_32f_s32f_convert_8i_a_sse(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
261  unsigned int number = 0;
262 
263  const unsigned int quarterPoints = num_points / 4;
264 
265  const float* inputVectorPtr = (const float*)inputVector;
266 
267  float min_val = -128;
268  float max_val = 127;
269  float r;
270 
271  int8_t* outputVectorPtr = outputVector;
272  __m128 vScalar = _mm_set_ps1(scalar);
273  __m128 ret;
274  __m128 vmin_val = _mm_set_ps1(min_val);
275  __m128 vmax_val = _mm_set_ps1(max_val);
276 
277  __VOLK_ATTR_ALIGNED(16) float outputFloatBuffer[4];
278 
279  for(;number < quarterPoints; number++){
280  ret = _mm_load_ps(inputVectorPtr);
281  inputVectorPtr += 4;
282 
283  ret = _mm_max_ps(_mm_min_ps(_mm_mul_ps(ret, vScalar), vmax_val), vmin_val);
284 
285  _mm_store_ps(outputFloatBuffer, ret);
286  *outputVectorPtr++ = (int8_t)(outputFloatBuffer[0]);
287  *outputVectorPtr++ = (int8_t)(outputFloatBuffer[1]);
288  *outputVectorPtr++ = (int8_t)(outputFloatBuffer[2]);
289  *outputVectorPtr++ = (int8_t)(outputFloatBuffer[3]);
290  }
291 
292  number = quarterPoints * 4;
293  for(; number < num_points; number++){
294  r = inputVector[number] * scalar;
295  if(r > max_val)
296  r = max_val;
297  else if(r < min_val)
298  r = min_val;
299  outputVector[number] = (int8_t)(r);
300  }
301 }
302 #endif /* LV_HAVE_SSE */
303 
304 #ifdef LV_HAVE_GENERIC
305  /*!
306  \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value
307  \param inputVector The floating point input data buffer
308  \param outputVector The 8 bit output data buffer
309  \param scalar The value multiplied against each point in the input buffer
310  \param num_points The number of data values to be converted
311  */
312 static inline void volk_32f_s32f_convert_8i_a_generic(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
313  int8_t* outputVectorPtr = outputVector;
314  const float* inputVectorPtr = inputVector;
315  unsigned int number = 0;
316  float min_val = -128;
317  float max_val = 127;
318  float r;
319 
320  for(number = 0; number < num_points; number++){
321  r = *inputVectorPtr++ * scalar;
322  if(r > max_val)
323  r = max_val;
324  else if(r < min_val)
325  r = min_val;
326  *outputVectorPtr++ = (int8_t)(r);
327  }
328 }
329 #endif /* LV_HAVE_GENERIC */
330 
331 
332 
333 
334 #endif /* INCLUDED_volk_32f_s32f_convert_8i_a_H */
signed short int16_t
Definition: stdint.h:76
signed char int8_t
Definition: stdint.h:75
#define __VOLK_ATTR_ALIGNED(x)
Definition: volk_common.h:27