GNU Radio 3.6.5 C++ API

volk_32fc_s32f_magnitude_16i_a.h

Go to the documentation of this file.
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 */