GNU Radio Manual and C++ API Reference  3.7.6.1
The Free & Open Software Radio Ecosystem
volk_32f_x2_interleave_32fc.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 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 #ifndef INCLUDED_volk_32f_x2_interleave_32fc_a_H
24 #define INCLUDED_volk_32f_x2_interleave_32fc_a_H
25 
26 #include <inttypes.h>
27 #include <stdio.h>
28 
29 #ifdef LV_HAVE_SSE
30 #include <xmmintrin.h>
31 /*!
32  \brief Interleaves the I & Q vector data into the complex vector
33  \param iBuffer The I buffer data to be interleaved
34  \param qBuffer The Q buffer data to be interleaved
35  \param complexVector The complex output vector
36  \param num_points The number of complex data values to be interleaved
37 */
38 static inline void volk_32f_x2_interleave_32fc_a_sse(lv_32fc_t* complexVector, const float* iBuffer, const float* qBuffer, unsigned int num_points){
39  unsigned int number = 0;
40  float* complexVectorPtr = (float*)complexVector;
41  const float* iBufferPtr = iBuffer;
42  const float* qBufferPtr = qBuffer;
43 
44  const uint64_t quarterPoints = num_points / 4;
45 
46  __m128 iValue, qValue, cplxValue;
47  for(;number < quarterPoints; number++){
48  iValue = _mm_load_ps(iBufferPtr);
49  qValue = _mm_load_ps(qBufferPtr);
50 
51  // Interleaves the lower two values in the i and q variables into one buffer
52  cplxValue = _mm_unpacklo_ps(iValue, qValue);
53  _mm_store_ps(complexVectorPtr, cplxValue);
54  complexVectorPtr += 4;
55 
56  // Interleaves the upper two values in the i and q variables into one buffer
57  cplxValue = _mm_unpackhi_ps(iValue, qValue);
58  _mm_store_ps(complexVectorPtr, cplxValue);
59  complexVectorPtr += 4;
60 
61  iBufferPtr += 4;
62  qBufferPtr += 4;
63  }
64 
65  number = quarterPoints * 4;
66  for(; number < num_points; number++){
67  *complexVectorPtr++ = *iBufferPtr++;
68  *complexVectorPtr++ = *qBufferPtr++;
69  }
70 }
71 #endif /* LV_HAVE_SSE */
72 
73 #ifdef LV_HAVE_NEON
74 #include <arm_neon.h>
75 /*!
76  \brief Interleaves the I & Q vector data into the complex vector.
77  \param iBuffer The I buffer data to be interleaved
78  \param qBuffer The Q buffer data to be interleaved
79  \param complexVector The complex output vector
80  \param num_points The number of complex data values to be interleaved
81 */
82 static inline void volk_32f_x2_interleave_32fc_neon(lv_32fc_t* complexVector, const float* iBuffer, const float* qBuffer, unsigned int num_points){
83  unsigned int quarter_points = num_points / 4;
84  unsigned int number;
85  float* complexVectorPtr = (float*) complexVector;
86 
87  float32x4x2_t complex_vec;
88  for(number=0; number < quarter_points; ++number) {
89  complex_vec.val[0] = vld1q_f32(iBuffer);
90  complex_vec.val[1] = vld1q_f32(qBuffer);
91  vst2q_f32(complexVectorPtr, complex_vec);
92  iBuffer += 4;
93  qBuffer += 4;
94  complexVectorPtr += 8;
95  }
96 
97  for(number=quarter_points * 4; number < num_points; ++number) {
98  *complexVectorPtr++ = *iBuffer++;
99  *complexVectorPtr++ = *qBuffer++;
100  }
101 
102 }
103 #endif /* LV_HAVE_NEON */
104 
105 
106 #ifdef LV_HAVE_GENERIC
107 /*!
108  \brief Interleaves the I & Q vector data into the complex vector.
109  \param iBuffer The I buffer data to be interleaved
110  \param qBuffer The Q buffer data to be interleaved
111  \param complexVector The complex output vector
112  \param num_points The number of complex data values to be interleaved
113 */
114 static inline void volk_32f_x2_interleave_32fc_generic(lv_32fc_t* complexVector, const float* iBuffer, const float* qBuffer, unsigned int num_points){
115  float* complexVectorPtr = (float*)complexVector;
116  const float* iBufferPtr = iBuffer;
117  const float* qBufferPtr = qBuffer;
118  unsigned int number;
119 
120  for(number = 0; number < num_points; number++){
121  *complexVectorPtr++ = *iBufferPtr++;
122  *complexVectorPtr++ = *qBufferPtr++;
123  }
124 }
125 #endif /* LV_HAVE_GENERIC */
126 
127 
128 
129 
130 #endif /* INCLUDED_volk_32f_x2_interleave_32fc_a_H */
unsigned __int64 uint64_t
Definition: stdint.h:90
float complex lv_32fc_t
Definition: volk_complex.h:56