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_16ic_s32f_deinterleave_32f_x2.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_16ic_s32f_deinterleave_32f_x2_a_H
2 #define INCLUDED_volk_16ic_s32f_deinterleave_32f_x2_a_H
3 
4 #include <volk/volk_common.h>
5 #include <inttypes.h>
6 #include <stdio.h>
7 
8 #ifdef LV_HAVE_SSE
9 #include <xmmintrin.h>
10  /*!
11  \brief Converts the complex 16 bit vector into floats,scales each data point, and deinterleaves into I & Q vector data
12  \param complexVector The complex input vector
13  \param iBuffer The I buffer output data
14  \param qBuffer The Q buffer output data
15  \param scalar The data value to be divided against each input data value of the input complex vector
16  \param num_points The number of complex data values to be deinterleaved
17  */
18 static inline void volk_16ic_s32f_deinterleave_32f_x2_a_sse(float* iBuffer, float* qBuffer, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
19  float* iBufferPtr = iBuffer;
20  float* qBufferPtr = qBuffer;
21 
22  uint64_t number = 0;
23  const uint64_t quarterPoints = num_points / 4;
24  __m128 cplxValue1, cplxValue2, iValue, qValue;
25 
26  __m128 invScalar = _mm_set_ps1(1.0/scalar);
27  int16_t* complexVectorPtr = (int16_t*)complexVector;
28 
29  __VOLK_ATTR_ALIGNED(16) float floatBuffer[8];
30 
31  for(;number < quarterPoints; number++){
32 
33  floatBuffer[0] = (float)(complexVectorPtr[0]);
34  floatBuffer[1] = (float)(complexVectorPtr[1]);
35  floatBuffer[2] = (float)(complexVectorPtr[2]);
36  floatBuffer[3] = (float)(complexVectorPtr[3]);
37 
38  floatBuffer[4] = (float)(complexVectorPtr[4]);
39  floatBuffer[5] = (float)(complexVectorPtr[5]);
40  floatBuffer[6] = (float)(complexVectorPtr[6]);
41  floatBuffer[7] = (float)(complexVectorPtr[7]);
42 
43  cplxValue1 = _mm_load_ps(&floatBuffer[0]);
44  cplxValue2 = _mm_load_ps(&floatBuffer[4]);
45 
46  complexVectorPtr += 8;
47 
48  cplxValue1 = _mm_mul_ps(cplxValue1, invScalar);
49  cplxValue2 = _mm_mul_ps(cplxValue2, invScalar);
50 
51  // Arrange in i1i2i3i4 format
52  iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
53  // Arrange in q1q2q3q4 format
54  qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
55 
56  _mm_store_ps(iBufferPtr, iValue);
57  _mm_store_ps(qBufferPtr, qValue);
58 
59  iBufferPtr += 4;
60  qBufferPtr += 4;
61  }
62 
63  number = quarterPoints * 4;
64  complexVectorPtr = (int16_t*)&complexVector[number];
65  for(; number < num_points; number++){
66  *iBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
67  *qBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
68  }
69 }
70 #endif /* LV_HAVE_SSE */
71 
72 #ifdef LV_HAVE_GENERIC
73  /*!
74  \brief Converts the complex 16 bit vector into floats,scales each data point, and deinterleaves into I & Q vector data
75  \param complexVector The complex input vector
76  \param iBuffer The I buffer output data
77  \param qBuffer The Q buffer output data
78  \param scalar The data value to be divided against each input data value of the input complex vector
79  \param num_points The number of complex data values to be deinterleaved
80  */
81 static inline void volk_16ic_s32f_deinterleave_32f_x2_generic(float* iBuffer, float* qBuffer, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
82  const int16_t* complexVectorPtr = (const int16_t*)complexVector;
83  float* iBufferPtr = iBuffer;
84  float* qBufferPtr = qBuffer;
85  unsigned int number;
86  for(number = 0; number < num_points; number++){
87  *iBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
88  *qBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
89  }
90 }
91 #endif /* LV_HAVE_GENERIC */
92 
93 #ifdef LV_HAVE_ORC
94  /*!
95  \brief Converts the complex 16 bit vector into floats,scales each data point, and deinterleaves into I & Q vector data
96  \param complexVector The complex input vector
97  \param iBuffer The I buffer output data
98  \param qBuffer The Q buffer output data
99  \param scalar The data value to be divided against each input data value of the input complex vector
100  \param num_points The number of complex data values to be deinterleaved
101  */
102 extern void volk_16ic_s32f_deinterleave_32f_x2_a_orc_impl(float* iBuffer, float* qBuffer, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points);
103 static inline void volk_16ic_s32f_deinterleave_32f_x2_u_orc(float* iBuffer, float* qBuffer, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
104  volk_16ic_s32f_deinterleave_32f_x2_a_orc_impl(iBuffer, qBuffer, complexVector, scalar, num_points);
105 }
106 #endif /* LV_HAVE_ORC */
107 
108 
109 #endif /* INCLUDED_volk_16ic_s32f_deinterleave_32f_x2_a_H */
short complex lv_16sc_t
Definition: volk_complex.h:53
signed short int16_t
Definition: stdint.h:76
unsigned __int64 uint64_t
Definition: stdint.h:90
#define __VOLK_ATTR_ALIGNED(x)
Definition: volk_common.h:27