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