GNU Radio 3.6.5 C++ API
|
00001 #ifndef INCLUDED_volk_32fc_magnitude_32f_a_H 00002 #define INCLUDED_volk_32fc_magnitude_32f_a_H 00003 00004 #include <inttypes.h> 00005 #include <stdio.h> 00006 #include <math.h> 00007 00008 #ifdef LV_HAVE_SSE3 00009 #include <pmmintrin.h> 00010 /*! 00011 \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector 00012 \param complexVector The vector containing the complex input values 00013 \param magnitudeVector The vector containing the real output values 00014 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00015 */ 00016 static inline void volk_32fc_magnitude_32f_a_sse3(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){ 00017 unsigned int number = 0; 00018 const unsigned int quarterPoints = num_points / 4; 00019 00020 const float* complexVectorPtr = (float*)complexVector; 00021 float* magnitudeVectorPtr = magnitudeVector; 00022 00023 __m128 cplxValue1, cplxValue2, result; 00024 for(;number < quarterPoints; number++){ 00025 cplxValue1 = _mm_load_ps(complexVectorPtr); 00026 complexVectorPtr += 4; 00027 00028 cplxValue2 = _mm_load_ps(complexVectorPtr); 00029 complexVectorPtr += 4; 00030 00031 cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values 00032 cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values 00033 00034 result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values 00035 00036 result = _mm_sqrt_ps(result); 00037 00038 _mm_store_ps(magnitudeVectorPtr, result); 00039 magnitudeVectorPtr += 4; 00040 } 00041 00042 number = quarterPoints * 4; 00043 for(; number < num_points; number++){ 00044 float val1Real = *complexVectorPtr++; 00045 float val1Imag = *complexVectorPtr++; 00046 *magnitudeVectorPtr++ = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag)); 00047 } 00048 } 00049 #endif /* LV_HAVE_SSE3 */ 00050 00051 #ifdef LV_HAVE_SSE 00052 #include <xmmintrin.h> 00053 /*! 00054 \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector 00055 \param complexVector The vector containing the complex input values 00056 \param magnitudeVector The vector containing the real output values 00057 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00058 */ 00059 static inline void volk_32fc_magnitude_32f_a_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){ 00060 unsigned int number = 0; 00061 const unsigned int quarterPoints = num_points / 4; 00062 00063 const float* complexVectorPtr = (float*)complexVector; 00064 float* magnitudeVectorPtr = magnitudeVector; 00065 00066 __m128 cplxValue1, cplxValue2, iValue, qValue, result; 00067 for(;number < quarterPoints; number++){ 00068 cplxValue1 = _mm_load_ps(complexVectorPtr); 00069 complexVectorPtr += 4; 00070 00071 cplxValue2 = _mm_load_ps(complexVectorPtr); 00072 complexVectorPtr += 4; 00073 00074 // Arrange in i1i2i3i4 format 00075 iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0)); 00076 // Arrange in q1q2q3q4 format 00077 qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1)); 00078 00079 iValue = _mm_mul_ps(iValue, iValue); // Square the I values 00080 qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values 00081 00082 result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values 00083 00084 result = _mm_sqrt_ps(result); 00085 00086 _mm_store_ps(magnitudeVectorPtr, result); 00087 magnitudeVectorPtr += 4; 00088 } 00089 00090 number = quarterPoints * 4; 00091 for(; number < num_points; number++){ 00092 float val1Real = *complexVectorPtr++; 00093 float val1Imag = *complexVectorPtr++; 00094 *magnitudeVectorPtr++ = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag)); 00095 } 00096 } 00097 #endif /* LV_HAVE_SSE */ 00098 00099 #ifdef LV_HAVE_GENERIC 00100 /*! 00101 \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector 00102 \param complexVector The vector containing the complex input values 00103 \param magnitudeVector The vector containing the real output values 00104 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00105 */ 00106 static inline void volk_32fc_magnitude_32f_a_generic(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){ 00107 const float* complexVectorPtr = (float*)complexVector; 00108 float* magnitudeVectorPtr = magnitudeVector; 00109 unsigned int number = 0; 00110 for(number = 0; number < num_points; number++){ 00111 const float real = *complexVectorPtr++; 00112 const float imag = *complexVectorPtr++; 00113 *magnitudeVectorPtr++ = sqrtf((real*real) + (imag*imag)); 00114 } 00115 } 00116 #endif /* LV_HAVE_GENERIC */ 00117 00118 #ifdef LV_HAVE_ORC 00119 /*! 00120 \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector 00121 \param complexVector The vector containing the complex input values 00122 \param magnitudeVector The vector containing the real output values 00123 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00124 */ 00125 extern void volk_32fc_magnitude_32f_a_orc_impl(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points); 00126 static inline void volk_32fc_magnitude_32f_a_orc(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){ 00127 volk_32fc_magnitude_32f_a_orc_impl(magnitudeVector, complexVector, num_points); 00128 } 00129 #endif /* LV_HAVE_ORC */ 00130 00131 00132 #endif /* INCLUDED_volk_32fc_magnitude_32f_a_H */