GNU Radio Manual and C++ API Reference  3.7.6.1
The Free & Open Software Radio Ecosystem
volk_16i_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_16i_convert_8i_u_H
24 #define INCLUDED_volk_16i_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 Converts the input 16 bit integer data into 8 bit integer data
33  \param inputVector The 16 bit input data buffer
34  \param outputVector The 8 bit output data buffer
35  \param num_points The number of data values to be converted
36  \note Input and output buffers do NOT need to be properly aligned
37 */
38 static inline void volk_16i_convert_8i_u_sse2(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points){
39  unsigned int number = 0;
40  const unsigned int sixteenthPoints = num_points / 16;
41 
42  int8_t* outputVectorPtr = outputVector;
43  int16_t* inputPtr = (int16_t*)inputVector;
44  __m128i inputVal1;
45  __m128i inputVal2;
46  __m128i ret;
47 
48  for(;number < sixteenthPoints; number++){
49 
50  // Load the 16 values
51  inputVal1 = _mm_loadu_si128((__m128i*)inputPtr); inputPtr += 8;
52  inputVal2 = _mm_loadu_si128((__m128i*)inputPtr); inputPtr += 8;
53 
54  inputVal1 = _mm_srai_epi16(inputVal1, 8);
55  inputVal2 = _mm_srai_epi16(inputVal2, 8);
56 
57  ret = _mm_packs_epi16(inputVal1, inputVal2);
58 
59  _mm_storeu_si128((__m128i*)outputVectorPtr, ret);
60 
61  outputVectorPtr += 16;
62  }
63 
64  number = sixteenthPoints * 16;
65  for(; number < num_points; number++){
66  outputVector[number] =(int8_t)(inputVector[number] >> 8);
67  }
68 }
69 #endif /* LV_HAVE_SSE2 */
70 
71 #ifdef LV_HAVE_GENERIC
72 /*!
73  \brief Converts the input 16 bit integer data into 8 bit integer data
74  \param inputVector The 16 bit input data buffer
75  \param outputVector The 8 bit output data buffer
76  \param num_points The number of data values to be converted
77  \note Input and output buffers do NOT need to be properly aligned
78 */
79 static inline void volk_16i_convert_8i_generic(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points){
80  int8_t* outputVectorPtr = outputVector;
81  const int16_t* inputVectorPtr = inputVector;
82  unsigned int number = 0;
83 
84  for(number = 0; number < num_points; number++){
85  *outputVectorPtr++ = ((int8_t)(*inputVectorPtr++ >> 8));
86  }
87 }
88 #endif /* LV_HAVE_GENERIC */
89 
90 
91 
92 
93 #endif /* INCLUDED_volk_16i_convert_8i_u_H */
94 #ifndef INCLUDED_volk_16i_convert_8i_a_H
95 #define INCLUDED_volk_16i_convert_8i_a_H
96 
97 #include <inttypes.h>
98 #include <stdio.h>
99 
100 #ifdef LV_HAVE_SSE2
101 #include <emmintrin.h>
102 /*!
103  \brief Converts the input 16 bit integer data into 8 bit integer data
104  \param inputVector The 16 bit input data buffer
105  \param outputVector The 8 bit output data buffer
106  \param num_points The number of data values to be converted
107 */
108 static inline void volk_16i_convert_8i_a_sse2(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points){
109  unsigned int number = 0;
110  const unsigned int sixteenthPoints = num_points / 16;
111 
112  int8_t* outputVectorPtr = outputVector;
113  int16_t* inputPtr = (int16_t*)inputVector;
114  __m128i inputVal1;
115  __m128i inputVal2;
116  __m128i ret;
117 
118  for(;number < sixteenthPoints; number++){
119 
120  // Load the 16 values
121  inputVal1 = _mm_load_si128((__m128i*)inputPtr); inputPtr += 8;
122  inputVal2 = _mm_load_si128((__m128i*)inputPtr); inputPtr += 8;
123 
124  inputVal1 = _mm_srai_epi16(inputVal1, 8);
125  inputVal2 = _mm_srai_epi16(inputVal2, 8);
126 
127  ret = _mm_packs_epi16(inputVal1, inputVal2);
128 
129  _mm_store_si128((__m128i*)outputVectorPtr, ret);
130 
131  outputVectorPtr += 16;
132  }
133 
134  number = sixteenthPoints * 16;
135  for(; number < num_points; number++){
136  outputVector[number] =(int8_t)(inputVector[number] >> 8);
137  }
138 }
139 #endif /* LV_HAVE_SSE2 */
140 
141 #ifdef LV_HAVE_NEON
142 #include <arm_neon.h>
143 /*!
144  \brief Converts the input 16 bit integer data into 8 bit integer data
145  \param inputVector The 16 bit input data buffer
146  \param outputVector The 8 bit output data buffer
147  \param num_points The number of data values to be converted
148 */
149 static inline void volk_16i_convert_8i_neon(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points){
150  int8_t* outputVectorPtr = outputVector;
151  const int16_t* inputVectorPtr = inputVector;
152  unsigned int number = 0;
153  unsigned int sixteenth_points = num_points / 16;
154 
155  int16x8_t inputVal0;
156  int16x8_t inputVal1;
157  int8x8_t outputVal0;
158  int8x8_t outputVal1;
159  int8x16_t outputVal;
160 
161  for(number = 0; number < sixteenth_points; number++){
162  // load two input vectors
163  inputVal0 = vld1q_s16(inputVectorPtr);
164  inputVal1 = vld1q_s16(inputVectorPtr+8);
165  // shift right
166  outputVal0 = vshrn_n_s16(inputVal0, 8);
167  outputVal1 = vshrn_n_s16(inputVal1, 8);
168  // squash two vectors and write output
169  outputVal = vcombine_s8(outputVal0, outputVal1);
170  vst1q_s8(outputVectorPtr, outputVal);
171  inputVectorPtr += 16;
172  outputVectorPtr += 16;
173  }
174 
175  for(number = sixteenth_points * 16; number < num_points; number++){
176  *outputVectorPtr++ = ((int8_t)(*inputVectorPtr++ >> 8));
177  }
178 }
179 #endif /* LV_HAVE_NEON */
180 
181 #ifdef LV_HAVE_GENERIC
182 /*!
183  \brief Converts the input 16 bit integer data into 8 bit integer data
184  \param inputVector The 16 bit input data buffer
185  \param outputVector The 8 bit output data buffer
186  \param num_points The number of data values to be converted
187 */
188 static inline void volk_16i_convert_8i_a_generic(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points){
189  int8_t* outputVectorPtr = outputVector;
190  const int16_t* inputVectorPtr = inputVector;
191  unsigned int number = 0;
192 
193  for(number = 0; number < num_points; number++){
194  *outputVectorPtr++ = ((int8_t)(*inputVectorPtr++ >> 8));
195  }
196 }
197 #endif /* LV_HAVE_GENERIC */
198 
199 #endif /* INCLUDED_volk_16i_convert_8i_a_H */
signed short int16_t
Definition: stdint.h:76
signed char int8_t
Definition: stdint.h:75