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_16ic_deinterleave_real_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_16ic_deinterleave_real_8i
25  *
26  * \b Overview
27  *
28  * Deinterleaves the complex 16 bit vector and returns the real
29  * (inphase) part of the signal as an 8-bit value.
30  *
31  * <b>Dispatcher Prototype</b>
32  * \code
33  * void volk_16ic_deinterleave_real_8i(int8_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points)
34  * \endcode
35  *
36  * \b Inputs
37  * \li complexVector: The complex input vector.
38  * \li num_points: The number of complex data values to be deinterleaved.
39  *
40  * \b Outputs
41  * \li iBuffer: The I buffer output data with 8-bit precision.
42  *
43  * \b Example
44  * \code
45  * int N = 10000;
46  *
47  * volk_16ic_deinterleave_real_8i();
48  *
49  * volk_free(x);
50  * volk_free(t);
51  * \endcode
52  */
53 
54 #ifndef INCLUDED_volk_16ic_deinterleave_real_8i_a_H
55 #define INCLUDED_volk_16ic_deinterleave_real_8i_a_H
56 
57 #include <inttypes.h>
58 #include <stdio.h>
59 
60 #ifdef LV_HAVE_SSSE3
61 #include <tmmintrin.h>
62 
63 static inline void
64 volk_16ic_deinterleave_real_8i_a_ssse3(int8_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points)
65 {
66  unsigned int number = 0;
67  const int8_t* complexVectorPtr = (int8_t*)complexVector;
68  int8_t* iBufferPtr = iBuffer;
69  __m128i iMoveMask1 = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 13, 12, 9, 8, 5, 4, 1, 0);
70  __m128i iMoveMask2 = _mm_set_epi8(13, 12, 9, 8, 5, 4, 1, 0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
71  __m128i complexVal1, complexVal2, complexVal3, complexVal4, iOutputVal;
72 
73  unsigned int sixteenthPoints = num_points / 16;
74 
75  for(number = 0; number < sixteenthPoints; number++){
76  complexVal1 = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16;
77  complexVal2 = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16;
78 
79  complexVal3 = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16;
80  complexVal4 = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16;
81 
82  complexVal1 = _mm_shuffle_epi8(complexVal1, iMoveMask1);
83  complexVal2 = _mm_shuffle_epi8(complexVal2, iMoveMask2);
84 
85  complexVal1 = _mm_or_si128(complexVal1, complexVal2);
86 
87  complexVal3 = _mm_shuffle_epi8(complexVal3, iMoveMask1);
88  complexVal4 = _mm_shuffle_epi8(complexVal4, iMoveMask2);
89 
90  complexVal3 = _mm_or_si128(complexVal3, complexVal4);
91 
92 
93  complexVal1 = _mm_srai_epi16(complexVal1, 8);
94  complexVal3 = _mm_srai_epi16(complexVal3, 8);
95 
96  iOutputVal = _mm_packs_epi16(complexVal1, complexVal3);
97 
98  _mm_store_si128((__m128i*)iBufferPtr, iOutputVal);
99 
100  iBufferPtr += 16;
101  }
102 
103  number = sixteenthPoints * 16;
104  int16_t* int16ComplexVectorPtr = (int16_t*)complexVectorPtr;
105  for(; number < num_points; number++){
106  *iBufferPtr++ = ((int8_t)(*int16ComplexVectorPtr++ >> 8));
107  int16ComplexVectorPtr++;
108  }
109 }
110 #endif /* LV_HAVE_SSSE3 */
111 
112 #ifdef LV_HAVE_GENERIC
113 
114 static inline void
115 volk_16ic_deinterleave_real_8i_generic(int8_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points)
116 {
117  unsigned int number = 0;
118  int16_t* complexVectorPtr = (int16_t*)complexVector;
119  int8_t* iBufferPtr = iBuffer;
120  for(number = 0; number < num_points; number++){
121  *iBufferPtr++ = ((int8_t)(*complexVectorPtr++ >> 8));
122  complexVectorPtr++;
123  }
124 }
125 #endif /* LV_HAVE_GENERIC */
126 
127 #ifdef LV_HAVE_NEON
128 #include <arm_neon.h>
129 
130 static inline void
131 volk_16ic_deinterleave_real_8i_neon(int8_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points)
132 {
133  const int16_t* complexVectorPtr = (const int16_t*)complexVector;
134  int8_t* iBufferPtr = iBuffer;
135  unsigned int eighth_points = num_points / 8;
136  unsigned int number;
137 
138  int16x8x2_t complexInput;
139  int8x8_t realOutput;
140  for(number = 0; number < eighth_points; number++){
141  complexInput = vld2q_s16(complexVectorPtr);
142  realOutput = vshrn_n_s16(complexInput.val[0], 8);
143  vst1_s8(iBufferPtr, realOutput);
144  complexVectorPtr += 16;
145  iBufferPtr += 8;
146  }
147 
148  for(number = eighth_points*8; number < num_points; number++){
149  *iBufferPtr++ = ((int8_t)(*complexVectorPtr++ >> 8));
150  complexVectorPtr++;
151  }
152 }
153 #endif
154 
155 #ifdef LV_HAVE_ORC
156 
157 extern void
158 volk_16ic_deinterleave_real_8i_a_orc_impl(int8_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points);
159 
160 static inline void
161 volk_16ic_deinterleave_real_8i_u_orc(int8_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points)
162 {
163  volk_16ic_deinterleave_real_8i_a_orc_impl(iBuffer, complexVector, num_points);
164 }
165 #endif /* LV_HAVE_ORC */
166 
167 
168 #endif /* INCLUDED_volk_16ic_deinterleave_real_8i_a_H */
short complex lv_16sc_t
Definition: volk_complex.h:53
signed short int16_t
Definition: stdint.h:76
signed char int8_t
Definition: stdint.h:75