GNU Radio 3.6.5 C++ API
|
00001 #ifndef INCLUDED_volk_32fc_s32f_magnitude_16i_a_H 00002 #define INCLUDED_volk_32fc_s32f_magnitude_16i_a_H 00003 00004 #include <volk/volk_common.h> 00005 #include <inttypes.h> 00006 #include <stdio.h> 00007 #include <math.h> 00008 00009 #ifdef LV_HAVE_SSE3 00010 #include <pmmintrin.h> 00011 /*! 00012 \brief Calculates the magnitude of the complexVector, scales the resulting value and stores the results in the magnitudeVector 00013 \param complexVector The vector containing the complex input values 00014 \param scalar The scale value multiplied to the magnitude of each complex vector 00015 \param magnitudeVector The vector containing the real output values 00016 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00017 */ 00018 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){ 00019 unsigned int number = 0; 00020 const unsigned int quarterPoints = num_points / 4; 00021 00022 const float* complexVectorPtr = (const float*)complexVector; 00023 int16_t* magnitudeVectorPtr = magnitudeVector; 00024 00025 __m128 vScalar = _mm_set_ps1(scalar); 00026 00027 __m128 cplxValue1, cplxValue2, result; 00028 00029 __VOLK_ATTR_ALIGNED(16) float floatBuffer[4]; 00030 00031 for(;number < quarterPoints; number++){ 00032 cplxValue1 = _mm_load_ps(complexVectorPtr); 00033 complexVectorPtr += 4; 00034 00035 cplxValue2 = _mm_load_ps(complexVectorPtr); 00036 complexVectorPtr += 4; 00037 00038 cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values 00039 cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values 00040 00041 result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values 00042 00043 result = _mm_sqrt_ps(result); 00044 00045 result = _mm_mul_ps(result, vScalar); 00046 00047 _mm_store_ps(floatBuffer, result); 00048 *magnitudeVectorPtr++ = (int16_t)(floatBuffer[0]); 00049 *magnitudeVectorPtr++ = (int16_t)(floatBuffer[1]); 00050 *magnitudeVectorPtr++ = (int16_t)(floatBuffer[2]); 00051 *magnitudeVectorPtr++ = (int16_t)(floatBuffer[3]); 00052 } 00053 00054 number = quarterPoints * 4; 00055 magnitudeVectorPtr = &magnitudeVector[number]; 00056 for(; number < num_points; number++){ 00057 float val1Real = *complexVectorPtr++; 00058 float val1Imag = *complexVectorPtr++; 00059 *magnitudeVectorPtr++ = (int16_t)(sqrtf((val1Real * val1Real) + (val1Imag * val1Imag)) * scalar); 00060 } 00061 } 00062 #endif /* LV_HAVE_SSE3 */ 00063 00064 #ifdef LV_HAVE_SSE 00065 #include <xmmintrin.h> 00066 /*! 00067 \brief Calculates the magnitude of the complexVector, scales the resulting value and stores the results in the magnitudeVector 00068 \param complexVector The vector containing the complex input values 00069 \param scalar The scale value multiplied to the magnitude of each complex vector 00070 \param magnitudeVector The vector containing the real output values 00071 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00072 */ 00073 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){ 00074 unsigned int number = 0; 00075 const unsigned int quarterPoints = num_points / 4; 00076 00077 const float* complexVectorPtr = (const float*)complexVector; 00078 int16_t* magnitudeVectorPtr = magnitudeVector; 00079 00080 __m128 vScalar = _mm_set_ps1(scalar); 00081 00082 __m128 cplxValue1, cplxValue2, iValue, qValue, result; 00083 00084 __VOLK_ATTR_ALIGNED(16) float floatBuffer[4]; 00085 00086 for(;number < quarterPoints; number++){ 00087 cplxValue1 = _mm_load_ps(complexVectorPtr); 00088 complexVectorPtr += 4; 00089 00090 cplxValue2 = _mm_load_ps(complexVectorPtr); 00091 complexVectorPtr += 4; 00092 00093 // Arrange in i1i2i3i4 format 00094 iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0)); 00095 // Arrange in q1q2q3q4 format 00096 qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1)); 00097 00098 iValue = _mm_mul_ps(iValue, iValue); // Square the I values 00099 qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values 00100 00101 result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values 00102 00103 result = _mm_sqrt_ps(result); 00104 00105 result = _mm_mul_ps(result, vScalar); 00106 00107 _mm_store_ps(floatBuffer, result); 00108 *magnitudeVectorPtr++ = (int16_t)(floatBuffer[0]); 00109 *magnitudeVectorPtr++ = (int16_t)(floatBuffer[1]); 00110 *magnitudeVectorPtr++ = (int16_t)(floatBuffer[2]); 00111 *magnitudeVectorPtr++ = (int16_t)(floatBuffer[3]); 00112 } 00113 00114 number = quarterPoints * 4; 00115 magnitudeVectorPtr = &magnitudeVector[number]; 00116 for(; number < num_points; number++){ 00117 float val1Real = *complexVectorPtr++; 00118 float val1Imag = *complexVectorPtr++; 00119 *magnitudeVectorPtr++ = (int16_t)(sqrtf((val1Real * val1Real) + (val1Imag * val1Imag)) * scalar); 00120 } 00121 } 00122 #endif /* LV_HAVE_SSE */ 00123 00124 #ifdef LV_HAVE_GENERIC 00125 /*! 00126 \brief Calculates the magnitude of the complexVector, scales the resulting value and stores the results in the magnitudeVector 00127 \param complexVector The vector containing the complex input values 00128 \param scalar The scale value multiplied to the magnitude of each complex vector 00129 \param magnitudeVector The vector containing the real output values 00130 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00131 */ 00132 static inline void volk_32fc_s32f_magnitude_16i_a_generic(int16_t* magnitudeVector, const lv_32fc_t* complexVector, const float scalar, unsigned int num_points){ 00133 const float* complexVectorPtr = (float*)complexVector; 00134 int16_t* magnitudeVectorPtr = magnitudeVector; 00135 unsigned int number = 0; 00136 for(number = 0; number < num_points; number++){ 00137 const float real = *complexVectorPtr++; 00138 const float imag = *complexVectorPtr++; 00139 *magnitudeVectorPtr++ = (int16_t)(sqrtf((real*real) + (imag*imag)) * scalar); 00140 } 00141 } 00142 #endif /* LV_HAVE_GENERIC */ 00143 00144 #ifdef LV_HAVE_ORC 00145 /*! 00146 \brief Calculates the magnitude of the complexVector, scales the resulting value and stores the results in the magnitudeVector 00147 \param complexVector The vector containing the complex input values 00148 \param scalar The scale value multiplied to the magnitude of each complex vector 00149 \param magnitudeVector The vector containing the real output values 00150 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00151 */ 00152 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); 00153 static inline void volk_32fc_s32f_magnitude_16i_a_orc(int16_t* magnitudeVector, const lv_32fc_t* complexVector, const float scalar, unsigned int num_points){ 00154 volk_32fc_s32f_magnitude_16i_a_orc_impl(magnitudeVector, complexVector, scalar, num_points); 00155 } 00156 #endif /* LV_HAVE_ORC */ 00157 00158 00159 #endif /* INCLUDED_volk_32fc_s32f_magnitude_16i_a_H */