GNU Radio 3.6.5 C++ API
|
00001 #ifndef INCLUDED_volk_16ic_magnitude_16i_a_H 00002 #define INCLUDED_volk_16ic_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 and stores the results in the magnitudeVector 00013 \param complexVector The vector containing the complex input values 00014 \param magnitudeVector The vector containing the real output values 00015 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00016 */ 00017 static inline void volk_16ic_magnitude_16i_a_sse3(int16_t* magnitudeVector, const lv_16sc_t* complexVector, unsigned int num_points){ 00018 unsigned int number = 0; 00019 const unsigned int quarterPoints = num_points / 4; 00020 00021 const int16_t* complexVectorPtr = (const int16_t*)complexVector; 00022 int16_t* magnitudeVectorPtr = magnitudeVector; 00023 00024 __m128 vScalar = _mm_set_ps1(32768.0); 00025 __m128 invScalar = _mm_set_ps1(1.0/32768.0); 00026 00027 __m128 cplxValue1, cplxValue2, result; 00028 00029 __VOLK_ATTR_ALIGNED(16) float inputFloatBuffer[8]; 00030 __VOLK_ATTR_ALIGNED(16) float outputFloatBuffer[4]; 00031 00032 for(;number < quarterPoints; number++){ 00033 00034 inputFloatBuffer[0] = (float)(complexVectorPtr[0]); 00035 inputFloatBuffer[1] = (float)(complexVectorPtr[1]); 00036 inputFloatBuffer[2] = (float)(complexVectorPtr[2]); 00037 inputFloatBuffer[3] = (float)(complexVectorPtr[3]); 00038 00039 inputFloatBuffer[4] = (float)(complexVectorPtr[4]); 00040 inputFloatBuffer[5] = (float)(complexVectorPtr[5]); 00041 inputFloatBuffer[6] = (float)(complexVectorPtr[6]); 00042 inputFloatBuffer[7] = (float)(complexVectorPtr[7]); 00043 00044 cplxValue1 = _mm_load_ps(&inputFloatBuffer[0]); 00045 cplxValue2 = _mm_load_ps(&inputFloatBuffer[4]); 00046 00047 complexVectorPtr += 8; 00048 00049 cplxValue1 = _mm_mul_ps(cplxValue1, invScalar); 00050 cplxValue2 = _mm_mul_ps(cplxValue2, invScalar); 00051 00052 cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values 00053 cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values 00054 00055 result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values 00056 00057 result = _mm_sqrt_ps(result); // Square root the values 00058 00059 result = _mm_mul_ps(result, vScalar); // Scale the results 00060 00061 _mm_store_ps(outputFloatBuffer, result); 00062 *magnitudeVectorPtr++ = (int16_t)(outputFloatBuffer[0]); 00063 *magnitudeVectorPtr++ = (int16_t)(outputFloatBuffer[1]); 00064 *magnitudeVectorPtr++ = (int16_t)(outputFloatBuffer[2]); 00065 *magnitudeVectorPtr++ = (int16_t)(outputFloatBuffer[3]); 00066 } 00067 00068 number = quarterPoints * 4; 00069 magnitudeVectorPtr = &magnitudeVector[number]; 00070 complexVectorPtr = (const int16_t*)&complexVector[number]; 00071 for(; number < num_points; number++){ 00072 const float val1Real = (float)(*complexVectorPtr++) / 32768.0; 00073 const float val1Imag = (float)(*complexVectorPtr++) / 32768.0; 00074 const float val1Result = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag)) * 32768.0; 00075 *magnitudeVectorPtr++ = (int16_t)(val1Result); 00076 } 00077 } 00078 #endif /* LV_HAVE_SSE3 */ 00079 00080 #ifdef LV_HAVE_SSE 00081 #include <xmmintrin.h> 00082 /*! 00083 \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector 00084 \param complexVector The vector containing the complex input values 00085 \param magnitudeVector The vector containing the real output values 00086 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00087 */ 00088 static inline void volk_16ic_magnitude_16i_a_sse(int16_t* magnitudeVector, const lv_16sc_t* complexVector, unsigned int num_points){ 00089 unsigned int number = 0; 00090 const unsigned int quarterPoints = num_points / 4; 00091 00092 const int16_t* complexVectorPtr = (const int16_t*)complexVector; 00093 int16_t* magnitudeVectorPtr = magnitudeVector; 00094 00095 __m128 vScalar = _mm_set_ps1(32768.0); 00096 __m128 invScalar = _mm_set_ps1(1.0/32768.0); 00097 00098 __m128 cplxValue1, cplxValue2, iValue, qValue, result; 00099 00100 __VOLK_ATTR_ALIGNED(16) float inputFloatBuffer[4]; 00101 __VOLK_ATTR_ALIGNED(16) float outputFloatBuffer[4]; 00102 00103 for(;number < quarterPoints; number++){ 00104 00105 inputFloatBuffer[0] = (float)(complexVectorPtr[0]); 00106 inputFloatBuffer[1] = (float)(complexVectorPtr[1]); 00107 inputFloatBuffer[2] = (float)(complexVectorPtr[2]); 00108 inputFloatBuffer[3] = (float)(complexVectorPtr[3]); 00109 00110 cplxValue1 = _mm_load_ps(inputFloatBuffer); 00111 complexVectorPtr += 4; 00112 00113 inputFloatBuffer[0] = (float)(complexVectorPtr[0]); 00114 inputFloatBuffer[1] = (float)(complexVectorPtr[1]); 00115 inputFloatBuffer[2] = (float)(complexVectorPtr[2]); 00116 inputFloatBuffer[3] = (float)(complexVectorPtr[3]); 00117 00118 cplxValue2 = _mm_load_ps(inputFloatBuffer); 00119 complexVectorPtr += 4; 00120 00121 cplxValue1 = _mm_mul_ps(cplxValue1, invScalar); 00122 cplxValue2 = _mm_mul_ps(cplxValue2, invScalar); 00123 00124 // Arrange in i1i2i3i4 format 00125 iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0)); 00126 // Arrange in q1q2q3q4 format 00127 qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1)); 00128 00129 iValue = _mm_mul_ps(iValue, iValue); // Square the I values 00130 qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values 00131 00132 result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values 00133 00134 result = _mm_sqrt_ps(result); // Square root the values 00135 00136 result = _mm_mul_ps(result, vScalar); // Scale the results 00137 00138 _mm_store_ps(outputFloatBuffer, result); 00139 *magnitudeVectorPtr++ = (int16_t)(outputFloatBuffer[0]); 00140 *magnitudeVectorPtr++ = (int16_t)(outputFloatBuffer[1]); 00141 *magnitudeVectorPtr++ = (int16_t)(outputFloatBuffer[2]); 00142 *magnitudeVectorPtr++ = (int16_t)(outputFloatBuffer[3]); 00143 } 00144 00145 number = quarterPoints * 4; 00146 magnitudeVectorPtr = &magnitudeVector[number]; 00147 complexVectorPtr = (const int16_t*)&complexVector[number]; 00148 for(; number < num_points; number++){ 00149 const float val1Real = (float)(*complexVectorPtr++) / 32768.0; 00150 const float val1Imag = (float)(*complexVectorPtr++) / 32768.0; 00151 const float val1Result = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag)) * 32768.0; 00152 *magnitudeVectorPtr++ = (int16_t)(val1Result); 00153 } 00154 } 00155 #endif /* LV_HAVE_SSE */ 00156 00157 #ifdef LV_HAVE_GENERIC 00158 /*! 00159 \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector 00160 \param complexVector The vector containing the complex input values 00161 \param magnitudeVector The vector containing the real output values 00162 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00163 */ 00164 static inline void volk_16ic_magnitude_16i_a_generic(int16_t* magnitudeVector, const lv_16sc_t* complexVector, unsigned int num_points){ 00165 const int16_t* complexVectorPtr = (const int16_t*)complexVector; 00166 int16_t* magnitudeVectorPtr = magnitudeVector; 00167 unsigned int number = 0; 00168 const float scalar = 32768.0; 00169 for(number = 0; number < num_points; number++){ 00170 float real = ((float)(*complexVectorPtr++)) / scalar; 00171 float imag = ((float)(*complexVectorPtr++)) / scalar; 00172 *magnitudeVectorPtr++ = (int16_t)(sqrtf((real*real) + (imag*imag)) * scalar); 00173 } 00174 } 00175 #endif /* LV_HAVE_GENERIC */ 00176 00177 #ifdef LV_HAVE_ORC_DISABLED 00178 /*! 00179 \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector 00180 \param complexVector The vector containing the complex input values 00181 \param magnitudeVector The vector containing the real output values 00182 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00183 */ 00184 extern void volk_16ic_magnitude_16i_a_orc_impl(int16_t* magnitudeVector, const lv_16sc_t* complexVector, float scalar, unsigned int num_points); 00185 static inline void volk_16ic_magnitude_16i_a_orc(int16_t* magnitudeVector, const lv_16sc_t* complexVector, unsigned int num_points){ 00186 volk_16ic_magnitude_16i_a_orc_impl(magnitudeVector, complexVector, 32768.0, num_points); 00187 } 00188 #endif /* LV_HAVE_ORC */ 00189 00190 00191 #endif /* INCLUDED_volk_16ic_magnitude_16i_a_H */