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_8ic_s32f_deinterleave_real_32f.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_8ic_s32f_deinterleave_real_32f
25  *
26  * \b Overview
27  *
28  * Deinterleaves the complex 8-bit char vector into just the real (I)
29  * vector, converts the samples to floats, and divides the results by
30  * the scalar factor.
31  *
32  * <b>Dispatcher Prototype</b>
33  * \code
34  * void volk_8ic_s32f_deinterleave_real_32f(float* iBuffer, const lv_8sc_t* complexVector, const float scalar, unsigned int num_points)
35  * \endcode
36  *
37  * \b Inputs
38  * \li complexVector: The complex input vector.
39  * \li scalar: The scalar value used to divide the floating point results.
40  * \li num_points: The number of complex data values to be deinterleaved.
41  *
42  * \b Outputs
43  * \li iBuffer: The I buffer output data.
44  *
45  * \b Example
46  * \code
47  * int N = 10000;
48  *
49  * volk_8ic_s32f_deinterleave_real_32f();
50  *
51  * volk_free(x);
52  * \endcode
53  */
54 
55 #ifndef INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H
56 #define INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H
57 
58 #include <volk/volk_common.h>
59 #include <inttypes.h>
60 #include <stdio.h>
61 
62 #ifdef LV_HAVE_SSE4_1
63 #include <smmintrin.h>
64 
65 static inline void
66 volk_8ic_s32f_deinterleave_real_32f_a_sse4_1(float* iBuffer, const lv_8sc_t* complexVector,
67  const float scalar, unsigned int num_points)
68 {
69  float* iBufferPtr = iBuffer;
70 
71  unsigned int number = 0;
72  const unsigned int eighthPoints = num_points / 8;
73  __m128 iFloatValue;
74 
75  const float iScalar= 1.0 / scalar;
76  __m128 invScalar = _mm_set_ps1(iScalar);
77  __m128i complexVal, iIntVal;
78  int8_t* complexVectorPtr = (int8_t*)complexVector;
79 
80  __m128i moveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
81 
82  for(;number < eighthPoints; number++){
83  complexVal = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16;
84  complexVal = _mm_shuffle_epi8(complexVal, moveMask);
85 
86  iIntVal = _mm_cvtepi8_epi32(complexVal);
87  iFloatValue = _mm_cvtepi32_ps(iIntVal);
88 
89  iFloatValue = _mm_mul_ps(iFloatValue, invScalar);
90 
91  _mm_store_ps(iBufferPtr, iFloatValue);
92 
93  iBufferPtr += 4;
94 
95  complexVal = _mm_srli_si128(complexVal, 4);
96  iIntVal = _mm_cvtepi8_epi32(complexVal);
97  iFloatValue = _mm_cvtepi32_ps(iIntVal);
98 
99  iFloatValue = _mm_mul_ps(iFloatValue, invScalar);
100 
101  _mm_store_ps(iBufferPtr, iFloatValue);
102 
103  iBufferPtr += 4;
104  }
105 
106  number = eighthPoints * 8;
107  for(; number < num_points; number++){
108  *iBufferPtr++ = (float)(*complexVectorPtr++) * iScalar;
109  complexVectorPtr++;
110  }
111 
112 }
113 #endif /* LV_HAVE_SSE4_1 */
114 
115 
116 #ifdef LV_HAVE_SSE
117 #include <xmmintrin.h>
118 
119 static inline void
120 volk_8ic_s32f_deinterleave_real_32f_a_sse(float* iBuffer, const lv_8sc_t* complexVector,
121  const float scalar, unsigned int num_points)
122 {
123  float* iBufferPtr = iBuffer;
124 
125  unsigned int number = 0;
126  const unsigned int quarterPoints = num_points / 4;
127  __m128 iValue;
128 
129  const float iScalar= 1.0 / scalar;
130  __m128 invScalar = _mm_set_ps1(iScalar);
131  int8_t* complexVectorPtr = (int8_t*)complexVector;
132 
133  __VOLK_ATTR_ALIGNED(16) float floatBuffer[4];
134 
135  for(;number < quarterPoints; number++){
136  floatBuffer[0] = (float)(*complexVectorPtr); complexVectorPtr += 2;
137  floatBuffer[1] = (float)(*complexVectorPtr); complexVectorPtr += 2;
138  floatBuffer[2] = (float)(*complexVectorPtr); complexVectorPtr += 2;
139  floatBuffer[3] = (float)(*complexVectorPtr); complexVectorPtr += 2;
140 
141  iValue = _mm_load_ps(floatBuffer);
142 
143  iValue = _mm_mul_ps(iValue, invScalar);
144 
145  _mm_store_ps(iBufferPtr, iValue);
146 
147  iBufferPtr += 4;
148  }
149 
150  number = quarterPoints * 4;
151  for(; number < num_points; number++){
152  *iBufferPtr++ = (float)(*complexVectorPtr++) * iScalar;
153  complexVectorPtr++;
154  }
155 
156 }
157 #endif /* LV_HAVE_SSE */
158 
159 
160 #ifdef LV_HAVE_GENERIC
161 
162 static inline void
163 volk_8ic_s32f_deinterleave_real_32f_generic(float* iBuffer, const lv_8sc_t* complexVector,
164  const float scalar, unsigned int num_points)
165 {
166  unsigned int number = 0;
167  const int8_t* complexVectorPtr = (const int8_t*)complexVector;
168  float* iBufferPtr = iBuffer;
169  const float invScalar = 1.0 / scalar;
170  for(number = 0; number < num_points; number++){
171  *iBufferPtr++ = ((float)(*complexVectorPtr++)) * invScalar;
172  complexVectorPtr++;
173  }
174 }
175 #endif /* LV_HAVE_GENERIC */
176 
177 
178 
179 #endif /* INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H */
signed char int8_t
Definition: stdint.h:75
#define __VOLK_ATTR_ALIGNED(x)
Definition: volk_common.h:27
char complex lv_8sc_t
Provide typedefs and operators for all complex types in C and C++.
Definition: volk_complex.h:52