GNU Radio Manual and C++ API Reference  3.7.7
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
volk_16i_convert_8i.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2012, 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 /*!
24  * \page volk_16i_convert_8i
25  *
26  * \b Overview
27  *
28  * Converts 16-bit shorts to 8-bit chars.
29  *
30  * <b>Dispatcher Prototype</b>
31  * \code
32  * void volk_16i_convert_8i(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points)
33  * \endcode
34  *
35  * \b Inputs
36  * \li inputVector: The input vector of 16-bit shorts.
37  * \li num_points: The number of complex data points.
38  *
39  * \b Outputs
40  * \li outputVector: The output vector of 8-bit chars.
41  *
42  * \b Example
43  * \code
44  * int N = 10000;
45  *
46  * volk_16i_convert_8i();
47  *
48  * volk_free(x);
49  * volk_free(t);
50  * \endcode
51  */
52 
53 #ifndef INCLUDED_volk_16i_convert_8i_u_H
54 #define INCLUDED_volk_16i_convert_8i_u_H
55 
56 #include <inttypes.h>
57 #include <stdio.h>
58 
59 #ifdef LV_HAVE_SSE2
60 #include <emmintrin.h>
61 
62 static inline void
63 volk_16i_convert_8i_u_sse2(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points)
64 {
65  unsigned int number = 0;
66  const unsigned int sixteenthPoints = num_points / 16;
67 
68  int8_t* outputVectorPtr = outputVector;
69  int16_t* inputPtr = (int16_t*)inputVector;
70  __m128i inputVal1;
71  __m128i inputVal2;
72  __m128i ret;
73 
74  for(;number < sixteenthPoints; number++){
75 
76  // Load the 16 values
77  inputVal1 = _mm_loadu_si128((__m128i*)inputPtr); inputPtr += 8;
78  inputVal2 = _mm_loadu_si128((__m128i*)inputPtr); inputPtr += 8;
79 
80  inputVal1 = _mm_srai_epi16(inputVal1, 8);
81  inputVal2 = _mm_srai_epi16(inputVal2, 8);
82 
83  ret = _mm_packs_epi16(inputVal1, inputVal2);
84 
85  _mm_storeu_si128((__m128i*)outputVectorPtr, ret);
86 
87  outputVectorPtr += 16;
88  }
89 
90  number = sixteenthPoints * 16;
91  for(; number < num_points; number++){
92  outputVector[number] =(int8_t)(inputVector[number] >> 8);
93  }
94 }
95 #endif /* LV_HAVE_SSE2 */
96 
97 
98 #ifdef LV_HAVE_GENERIC
99 
100 static inline void
101 volk_16i_convert_8i_generic(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points)
102 {
103  int8_t* outputVectorPtr = outputVector;
104  const int16_t* inputVectorPtr = inputVector;
105  unsigned int number = 0;
106 
107  for(number = 0; number < num_points; number++){
108  *outputVectorPtr++ = ((int8_t)(*inputVectorPtr++ >> 8));
109  }
110 }
111 #endif /* LV_HAVE_GENERIC */
112 
113 
114 
115 
116 #endif /* INCLUDED_volk_16i_convert_8i_u_H */
117 #ifndef INCLUDED_volk_16i_convert_8i_a_H
118 #define INCLUDED_volk_16i_convert_8i_a_H
119 
120 #include <inttypes.h>
121 #include <stdio.h>
122 
123 #ifdef LV_HAVE_SSE2
124 #include <emmintrin.h>
125 
126 static inline void
127 volk_16i_convert_8i_a_sse2(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points)
128 {
129  unsigned int number = 0;
130  const unsigned int sixteenthPoints = num_points / 16;
131 
132  int8_t* outputVectorPtr = outputVector;
133  int16_t* inputPtr = (int16_t*)inputVector;
134  __m128i inputVal1;
135  __m128i inputVal2;
136  __m128i ret;
137 
138  for(;number < sixteenthPoints; number++){
139 
140  // Load the 16 values
141  inputVal1 = _mm_load_si128((__m128i*)inputPtr); inputPtr += 8;
142  inputVal2 = _mm_load_si128((__m128i*)inputPtr); inputPtr += 8;
143 
144  inputVal1 = _mm_srai_epi16(inputVal1, 8);
145  inputVal2 = _mm_srai_epi16(inputVal2, 8);
146 
147  ret = _mm_packs_epi16(inputVal1, inputVal2);
148 
149  _mm_store_si128((__m128i*)outputVectorPtr, ret);
150 
151  outputVectorPtr += 16;
152  }
153 
154  number = sixteenthPoints * 16;
155  for(; number < num_points; number++){
156  outputVector[number] =(int8_t)(inputVector[number] >> 8);
157  }
158 }
159 #endif /* LV_HAVE_SSE2 */
160 
161 
162 #ifdef LV_HAVE_NEON
163 #include <arm_neon.h>
164 
165 static inline void
166 volk_16i_convert_8i_neon(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points)
167 {
168  int8_t* outputVectorPtr = outputVector;
169  const int16_t* inputVectorPtr = inputVector;
170  unsigned int number = 0;
171  unsigned int sixteenth_points = num_points / 16;
172 
173  int16x8_t inputVal0;
174  int16x8_t inputVal1;
175  int8x8_t outputVal0;
176  int8x8_t outputVal1;
177  int8x16_t outputVal;
178 
179  for(number = 0; number < sixteenth_points; number++){
180  // load two input vectors
181  inputVal0 = vld1q_s16(inputVectorPtr);
182  inputVal1 = vld1q_s16(inputVectorPtr+8);
183  // shift right
184  outputVal0 = vshrn_n_s16(inputVal0, 8);
185  outputVal1 = vshrn_n_s16(inputVal1, 8);
186  // squash two vectors and write output
187  outputVal = vcombine_s8(outputVal0, outputVal1);
188  vst1q_s8(outputVectorPtr, outputVal);
189  inputVectorPtr += 16;
190  outputVectorPtr += 16;
191  }
192 
193  for(number = sixteenth_points * 16; number < num_points; number++){
194  *outputVectorPtr++ = ((int8_t)(*inputVectorPtr++ >> 8));
195  }
196 }
197 #endif /* LV_HAVE_NEON */
198 
199 
200 #ifdef LV_HAVE_GENERIC
201 
202 static inline void
203 volk_16i_convert_8i_a_generic(int8_t* outputVector, const int16_t* inputVector, unsigned int num_points)
204 {
205  int8_t* outputVectorPtr = outputVector;
206  const int16_t* inputVectorPtr = inputVector;
207  unsigned int number = 0;
208 
209  for(number = 0; number < num_points; number++){
210  *outputVectorPtr++ = ((int8_t)(*inputVectorPtr++ >> 8));
211  }
212 }
213 #endif /* LV_HAVE_GENERIC */
214 
215 #endif /* INCLUDED_volk_16i_convert_8i_a_H */
signed short int16_t
Definition: stdint.h:76
signed char int8_t
Definition: stdint.h:75