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_32fc_s32f_magnitude_16i.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_32fc_s32f_magnitude_16i_a_H
2 #define INCLUDED_volk_32fc_s32f_magnitude_16i_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, scales the resulting value and stores the results in the magnitudeVector
13  \param complexVector The vector containing the complex input values
14  \param scalar The scale value multiplied to the magnitude of each complex vector
15  \param magnitudeVector The vector containing the real output values
16  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
17 */
18 static inline void volk_32fc_s32f_magnitude_16i_a_sse3(int16_t* magnitudeVector, const lv_32fc_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 float* complexVectorPtr = (const float*)complexVector;
23  int16_t* magnitudeVectorPtr = magnitudeVector;
24 
25  __m128 vScalar = _mm_set_ps1(scalar);
26 
27  __m128 cplxValue1, cplxValue2, result;
28 
29  __VOLK_ATTR_ALIGNED(16) float floatBuffer[4];
30 
31  for(;number < quarterPoints; number++){
32  cplxValue1 = _mm_load_ps(complexVectorPtr);
33  complexVectorPtr += 4;
34 
35  cplxValue2 = _mm_load_ps(complexVectorPtr);
36  complexVectorPtr += 4;
37 
38  cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
39  cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
40 
41  result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
42 
43  result = _mm_sqrt_ps(result);
44 
45  result = _mm_mul_ps(result, vScalar);
46 
47  _mm_store_ps(floatBuffer, result);
48  *magnitudeVectorPtr++ = (int16_t)(floatBuffer[0]);
49  *magnitudeVectorPtr++ = (int16_t)(floatBuffer[1]);
50  *magnitudeVectorPtr++ = (int16_t)(floatBuffer[2]);
51  *magnitudeVectorPtr++ = (int16_t)(floatBuffer[3]);
52  }
53 
54  number = quarterPoints * 4;
55  magnitudeVectorPtr = &magnitudeVector[number];
56  for(; number < num_points; number++){
57  float val1Real = *complexVectorPtr++;
58  float val1Imag = *complexVectorPtr++;
59  *magnitudeVectorPtr++ = (int16_t)(sqrtf((val1Real * val1Real) + (val1Imag * val1Imag)) * scalar);
60  }
61 }
62 #endif /* LV_HAVE_SSE3 */
63 
64 #ifdef LV_HAVE_SSE
65 #include <xmmintrin.h>
66 /*!
67  \brief Calculates the magnitude of the complexVector, scales the resulting value and stores the results in the magnitudeVector
68  \param complexVector The vector containing the complex input values
69  \param scalar The scale value multiplied to the magnitude of each complex vector
70  \param magnitudeVector The vector containing the real output values
71  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
72 */
73 static inline void volk_32fc_s32f_magnitude_16i_a_sse(int16_t* magnitudeVector, const lv_32fc_t* complexVector, const float scalar, unsigned int num_points){
74  unsigned int number = 0;
75  const unsigned int quarterPoints = num_points / 4;
76 
77  const float* complexVectorPtr = (const float*)complexVector;
78  int16_t* magnitudeVectorPtr = magnitudeVector;
79 
80  __m128 vScalar = _mm_set_ps1(scalar);
81 
82  __m128 cplxValue1, cplxValue2, iValue, qValue, result;
83 
84  __VOLK_ATTR_ALIGNED(16) float floatBuffer[4];
85 
86  for(;number < quarterPoints; number++){
87  cplxValue1 = _mm_load_ps(complexVectorPtr);
88  complexVectorPtr += 4;
89 
90  cplxValue2 = _mm_load_ps(complexVectorPtr);
91  complexVectorPtr += 4;
92 
93  // Arrange in i1i2i3i4 format
94  iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
95  // Arrange in q1q2q3q4 format
96  qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
97 
98  iValue = _mm_mul_ps(iValue, iValue); // Square the I values
99  qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
100 
101  result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
102 
103  result = _mm_sqrt_ps(result);
104 
105  result = _mm_mul_ps(result, vScalar);
106 
107  _mm_store_ps(floatBuffer, result);
108  *magnitudeVectorPtr++ = (int16_t)(floatBuffer[0]);
109  *magnitudeVectorPtr++ = (int16_t)(floatBuffer[1]);
110  *magnitudeVectorPtr++ = (int16_t)(floatBuffer[2]);
111  *magnitudeVectorPtr++ = (int16_t)(floatBuffer[3]);
112  }
113 
114  number = quarterPoints * 4;
115  magnitudeVectorPtr = &magnitudeVector[number];
116  for(; number < num_points; number++){
117  float val1Real = *complexVectorPtr++;
118  float val1Imag = *complexVectorPtr++;
119  *magnitudeVectorPtr++ = (int16_t)(sqrtf((val1Real * val1Real) + (val1Imag * val1Imag)) * scalar);
120  }
121 }
122 #endif /* LV_HAVE_SSE */
123 
124 #ifdef LV_HAVE_GENERIC
125 /*!
126  \brief Calculates the magnitude of the complexVector, scales the resulting value and stores the results in the magnitudeVector
127  \param complexVector The vector containing the complex input values
128  \param scalar The scale value multiplied to the magnitude of each complex vector
129  \param magnitudeVector The vector containing the real output values
130  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
131 */
132 static inline void volk_32fc_s32f_magnitude_16i_generic(int16_t* magnitudeVector, const lv_32fc_t* complexVector, const float scalar, unsigned int num_points){
133  const float* complexVectorPtr = (float*)complexVector;
134  int16_t* magnitudeVectorPtr = magnitudeVector;
135  unsigned int number = 0;
136  for(number = 0; number < num_points; number++){
137  const float real = *complexVectorPtr++;
138  const float imag = *complexVectorPtr++;
139  *magnitudeVectorPtr++ = (int16_t)(sqrtf((real*real) + (imag*imag)) * scalar);
140  }
141 }
142 #endif /* LV_HAVE_GENERIC */
143 
144 #ifdef LV_HAVE_ORC
145 /*!
146  \brief Calculates the magnitude of the complexVector, scales the resulting value and stores the results in the magnitudeVector
147  \param complexVector The vector containing the complex input values
148  \param scalar The scale value multiplied to the magnitude of each complex vector
149  \param magnitudeVector The vector containing the real output values
150  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
151 */
152 extern void volk_32fc_s32f_magnitude_16i_a_orc_impl(int16_t* magnitudeVector, const lv_32fc_t* complexVector, const float scalar, unsigned int num_points);
153 static inline void volk_32fc_s32f_magnitude_16i_u_orc(int16_t* magnitudeVector, const lv_32fc_t* complexVector, const float scalar, unsigned int num_points){
154  volk_32fc_s32f_magnitude_16i_a_orc_impl(magnitudeVector, complexVector, scalar, num_points);
155 }
156 #endif /* LV_HAVE_ORC */
157 
158 
159 #endif /* INCLUDED_volk_32fc_s32f_magnitude_16i_a_H */
signed short int16_t
Definition: stdint.h:76
#define __VOLK_ATTR_ALIGNED(x)
Definition: volk_common.h:27
float complex lv_32fc_t
Definition: volk_complex.h:56