GNU Radio Manual and C++ API Reference  3.7.4.1
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
volk_32f_x2_s32f_interleave_16ic.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_32f_x2_s32f_interleave_16ic_a_H
2 #define INCLUDED_volk_32f_x2_s32f_interleave_16ic_a_H
3 
4 #include <volk/volk_common.h>
5 #include <inttypes.h>
6 #include <stdio.h>
7 
8 #ifdef LV_HAVE_SSE2
9 #include <emmintrin.h>
10  /*!
11  \brief Interleaves the I & Q vector data into the complex vector, scales the output values by the scalar, and converts to 16 bit data.
12  \param iBuffer The I buffer data to be interleaved
13  \param qBuffer The Q buffer data to be interleaved
14  \param complexVector The complex output vector
15  \param scalar The scaling value being multiplied against each data point
16  \param num_points The number of complex data values to be interleaved
17  */
18 static inline void volk_32f_x2_s32f_interleave_16ic_a_sse2(lv_16sc_t* complexVector, const float* iBuffer, const float* qBuffer, const float scalar, unsigned int num_points){
19  unsigned int number = 0;
20  const float* iBufferPtr = iBuffer;
21  const float* qBufferPtr = qBuffer;
22 
23  __m128 vScalar = _mm_set_ps1(scalar);
24 
25  const unsigned int quarterPoints = num_points / 4;
26 
27  __m128 iValue, qValue, cplxValue1, cplxValue2;
28  __m128i intValue1, intValue2;
29 
30  int16_t* complexVectorPtr = (int16_t*)complexVector;
31 
32  for(;number < quarterPoints; number++){
33  iValue = _mm_load_ps(iBufferPtr);
34  qValue = _mm_load_ps(qBufferPtr);
35 
36  // Interleaves the lower two values in the i and q variables into one buffer
37  cplxValue1 = _mm_unpacklo_ps(iValue, qValue);
38  cplxValue1 = _mm_mul_ps(cplxValue1, vScalar);
39 
40  // Interleaves the upper two values in the i and q variables into one buffer
41  cplxValue2 = _mm_unpackhi_ps(iValue, qValue);
42  cplxValue2 = _mm_mul_ps(cplxValue2, vScalar);
43 
44  intValue1 = _mm_cvtps_epi32(cplxValue1);
45  intValue2 = _mm_cvtps_epi32(cplxValue2);
46 
47  intValue1 = _mm_packs_epi32(intValue1, intValue2);
48 
49  _mm_store_si128((__m128i*)complexVectorPtr, intValue1);
50  complexVectorPtr += 8;
51 
52  iBufferPtr += 4;
53  qBufferPtr += 4;
54  }
55 
56  number = quarterPoints * 4;
57  complexVectorPtr = (int16_t*)(&complexVector[number]);
58  for(; number < num_points; number++){
59  *complexVectorPtr++ = (int16_t)(*iBufferPtr++ * scalar);
60  *complexVectorPtr++ = (int16_t)(*qBufferPtr++ * scalar);
61  }
62 
63 }
64 #endif /* LV_HAVE_SSE2 */
65 
66 #ifdef LV_HAVE_SSE
67 #include <xmmintrin.h>
68  /*!
69  \brief Interleaves the I & Q vector data into the complex vector, scales the output values by the scalar, and converts to 16 bit data.
70  \param iBuffer The I buffer data to be interleaved
71  \param qBuffer The Q buffer data to be interleaved
72  \param complexVector The complex output vector
73  \param scalar The scaling value being multiplied against each data point
74  \param num_points The number of complex data values to be interleaved
75  */
76 static inline void volk_32f_x2_s32f_interleave_16ic_a_sse(lv_16sc_t* complexVector, const float* iBuffer, const float* qBuffer, const float scalar, unsigned int num_points){
77  unsigned int number = 0;
78  const float* iBufferPtr = iBuffer;
79  const float* qBufferPtr = qBuffer;
80 
81  __m128 vScalar = _mm_set_ps1(scalar);
82 
83  const unsigned int quarterPoints = num_points / 4;
84 
85  __m128 iValue, qValue, cplxValue;
86 
87  int16_t* complexVectorPtr = (int16_t*)complexVector;
88 
89  __VOLK_ATTR_ALIGNED(16) float floatBuffer[4];
90 
91  for(;number < quarterPoints; number++){
92  iValue = _mm_load_ps(iBufferPtr);
93  qValue = _mm_load_ps(qBufferPtr);
94 
95  // Interleaves the lower two values in the i and q variables into one buffer
96  cplxValue = _mm_unpacklo_ps(iValue, qValue);
97  cplxValue = _mm_mul_ps(cplxValue, vScalar);
98 
99  _mm_store_ps(floatBuffer, cplxValue);
100 
101  *complexVectorPtr++ = (int16_t)(floatBuffer[0]);
102  *complexVectorPtr++ = (int16_t)(floatBuffer[1]);
103  *complexVectorPtr++ = (int16_t)(floatBuffer[2]);
104  *complexVectorPtr++ = (int16_t)(floatBuffer[3]);
105 
106  // Interleaves the upper two values in the i and q variables into one buffer
107  cplxValue = _mm_unpackhi_ps(iValue, qValue);
108  cplxValue = _mm_mul_ps(cplxValue, vScalar);
109 
110  _mm_store_ps(floatBuffer, cplxValue);
111 
112  *complexVectorPtr++ = (int16_t)(floatBuffer[0]);
113  *complexVectorPtr++ = (int16_t)(floatBuffer[1]);
114  *complexVectorPtr++ = (int16_t)(floatBuffer[2]);
115  *complexVectorPtr++ = (int16_t)(floatBuffer[3]);
116 
117  iBufferPtr += 4;
118  qBufferPtr += 4;
119  }
120 
121  number = quarterPoints * 4;
122  complexVectorPtr = (int16_t*)(&complexVector[number]);
123  for(; number < num_points; number++){
124  *complexVectorPtr++ = (int16_t)(*iBufferPtr++ * scalar);
125  *complexVectorPtr++ = (int16_t)(*qBufferPtr++ * scalar);
126  }
127 
128 }
129 #endif /* LV_HAVE_SSE */
130 
131 #ifdef LV_HAVE_GENERIC
132  /*!
133  \brief Interleaves the I & Q vector data into the complex vector, scales the output values by the scalar, and converts to 16 bit data.
134  \param iBuffer The I buffer data to be interleaved
135  \param qBuffer The Q buffer data to be interleaved
136  \param complexVector The complex output vector
137  \param scalar The scaling value being multiplied against each data point
138  \param num_points The number of complex data values to be interleaved
139  */
140 static inline void volk_32f_x2_s32f_interleave_16ic_generic(lv_16sc_t* complexVector, const float* iBuffer, const float* qBuffer, const float scalar, unsigned int num_points){
141  int16_t* complexVectorPtr = (int16_t*)complexVector;
142  const float* iBufferPtr = iBuffer;
143  const float* qBufferPtr = qBuffer;
144  unsigned int number = 0;
145 
146  for(number = 0; number < num_points; number++){
147  *complexVectorPtr++ = (int16_t)(*iBufferPtr++ * scalar);
148  *complexVectorPtr++ = (int16_t)(*qBufferPtr++ * scalar);
149  }
150 }
151 #endif /* LV_HAVE_GENERIC */
152 
153 
154 
155 
156 #endif /* INCLUDED_volk_32f_x2_s32f_interleave_16ic_a_H */
short complex lv_16sc_t
Definition: volk_complex.h:53
signed short int16_t
Definition: stdint.h:76
#define __VOLK_ATTR_ALIGNED(x)
Definition: volk_common.h:27