GNU Radio 3.4.0 C++ API
volk_32f_s32f_convert_8i_a16.h
Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_32f_s32f_convert_8i_a16_H
00002 #define INCLUDED_volk_32f_s32f_convert_8i_a16_H
00003 
00004 #include <inttypes.h>
00005 #include <stdio.h>
00006 
00007 #if LV_HAVE_SSE2
00008 #include <emmintrin.h>
00009   /*!
00010     \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value
00011     \param inputVector The floating point input data buffer
00012     \param outputVector The 8 bit output data buffer
00013     \param scalar The value multiplied against each point in the input buffer
00014     \param num_points The number of data values to be converted
00015   */
00016 static inline void volk_32f_s32f_convert_8i_a16_sse2(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
00017   unsigned int number = 0;
00018 
00019   const unsigned int sixteenthPoints = num_points / 16;
00020     
00021   const float* inputVectorPtr = (const float*)inputVector;
00022   int8_t* outputVectorPtr = outputVector;
00023   __m128 vScalar = _mm_set_ps1(scalar);
00024   __m128 inputVal1, inputVal2, inputVal3, inputVal4;
00025   __m128i intInputVal1, intInputVal2, intInputVal3, intInputVal4;
00026 
00027   for(;number < sixteenthPoints; number++){
00028     inputVal1 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
00029     inputVal2 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
00030     inputVal3 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
00031     inputVal4 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4;
00032 
00033     intInputVal1 = _mm_cvtps_epi32(_mm_mul_ps(inputVal1, vScalar));
00034     intInputVal2 = _mm_cvtps_epi32(_mm_mul_ps(inputVal2, vScalar));
00035     intInputVal3 = _mm_cvtps_epi32(_mm_mul_ps(inputVal3, vScalar));
00036     intInputVal4 = _mm_cvtps_epi32(_mm_mul_ps(inputVal4, vScalar));
00037     
00038     intInputVal1 = _mm_packs_epi32(intInputVal1, intInputVal2);
00039     intInputVal3 = _mm_packs_epi32(intInputVal3, intInputVal4);
00040 
00041     intInputVal1 = _mm_packs_epi16(intInputVal1, intInputVal3);
00042 
00043     _mm_store_si128((__m128i*)outputVectorPtr, intInputVal1);
00044     outputVectorPtr += 16;
00045   }
00046 
00047   number = sixteenthPoints * 16;    
00048   for(; number < num_points; number++){
00049     outputVector[number] = (int8_t)(inputVector[number] * scalar);
00050   }
00051 }
00052 #endif /* LV_HAVE_SSE2 */
00053 
00054 #if LV_HAVE_SSE
00055 #include <xmmintrin.h>
00056   /*!
00057     \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value
00058     \param inputVector The floating point input data buffer
00059     \param outputVector The 8 bit output data buffer
00060     \param scalar The value multiplied against each point in the input buffer
00061     \param num_points The number of data values to be converted
00062   */
00063 static inline void volk_32f_s32f_convert_8i_a16_sse(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
00064   unsigned int number = 0;
00065 
00066   const unsigned int quarterPoints = num_points / 4;
00067     
00068   const float* inputVectorPtr = (const float*)inputVector;
00069   int8_t* outputVectorPtr = outputVector;
00070   __m128 vScalar = _mm_set_ps1(scalar);
00071   __m128 ret;
00072 
00073   float outputFloatBuffer[4] __attribute__((aligned(128)));
00074 
00075   for(;number < quarterPoints; number++){
00076     ret = _mm_load_ps(inputVectorPtr);
00077     inputVectorPtr += 4;
00078 
00079     ret = _mm_mul_ps(ret, vScalar);
00080 
00081     _mm_store_ps(outputFloatBuffer, ret);
00082     *outputVectorPtr++ = (int8_t)(outputFloatBuffer[0]);
00083     *outputVectorPtr++ = (int8_t)(outputFloatBuffer[1]);
00084     *outputVectorPtr++ = (int8_t)(outputFloatBuffer[2]);
00085     *outputVectorPtr++ = (int8_t)(outputFloatBuffer[3]);
00086   }
00087 
00088   number = quarterPoints * 4;    
00089   for(; number < num_points; number++){
00090     outputVector[number] = (int8_t)(inputVector[number] * scalar);
00091   }
00092 }
00093 #endif /* LV_HAVE_SSE */
00094 
00095 #ifdef LV_HAVE_GENERIC
00096   /*!
00097     \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value
00098     \param inputVector The floating point input data buffer
00099     \param outputVector The 8 bit output data buffer
00100     \param scalar The value multiplied against each point in the input buffer
00101     \param num_points The number of data values to be converted
00102   */
00103 static inline void volk_32f_s32f_convert_8i_a16_generic(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){
00104   int8_t* outputVectorPtr = outputVector;
00105   const float* inputVectorPtr = inputVector;
00106   unsigned int number = 0;
00107 
00108   for(number = 0; number < num_points; number++){
00109     *outputVectorPtr++ = (int8_t)(*inputVectorPtr++  * scalar);
00110   }
00111 }
00112 #endif /* LV_HAVE_GENERIC */
00113 
00114 
00115 
00116 
00117 #endif /* INCLUDED_volk_32f_s32f_convert_8i_a16_H */