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