GNU Radio 3.6.5 C++ API

volk_16ic_magnitude_16i_a.h

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