GNU Radio 3.6.5 C++ API
|
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 */