GNU Radio Manual and C++ API Reference  3.7.6.1
The Free & Open Software Radio Ecosystem
volk_16ic_s32f_deinterleave_32f_x2.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_16ic_s32f_deinterleave_32f_x2_a_H
24 #define INCLUDED_volk_16ic_s32f_deinterleave_32f_x2_a_H
25 
26 #include <volk/volk_common.h>
27 #include <inttypes.h>
28 #include <stdio.h>
29 
30 #ifdef LV_HAVE_SSE
31 #include <xmmintrin.h>
32  /*!
33  \brief Converts the complex 16 bit vector into floats,scales each data point, and deinterleaves into I & Q vector data
34  \param complexVector The complex input vector
35  \param iBuffer The I buffer output data
36  \param qBuffer The Q buffer output data
37  \param scalar The data value to be divided against each input data value of the input complex vector
38  \param num_points The number of complex data values to be deinterleaved
39  */
40 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){
41  float* iBufferPtr = iBuffer;
42  float* qBufferPtr = qBuffer;
43 
44  uint64_t number = 0;
45  const uint64_t quarterPoints = num_points / 4;
46  __m128 cplxValue1, cplxValue2, iValue, qValue;
47 
48  __m128 invScalar = _mm_set_ps1(1.0/scalar);
49  int16_t* complexVectorPtr = (int16_t*)complexVector;
50 
51  __VOLK_ATTR_ALIGNED(16) float floatBuffer[8];
52 
53  for(;number < quarterPoints; number++){
54 
55  floatBuffer[0] = (float)(complexVectorPtr[0]);
56  floatBuffer[1] = (float)(complexVectorPtr[1]);
57  floatBuffer[2] = (float)(complexVectorPtr[2]);
58  floatBuffer[3] = (float)(complexVectorPtr[3]);
59 
60  floatBuffer[4] = (float)(complexVectorPtr[4]);
61  floatBuffer[5] = (float)(complexVectorPtr[5]);
62  floatBuffer[6] = (float)(complexVectorPtr[6]);
63  floatBuffer[7] = (float)(complexVectorPtr[7]);
64 
65  cplxValue1 = _mm_load_ps(&floatBuffer[0]);
66  cplxValue2 = _mm_load_ps(&floatBuffer[4]);
67 
68  complexVectorPtr += 8;
69 
70  cplxValue1 = _mm_mul_ps(cplxValue1, invScalar);
71  cplxValue2 = _mm_mul_ps(cplxValue2, invScalar);
72 
73  // Arrange in i1i2i3i4 format
74  iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
75  // Arrange in q1q2q3q4 format
76  qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
77 
78  _mm_store_ps(iBufferPtr, iValue);
79  _mm_store_ps(qBufferPtr, qValue);
80 
81  iBufferPtr += 4;
82  qBufferPtr += 4;
83  }
84 
85  number = quarterPoints * 4;
86  complexVectorPtr = (int16_t*)&complexVector[number];
87  for(; number < num_points; number++){
88  *iBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
89  *qBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
90  }
91 }
92 #endif /* LV_HAVE_SSE */
93 
94 #ifdef LV_HAVE_GENERIC
95  /*!
96  \brief Converts the complex 16 bit vector into floats,scales each data point, and deinterleaves into I & Q vector data
97  \param complexVector The complex input vector
98  \param iBuffer The I buffer output data
99  \param qBuffer The Q buffer output data
100  \param scalar The data value to be divided against each input data value of the input complex vector
101  \param num_points The number of complex data values to be deinterleaved
102  */
103 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){
104  const int16_t* complexVectorPtr = (const int16_t*)complexVector;
105  float* iBufferPtr = iBuffer;
106  float* qBufferPtr = qBuffer;
107  unsigned int number;
108  for(number = 0; number < num_points; number++){
109  *iBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
110  *qBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
111  }
112 }
113 #endif /* LV_HAVE_GENERIC */
114 
115 #ifdef LV_HAVE_ORC
116  /*!
117  \brief Converts the complex 16 bit vector into floats,scales each data point, and deinterleaves into I & Q vector data
118  \param complexVector The complex input vector
119  \param iBuffer The I buffer output data
120  \param qBuffer The Q buffer output data
121  \param scalar The data value to be divided against each input data value of the input complex vector
122  \param num_points The number of complex data values to be deinterleaved
123  */
124 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);
125 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){
126  volk_16ic_s32f_deinterleave_32f_x2_a_orc_impl(iBuffer, qBuffer, complexVector, scalar, num_points);
127 }
128 #endif /* LV_HAVE_ORC */
129 
130 
131 #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