GNU Radio 3.7.3 C++ API
volk_16ic_s32f_magnitude_32f.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_16ic_s32f_magnitude_32f_a_H
2 #define INCLUDED_volk_16ic_s32f_magnitude_32f_a_H
3 
4 #include <volk/volk_common.h>
5 #include <inttypes.h>
6 #include <stdio.h>
7 #include <math.h>
8 
9 #ifdef LV_HAVE_SSE3
10 #include <pmmintrin.h>
11 /*!
12  \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
13  \param complexVector The vector containing the complex input values
14  \param magnitudeVector The vector containing the real output values
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 values in complexVector to be calculated and stored into cVector
17 */
18 static inline void volk_16ic_s32f_magnitude_32f_a_sse3(float* magnitudeVector, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
19  unsigned int number = 0;
20  const unsigned int quarterPoints = num_points / 4;
21 
22  const int16_t* complexVectorPtr = (const int16_t*)complexVector;
23  float* magnitudeVectorPtr = magnitudeVector;
24 
25  __m128 invScalar = _mm_set_ps1(1.0/scalar);
26 
27  __m128 cplxValue1, cplxValue2, result;
28 
29  __VOLK_ATTR_ALIGNED(16) float inputFloatBuffer[8];
30 
31  for(;number < quarterPoints; number++){
32 
33  inputFloatBuffer[0] = (float)(complexVectorPtr[0]);
34  inputFloatBuffer[1] = (float)(complexVectorPtr[1]);
35  inputFloatBuffer[2] = (float)(complexVectorPtr[2]);
36  inputFloatBuffer[3] = (float)(complexVectorPtr[3]);
37 
38  inputFloatBuffer[4] = (float)(complexVectorPtr[4]);
39  inputFloatBuffer[5] = (float)(complexVectorPtr[5]);
40  inputFloatBuffer[6] = (float)(complexVectorPtr[6]);
41  inputFloatBuffer[7] = (float)(complexVectorPtr[7]);
42 
43  cplxValue1 = _mm_load_ps(&inputFloatBuffer[0]);
44  cplxValue2 = _mm_load_ps(&inputFloatBuffer[4]);
45 
46  complexVectorPtr += 8;
47 
48  cplxValue1 = _mm_mul_ps(cplxValue1, invScalar);
49  cplxValue2 = _mm_mul_ps(cplxValue2, invScalar);
50 
51  cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
52  cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
53 
54  result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
55 
56  result = _mm_sqrt_ps(result); // Square root the values
57 
58  _mm_store_ps(magnitudeVectorPtr, result);
59 
60  magnitudeVectorPtr += 4;
61  }
62 
63  number = quarterPoints * 4;
64  magnitudeVectorPtr = &magnitudeVector[number];
65  complexVectorPtr = (const int16_t*)&complexVector[number];
66  for(; number < num_points; number++){
67  float val1Real = (float)(*complexVectorPtr++) / scalar;
68  float val1Imag = (float)(*complexVectorPtr++) / scalar;
69  *magnitudeVectorPtr++ = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag));
70  }
71 }
72 #endif /* LV_HAVE_SSE3 */
73 
74 #ifdef LV_HAVE_SSE
75 #include <xmmintrin.h>
76 /*!
77  \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
78  \param complexVector The vector containing the complex input values
79  \param magnitudeVector The vector containing the real output values
80  \param scalar The data value to be divided against each input data value of the input complex vector
81  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
82 */
83 static inline void volk_16ic_s32f_magnitude_32f_a_sse(float* magnitudeVector, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
84  unsigned int number = 0;
85  const unsigned int quarterPoints = num_points / 4;
86 
87  const int16_t* complexVectorPtr = (const int16_t*)complexVector;
88  float* magnitudeVectorPtr = magnitudeVector;
89 
90  const float iScalar = 1.0 / scalar;
91  __m128 invScalar = _mm_set_ps1(iScalar);
92 
93  __m128 cplxValue1, cplxValue2, result, re, im;
94 
95  __VOLK_ATTR_ALIGNED(16) float inputFloatBuffer[8];
96 
97  for(;number < quarterPoints; number++){
98  inputFloatBuffer[0] = (float)(complexVectorPtr[0]);
99  inputFloatBuffer[1] = (float)(complexVectorPtr[1]);
100  inputFloatBuffer[2] = (float)(complexVectorPtr[2]);
101  inputFloatBuffer[3] = (float)(complexVectorPtr[3]);
102 
103  inputFloatBuffer[4] = (float)(complexVectorPtr[4]);
104  inputFloatBuffer[5] = (float)(complexVectorPtr[5]);
105  inputFloatBuffer[6] = (float)(complexVectorPtr[6]);
106  inputFloatBuffer[7] = (float)(complexVectorPtr[7]);
107 
108  cplxValue1 = _mm_load_ps(&inputFloatBuffer[0]);
109  cplxValue2 = _mm_load_ps(&inputFloatBuffer[4]);
110 
111  re = _mm_shuffle_ps(cplxValue1, cplxValue2, 0x88);
112  im = _mm_shuffle_ps(cplxValue1, cplxValue2, 0xdd);
113 
114  complexVectorPtr += 8;
115 
116  cplxValue1 = _mm_mul_ps(re, invScalar);
117  cplxValue2 = _mm_mul_ps(im, invScalar);
118 
119  cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
120  cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
121 
122  result = _mm_add_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
123 
124  result = _mm_sqrt_ps(result); // Square root the values
125 
126  _mm_store_ps(magnitudeVectorPtr, result);
127 
128  magnitudeVectorPtr += 4;
129  }
130 
131  number = quarterPoints * 4;
132  magnitudeVectorPtr = &magnitudeVector[number];
133  complexVectorPtr = (const int16_t*)&complexVector[number];
134  for(; number < num_points; number++){
135  float val1Real = (float)(*complexVectorPtr++) * iScalar;
136  float val1Imag = (float)(*complexVectorPtr++) * iScalar;
137  *magnitudeVectorPtr++ = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag));
138  }
139 }
140 
141 
142 #endif /* LV_HAVE_SSE */
143 
144 #ifdef LV_HAVE_GENERIC
145 /*!
146  \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
147  \param complexVector The vector containing the complex input values
148  \param magnitudeVector The vector containing the real output values
149  \param scalar The data value to be divided against each input data value of the input complex vector
150  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
151 */
152 static inline void volk_16ic_s32f_magnitude_32f_generic(float* magnitudeVector, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
153  const int16_t* complexVectorPtr = (const int16_t*)complexVector;
154  float* magnitudeVectorPtr = magnitudeVector;
155  unsigned int number = 0;
156  const float invScalar = 1.0 / scalar;
157  for(number = 0; number < num_points; number++){
158  float real = ( (float) (*complexVectorPtr++)) * invScalar;
159  float imag = ( (float) (*complexVectorPtr++)) * invScalar;
160  *magnitudeVectorPtr++ = sqrtf((real*real) + (imag*imag));
161  }
162 }
163 #endif /* LV_HAVE_GENERIC */
164 
165 #ifdef LV_HAVE_ORC_DISABLED
166 /*!
167  \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
168  \param complexVector The vector containing the complex input values
169  \param magnitudeVector The vector containing the real output values
170  \param scalar The data value to be divided against each input data value of the input complex vector
171  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
172 */
173 extern void volk_16ic_s32f_magnitude_32f_a_orc_impl(float* magnitudeVector, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points);
174 static inline void volk_16ic_s32f_magnitude_32f_u_orc(float* magnitudeVector, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
175  volk_16ic_s32f_magnitude_32f_a_orc_impl(magnitudeVector, complexVector, scalar, num_points);
176 }
177 #endif /* LV_HAVE_ORC */
178 
179 
180 #endif /* INCLUDED_volk_16ic_s32f_magnitude_32f_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