GNU Radio 3.7.3 C++ API
volk_32fc_deinterleave_64f_x2.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_32fc_deinterleave_64f_x2_u_H
2 #define INCLUDED_volk_32fc_deinterleave_64f_x2_u_H
3 
4 #include <inttypes.h>
5 #include <stdio.h>
6 
7 #ifdef LV_HAVE_SSE2
8 #include <emmintrin.h>
9 /*!
10  \brief Deinterleaves the lv_32fc_t vector into double I & Q vector data
11  \param complexVector The complex input vector
12  \param iBuffer The I buffer output data
13  \param qBuffer The Q buffer output data
14  \param num_points The number of complex data values to be deinterleaved
15 */
16 static inline void volk_32fc_deinterleave_64f_x2_u_sse2(double* iBuffer, double* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
17  unsigned int number = 0;
18 
19  const float* complexVectorPtr = (float*)complexVector;
20  double* iBufferPtr = iBuffer;
21  double* qBufferPtr = qBuffer;
22 
23  const unsigned int halfPoints = num_points / 2;
24  __m128 cplxValue, fVal;
25  __m128d dVal;
26 
27  for(;number < halfPoints; number++){
28 
29  cplxValue = _mm_loadu_ps(complexVectorPtr);
30  complexVectorPtr += 4;
31 
32  // Arrange in i1i2i1i2 format
33  fVal = _mm_shuffle_ps(cplxValue, cplxValue, _MM_SHUFFLE(2,0,2,0));
34  dVal = _mm_cvtps_pd(fVal);
35  _mm_storeu_pd(iBufferPtr, dVal);
36 
37  // Arrange in q1q2q1q2 format
38  fVal = _mm_shuffle_ps(cplxValue, cplxValue, _MM_SHUFFLE(3,1,3,1));
39  dVal = _mm_cvtps_pd(fVal);
40  _mm_storeu_pd(qBufferPtr, dVal);
41 
42  iBufferPtr += 2;
43  qBufferPtr += 2;
44  }
45 
46  number = halfPoints * 2;
47  for(; number < num_points; number++){
48  *iBufferPtr++ = *complexVectorPtr++;
49  *qBufferPtr++ = *complexVectorPtr++;
50  }
51 }
52 #endif /* LV_HAVE_SSE */
53 
54 #ifdef LV_HAVE_GENERIC
55 /*!
56  \brief Deinterleaves the lv_32fc_t vector into double I & Q vector data
57  \param complexVector The complex input vector
58  \param iBuffer The I buffer output data
59  \param qBuffer The Q buffer output data
60  \param num_points The number of complex data values to be deinterleaved
61 */
62 static inline void volk_32fc_deinterleave_64f_x2_generic(double* iBuffer, double* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
63  unsigned int number = 0;
64  const float* complexVectorPtr = (float*)complexVector;
65  double* iBufferPtr = iBuffer;
66  double* qBufferPtr = qBuffer;
67 
68  for(number = 0; number < num_points; number++){
69  *iBufferPtr++ = (double)*complexVectorPtr++;
70  *qBufferPtr++ = (double)*complexVectorPtr++;
71  }
72 }
73 #endif /* LV_HAVE_GENERIC */
74 
75 
76 
77 
78 #endif /* INCLUDED_volk_32fc_deinterleave_64f_x2_u_H */
79 #ifndef INCLUDED_volk_32fc_deinterleave_64f_x2_a_H
80 #define INCLUDED_volk_32fc_deinterleave_64f_x2_a_H
81 
82 #include <inttypes.h>
83 #include <stdio.h>
84 
85 #ifdef LV_HAVE_SSE2
86 #include <emmintrin.h>
87 /*!
88  \brief Deinterleaves the lv_32fc_t vector into double I & Q vector data
89  \param complexVector The complex input vector
90  \param iBuffer The I buffer output data
91  \param qBuffer The Q buffer output data
92  \param num_points The number of complex data values to be deinterleaved
93 */
94 static inline void volk_32fc_deinterleave_64f_x2_a_sse2(double* iBuffer, double* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
95  unsigned int number = 0;
96 
97  const float* complexVectorPtr = (float*)complexVector;
98  double* iBufferPtr = iBuffer;
99  double* qBufferPtr = qBuffer;
100 
101  const unsigned int halfPoints = num_points / 2;
102  __m128 cplxValue, fVal;
103  __m128d dVal;
104 
105  for(;number < halfPoints; number++){
106 
107  cplxValue = _mm_load_ps(complexVectorPtr);
108  complexVectorPtr += 4;
109 
110  // Arrange in i1i2i1i2 format
111  fVal = _mm_shuffle_ps(cplxValue, cplxValue, _MM_SHUFFLE(2,0,2,0));
112  dVal = _mm_cvtps_pd(fVal);
113  _mm_store_pd(iBufferPtr, dVal);
114 
115  // Arrange in q1q2q1q2 format
116  fVal = _mm_shuffle_ps(cplxValue, cplxValue, _MM_SHUFFLE(3,1,3,1));
117  dVal = _mm_cvtps_pd(fVal);
118  _mm_store_pd(qBufferPtr, dVal);
119 
120  iBufferPtr += 2;
121  qBufferPtr += 2;
122  }
123 
124  number = halfPoints * 2;
125  for(; number < num_points; number++){
126  *iBufferPtr++ = *complexVectorPtr++;
127  *qBufferPtr++ = *complexVectorPtr++;
128  }
129 }
130 #endif /* LV_HAVE_SSE */
131 
132 #ifdef LV_HAVE_GENERIC
133 /*!
134  \brief Deinterleaves the lv_32fc_t vector into double I & Q vector data
135  \param complexVector The complex input vector
136  \param iBuffer The I buffer output data
137  \param qBuffer The Q buffer output data
138  \param num_points The number of complex data values to be deinterleaved
139 */
140 static inline void volk_32fc_deinterleave_64f_x2_a_generic(double* iBuffer, double* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
141  unsigned int number = 0;
142  const float* complexVectorPtr = (float*)complexVector;
143  double* iBufferPtr = iBuffer;
144  double* qBufferPtr = qBuffer;
145 
146  for(number = 0; number < num_points; number++){
147  *iBufferPtr++ = (double)*complexVectorPtr++;
148  *qBufferPtr++ = (double)*complexVectorPtr++;
149  }
150 }
151 #endif /* LV_HAVE_GENERIC */
152 
153 
154 
155 
156 #endif /* INCLUDED_volk_32fc_deinterleave_64f_x2_a_H */
float complex lv_32fc_t
Definition: volk_complex.h:56