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_16i.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_16i
25  *
26  * \b Overview
27  *
28  * Deinterleaves the complex 16 bit vector and returns the real (inphase) part of the signal.
29  *
30  * <b>Dispatcher Prototype</b>
31  * \code
32  * void volk_16ic_deinterleave_real_16i(int16_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points)
33  * \endcode
34  *
35  * \b Inputs
36  * \li complexVector: The complex input vector.
37  * \li num_points: The number of complex data values to be deinterleaved.
38  *
39  * \b Outputs
40  * \li iBuffer: The I buffer output data.
41  *
42  * \b Example
43  * \code
44  * int N = 10000;
45  *
46  * volk_16ic_deinterleave_real_16i();
47  *
48  * volk_free(x);
49  * volk_free(t);
50  * \endcode
51  */
52 
53 #ifndef INCLUDED_volk_16ic_deinterleave_real_16i_a_H
54 #define INCLUDED_volk_16ic_deinterleave_real_16i_a_H
55 
56 #include <inttypes.h>
57 #include <stdio.h>
58 
59 #ifdef LV_HAVE_SSSE3
60 #include <tmmintrin.h>
61 
62 static inline void
63 volk_16ic_deinterleave_real_16i_a_ssse3(int16_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points)
64 {
65  unsigned int number = 0;
66  const int16_t* complexVectorPtr = (int16_t*)complexVector;
67  int16_t* iBufferPtr = iBuffer;
68 
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 
72  __m128i complexVal1, complexVal2, iOutputVal;
73 
74  unsigned int eighthPoints = num_points / 8;
75 
76  for(number = 0; number < eighthPoints; number++){
77  complexVal1 = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 8;
78  complexVal2 = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 8;
79 
80  complexVal1 = _mm_shuffle_epi8(complexVal1, iMoveMask1);
81  complexVal2 = _mm_shuffle_epi8(complexVal2, iMoveMask2);
82 
83  iOutputVal = _mm_or_si128(complexVal1, complexVal2);
84 
85  _mm_store_si128((__m128i*)iBufferPtr, iOutputVal);
86 
87  iBufferPtr += 8;
88  }
89 
90  number = eighthPoints * 8;
91  for(; number < num_points; number++){
92  *iBufferPtr++ = *complexVectorPtr++;
93  complexVectorPtr++;
94  }
95 }
96 #endif /* LV_HAVE_SSSE3 */
97 
98 
99 #ifdef LV_HAVE_SSE2
100 #include <emmintrin.h>
101 
102 static inline void
103 volk_16ic_deinterleave_real_16i_a_sse2(int16_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points)
104 {
105  unsigned int number = 0;
106  const int16_t* complexVectorPtr = (int16_t*)complexVector;
107  int16_t* iBufferPtr = iBuffer;
108  __m128i complexVal1, complexVal2, iOutputVal;
109  __m128i lowMask = _mm_set_epi32(0x0, 0x0, 0xFFFFFFFF, 0xFFFFFFFF);
110  __m128i highMask = _mm_set_epi32(0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0);
111 
112  unsigned int eighthPoints = num_points / 8;
113 
114  for(number = 0; number < eighthPoints; number++){
115  complexVal1 = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 8;
116  complexVal2 = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 8;
117 
118  complexVal1 = _mm_shufflelo_epi16(complexVal1, _MM_SHUFFLE(3,1,2,0));
119 
120  complexVal1 = _mm_shufflehi_epi16(complexVal1, _MM_SHUFFLE(3,1,2,0));
121 
122  complexVal1 = _mm_shuffle_epi32(complexVal1, _MM_SHUFFLE(3,1,2,0));
123 
124  complexVal2 = _mm_shufflelo_epi16(complexVal2, _MM_SHUFFLE(3,1,2,0));
125 
126  complexVal2 = _mm_shufflehi_epi16(complexVal2, _MM_SHUFFLE(3,1,2,0));
127 
128  complexVal2 = _mm_shuffle_epi32(complexVal2, _MM_SHUFFLE(2,0,3,1));
129 
130  iOutputVal = _mm_or_si128(_mm_and_si128(complexVal1, lowMask), _mm_and_si128(complexVal2, highMask));
131 
132  _mm_store_si128((__m128i*)iBufferPtr, iOutputVal);
133 
134  iBufferPtr += 8;
135  }
136 
137  number = eighthPoints * 8;
138  for(; number < num_points; number++){
139  *iBufferPtr++ = *complexVectorPtr++;
140  complexVectorPtr++;
141  }
142 }
143 #endif /* LV_HAVE_SSE2 */
144 
145 #ifdef LV_HAVE_GENERIC
146 
147 static inline void
148 volk_16ic_deinterleave_real_16i_generic(int16_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points)
149 {
150  unsigned int number = 0;
151  const int16_t* complexVectorPtr = (int16_t*)complexVector;
152  int16_t* iBufferPtr = iBuffer;
153  for(number = 0; number < num_points; number++){
154  *iBufferPtr++ = *complexVectorPtr++;
155  complexVectorPtr++;
156  }
157 }
158 #endif /* LV_HAVE_GENERIC */
159 
160 
161 #endif /* INCLUDED_volk_16ic_deinterleave_real_16i_a_H */
short complex lv_16sc_t
Definition: volk_complex.h:53
signed short int16_t
Definition: stdint.h:76