GNU Radio 3.6.5 C++ API

volk_16ic_s32f_deinterleave_32f_x2_a.h

Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_16ic_s32f_deinterleave_32f_x2_a_H
00002 #define INCLUDED_volk_16ic_s32f_deinterleave_32f_x2_a_H
00003 
00004 #include <volk/volk_common.h>
00005 #include <inttypes.h>
00006 #include <stdio.h>
00007 
00008 #ifdef LV_HAVE_SSE
00009 #include <xmmintrin.h>
00010   /*!
00011     \brief Converts the complex 16 bit vector into floats,scales each data point, and deinterleaves into I & Q vector data
00012     \param complexVector The complex input vector
00013     \param iBuffer The I buffer output data
00014     \param qBuffer The Q buffer output data
00015     \param scalar The data value to be divided against each input data value of the input complex vector
00016     \param num_points The number of complex data values to be deinterleaved
00017   */
00018 static inline void volk_16ic_s32f_deinterleave_32f_x2_a_sse(float* iBuffer, float* qBuffer, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
00019     float* iBufferPtr = iBuffer;
00020     float* qBufferPtr = qBuffer;
00021 
00022     uint64_t number = 0;
00023     const uint64_t quarterPoints = num_points / 4;
00024     __m128 cplxValue1, cplxValue2, iValue, qValue;
00025 
00026     __m128 invScalar = _mm_set_ps1(1.0/scalar);
00027     int16_t* complexVectorPtr = (int16_t*)complexVector;
00028 
00029     __VOLK_ATTR_ALIGNED(16) float floatBuffer[8];
00030 
00031     for(;number < quarterPoints; number++){
00032 
00033       floatBuffer[0] = (float)(complexVectorPtr[0]);
00034       floatBuffer[1] = (float)(complexVectorPtr[1]);
00035       floatBuffer[2] = (float)(complexVectorPtr[2]);
00036       floatBuffer[3] = (float)(complexVectorPtr[3]);
00037 
00038       floatBuffer[4] = (float)(complexVectorPtr[4]);
00039       floatBuffer[5] = (float)(complexVectorPtr[5]);
00040       floatBuffer[6] = (float)(complexVectorPtr[6]);
00041       floatBuffer[7] = (float)(complexVectorPtr[7]);
00042 
00043       cplxValue1 = _mm_load_ps(&floatBuffer[0]);
00044       cplxValue2 = _mm_load_ps(&floatBuffer[4]);
00045 
00046       complexVectorPtr += 8;
00047 
00048       cplxValue1 = _mm_mul_ps(cplxValue1, invScalar);
00049       cplxValue2 = _mm_mul_ps(cplxValue2, invScalar);
00050 
00051       // Arrange in i1i2i3i4 format
00052       iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
00053       // Arrange in q1q2q3q4 format
00054       qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
00055 
00056       _mm_store_ps(iBufferPtr, iValue);
00057       _mm_store_ps(qBufferPtr, qValue);
00058 
00059       iBufferPtr += 4;
00060       qBufferPtr += 4;
00061     }
00062 
00063     number = quarterPoints * 4;
00064     complexVectorPtr = (int16_t*)&complexVector[number];
00065     for(; number < num_points; number++){
00066       *iBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
00067       *qBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
00068     }
00069 }
00070 #endif /* LV_HAVE_SSE */
00071 
00072 #ifdef LV_HAVE_GENERIC
00073   /*!
00074     \brief Converts the complex 16 bit vector into floats,scales each data point, and deinterleaves into I & Q vector data
00075     \param complexVector The complex input vector
00076     \param iBuffer The I buffer output data
00077     \param qBuffer The Q buffer output data
00078     \param scalar The data value to be divided against each input data value of the input complex vector
00079     \param num_points The number of complex data values to be deinterleaved
00080   */
00081 static inline void volk_16ic_s32f_deinterleave_32f_x2_a_generic(float* iBuffer, float* qBuffer, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
00082   const int16_t* complexVectorPtr = (const int16_t*)complexVector;
00083   float* iBufferPtr = iBuffer;
00084   float* qBufferPtr = qBuffer;
00085   unsigned int number;
00086   for(number = 0; number < num_points; number++){
00087     *iBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
00088     *qBufferPtr++ = (float)(*complexVectorPtr++) / scalar;
00089   }
00090 }
00091 #endif /* LV_HAVE_GENERIC */
00092 
00093 #ifdef LV_HAVE_ORC
00094   /*!
00095     \brief Converts the complex 16 bit vector into floats,scales each data point, and deinterleaves into I & Q vector data
00096     \param complexVector The complex input vector
00097     \param iBuffer The I buffer output data
00098     \param qBuffer The Q buffer output data
00099     \param scalar The data value to be divided against each input data value of the input complex vector
00100     \param num_points The number of complex data values to be deinterleaved
00101   */
00102 extern void volk_16ic_s32f_deinterleave_32f_x2_a_orc_impl(float* iBuffer, float* qBuffer, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points);
00103 static inline void volk_16ic_s32f_deinterleave_32f_x2_a_orc(float* iBuffer, float* qBuffer, const lv_16sc_t* complexVector, const float scalar, unsigned int num_points){
00104     volk_16ic_s32f_deinterleave_32f_x2_a_orc_impl(iBuffer, qBuffer, complexVector, scalar, num_points);
00105 }
00106 #endif /* LV_HAVE_ORC */
00107 
00108 
00109 #endif /* INCLUDED_volk_16ic_s32f_deinterleave_32f_x2_a_H */