GNU Radio 3.4.0 C++ API
|
00001 #ifndef INCLUDED_volk_32fc_s32f_deinterleave_real_16i_a16_H 00002 #define INCLUDED_volk_32fc_s32f_deinterleave_real_16i_a16_H 00003 00004 #include <inttypes.h> 00005 #include <stdio.h> 00006 00007 #if LV_HAVE_SSE 00008 #include <xmmintrin.h> 00009 /*! 00010 \brief Deinterleaves the complex vector, multiply the value by the scalar, convert to 16t, and in I vector data 00011 \param complexVector The complex input vector 00012 \param scalar The value to be multiply against each of the input values 00013 \param iBuffer The I buffer output data 00014 \param num_points The number of complex data values to be deinterleaved 00015 */ 00016 static inline void volk_32fc_s32f_deinterleave_real_16i_a16_sse(int16_t* iBuffer, const lv_32fc_t* complexVector, const float scalar, unsigned int num_points){ 00017 unsigned int number = 0; 00018 const unsigned int quarterPoints = num_points / 4; 00019 00020 const float* complexVectorPtr = (float*)complexVector; 00021 int16_t* iBufferPtr = iBuffer; 00022 00023 __m128 vScalar = _mm_set_ps1(scalar); 00024 00025 __m128 cplxValue1, cplxValue2, iValue; 00026 00027 float floatBuffer[4] __attribute__((aligned(128))); 00028 00029 for(;number < quarterPoints; number++){ 00030 cplxValue1 = _mm_load_ps(complexVectorPtr); 00031 complexVectorPtr += 4; 00032 00033 cplxValue2 = _mm_load_ps(complexVectorPtr); 00034 complexVectorPtr += 4; 00035 00036 // Arrange in i1i2i3i4 format 00037 iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0)); 00038 00039 iValue = _mm_mul_ps(iValue, vScalar); 00040 00041 _mm_store_ps(floatBuffer, iValue); 00042 *iBufferPtr++ = (int16_t)(floatBuffer[0]); 00043 *iBufferPtr++ = (int16_t)(floatBuffer[1]); 00044 *iBufferPtr++ = (int16_t)(floatBuffer[2]); 00045 *iBufferPtr++ = (int16_t)(floatBuffer[3]); 00046 } 00047 00048 number = quarterPoints * 4; 00049 iBufferPtr = &iBuffer[number]; 00050 for(; number < num_points; number++){ 00051 *iBufferPtr++ = (int16_t)(*complexVectorPtr++ * scalar); 00052 complexVectorPtr++; 00053 } 00054 } 00055 #endif /* LV_HAVE_SSE */ 00056 00057 #if LV_HAVE_GENERIC 00058 /*! 00059 \brief Deinterleaves the complex vector, multiply the value by the scalar, convert to 16t, and in I vector data 00060 \param complexVector The complex input vector 00061 \param scalar The value to be multiply against each of the input values 00062 \param iBuffer The I buffer output data 00063 \param num_points The number of complex data values to be deinterleaved 00064 */ 00065 static inline void volk_32fc_s32f_deinterleave_real_16i_a16_generic(int16_t* iBuffer, const lv_32fc_t* complexVector, const float scalar, unsigned int num_points){ 00066 const float* complexVectorPtr = (float*)complexVector; 00067 int16_t* iBufferPtr = iBuffer; 00068 unsigned int number = 0; 00069 for(number = 0; number < num_points; number++){ 00070 *iBufferPtr++ = (int16_t)(*complexVectorPtr++ * scalar); 00071 complexVectorPtr++; 00072 } 00073 00074 } 00075 #endif /* LV_HAVE_GENERIC */ 00076 00077 00078 00079 00080 #endif /* INCLUDED_volk_32fc_s32f_deinterleave_real_16i_a16_H */