GNU Radio 3.4.0 C++ API
volk_16ic_s32f_magnitude_32f_a16.h
Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_16ic_s32f_magnitude_32f_a16_H
00002 #define INCLUDED_volk_16ic_s32f_magnitude_32f_a16_H
00003 
00004 #include <inttypes.h>
00005 #include <stdio.h>
00006 #include <math.h>
00007 
00008 #if 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 scalar The data value to be divided against each input data value of the input complex vector
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_s32f_magnitude_32f_a16_sse3(float* magnitudeVector, const lv_16sc_t* complexVector, const float scalar, 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   float* magnitudeVectorPtr = magnitudeVector;
00023 
00024   __m128 invScalar = _mm_set_ps1(1.0/scalar);
00025 
00026   __m128 cplxValue1, cplxValue2, result;
00027 
00028   float inputFloatBuffer[8] __attribute__((aligned(128)));
00029 
00030   for(;number < quarterPoints; number++){
00031 
00032     inputFloatBuffer[0] = (float)(complexVectorPtr[0]);
00033     inputFloatBuffer[1] = (float)(complexVectorPtr[1]);
00034     inputFloatBuffer[2] = (float)(complexVectorPtr[2]);
00035     inputFloatBuffer[3] = (float)(complexVectorPtr[3]);
00036       
00037     inputFloatBuffer[4] = (float)(complexVectorPtr[4]);
00038     inputFloatBuffer[5] = (float)(complexVectorPtr[5]);
00039     inputFloatBuffer[6] = (float)(complexVectorPtr[6]);
00040     inputFloatBuffer[7] = (float)(complexVectorPtr[7]);
00041 
00042     cplxValue1 = _mm_load_ps(&inputFloatBuffer[0]);
00043     cplxValue2 = _mm_load_ps(&inputFloatBuffer[4]);
00044 
00045     complexVectorPtr += 8;
00046 
00047     cplxValue1 = _mm_mul_ps(cplxValue1, invScalar);
00048     cplxValue2 = _mm_mul_ps(cplxValue2, invScalar);
00049 
00050     cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
00051     cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
00052 
00053     result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
00054 
00055     result = _mm_sqrt_ps(result); // Square root the values
00056 
00057     _mm_store_ps(magnitudeVectorPtr, result);
00058       
00059     magnitudeVectorPtr += 4;
00060   }
00061 
00062   number = quarterPoints * 4;
00063   magnitudeVectorPtr = &magnitudeVector[number];
00064   complexVectorPtr = (const int16_t*)&complexVector[number];
00065   for(; number < num_points; number++){
00066     float val1Real = (float)(*complexVectorPtr++) / scalar;
00067     float val1Imag = (float)(*complexVectorPtr++) / scalar;
00068     *magnitudeVectorPtr++ = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag));
00069   }
00070 }
00071 #endif /* LV_HAVE_SSE3 */
00072 
00073 #if LV_HAVE_SSE
00074 #include <xmmintrin.h>
00075 /*!
00076   \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
00077   \param complexVector The vector containing the complex input values
00078   \param magnitudeVector The vector containing the real output values
00079   \param scalar The data value to be divided against each input data value of the input complex vector
00080   \param num_points The number of complex values in complexVector to be calculated and stored into cVector
00081 */
00082 static inline void volk_16ic_s32f_magnitude_32f_a16_sse(float* magnitudeVector, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
00083   unsigned int number = 0;
00084   const unsigned int quarterPoints = num_points / 4;
00085 
00086   const int16_t* complexVectorPtr = (const int16_t*)complexVector;
00087   float* magnitudeVectorPtr = magnitudeVector;
00088 
00089   const float iScalar = 1.0 / scalar;
00090   __m128 invScalar = _mm_set_ps1(iScalar);
00091 
00092   __m128 cplxValue1, cplxValue2, result, re, im;
00093 
00094   float inputFloatBuffer[8] __attribute__((aligned(128)));
00095 
00096   for(;number < quarterPoints; number++){
00097     inputFloatBuffer[0] = (float)(complexVectorPtr[0]);
00098     inputFloatBuffer[1] = (float)(complexVectorPtr[1]);
00099     inputFloatBuffer[2] = (float)(complexVectorPtr[2]);
00100     inputFloatBuffer[3] = (float)(complexVectorPtr[3]);
00101       
00102     inputFloatBuffer[4] = (float)(complexVectorPtr[4]);
00103     inputFloatBuffer[5] = (float)(complexVectorPtr[5]);
00104     inputFloatBuffer[6] = (float)(complexVectorPtr[6]);
00105     inputFloatBuffer[7] = (float)(complexVectorPtr[7]);
00106 
00107     cplxValue1 = _mm_load_ps(&inputFloatBuffer[0]);
00108     cplxValue2 = _mm_load_ps(&inputFloatBuffer[4]);
00109     
00110     re = _mm_shuffle_ps(cplxValue1, cplxValue2, 0x88);
00111     im = _mm_shuffle_ps(cplxValue1, cplxValue2, 0xdd);
00112 
00113     complexVectorPtr += 8;
00114 
00115     cplxValue1 = _mm_mul_ps(re, invScalar);
00116     cplxValue2 = _mm_mul_ps(im, invScalar);
00117 
00118     cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
00119     cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
00120 
00121     result = _mm_add_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
00122 
00123     result = _mm_sqrt_ps(result); // Square root the values
00124 
00125     _mm_store_ps(magnitudeVectorPtr, result);
00126       
00127     magnitudeVectorPtr += 4;
00128   }
00129 
00130   number = quarterPoints * 4;
00131   magnitudeVectorPtr = &magnitudeVector[number];
00132   complexVectorPtr = (const int16_t*)&complexVector[number];
00133   for(; number < num_points; number++){
00134     float val1Real = (float)(*complexVectorPtr++) * iScalar;
00135     float val1Imag = (float)(*complexVectorPtr++) * iScalar;
00136     *magnitudeVectorPtr++ = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag));
00137   }
00138 }
00139 
00140  
00141 #endif /* LV_HAVE_SSE */
00142 
00143 #if LV_HAVE_GENERIC
00144 /*!
00145   \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
00146   \param complexVector The vector containing the complex input values
00147   \param magnitudeVector The vector containing the real output values
00148   \param scalar The data value to be divided against each input data value of the input complex vector
00149   \param num_points The number of complex values in complexVector to be calculated and stored into cVector
00150 */
00151 static inline void volk_16ic_s32f_magnitude_32f_a16_generic(float* magnitudeVector, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
00152   const int16_t* complexVectorPtr = (const int16_t*)complexVector;
00153   float* magnitudeVectorPtr = magnitudeVector;
00154   unsigned int number = 0;
00155   const float invScalar = 1.0 / scalar;
00156   for(number = 0; number < num_points; number++){
00157     float real = ( (float) (*complexVectorPtr++)) * invScalar;
00158     float imag = ( (float) (*complexVectorPtr++)) * invScalar;
00159     *magnitudeVectorPtr++ = sqrtf((real*real) + (imag*imag));
00160   }
00161 }
00162 #endif /* LV_HAVE_GENERIC */
00163 
00164 #if LV_HAVE_ORC_DISABLED
00165 /*!
00166   \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
00167   \param complexVector The vector containing the complex input values
00168   \param magnitudeVector The vector containing the real output values
00169   \param scalar The data value to be divided against each input data value of the input complex vector
00170   \param num_points The number of complex values in complexVector to be calculated and stored into cVector
00171 */
00172 extern void volk_16ic_s32f_magnitude_32f_a16_orc_impl(float* magnitudeVector, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points);
00173 static inline void volk_16ic_s32f_magnitude_32f_a16_orc(float* magnitudeVector, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
00174     volk_16ic_s32f_magnitude_32f_a16_orc_impl(magnitudeVector, complexVector, scalar, num_points);
00175 }
00176 #endif /* LV_HAVE_ORC */
00177 
00178 
00179 #endif /* INCLUDED_volk_16ic_s32f_magnitude_32f_a16_H */