From 0adeba66682fb8f5f07f26abe64a9b2d675dc3ba Mon Sep 17 00:00:00 2001 From: Vladslav P Date: Wed, 2 Aug 2023 22:00:59 +0300 Subject: [PATCH] iq_formats: add 14bit real format (no BMI acc) --- src/dsp/format_converter.cpp | 320 +++++++++++++++++++++++++++++++++++ src/dsp/format_converter.h | 52 ++++++ 2 files changed, 372 insertions(+) diff --git a/src/dsp/format_converter.cpp b/src/dsp/format_converter.cpp index 108867366..1e1d9d32a 100644 --- a/src/dsp/format_converter.cpp +++ b/src/dsp/format_converter.cpp @@ -356,6 +356,59 @@ void any_to_any_impl::convert(const std::array *in, gr_complex * out } } +void any_to_any_impl::convert(const std::array *in, gr_complex * out, int noutput_items) +{ + uint8_t * p = (uint8_t *) &(*in)[0]; + while(noutput_items) + { + int i0; + int i1; + i0 = p[0] | ((p[1] & 0x3f) << 8); + i1 = (p[1] >> 6) | (p[2] << 2) | ((p[3] & 0x0f) << 10); + *out=gr_complex(float((i0&(1<<13))?i0-16384:i0)*d_scale_i); + out++; + *out=gr_complex(float((i1&(1<<13))?i1-16384:i1)*d_scale_i); + out++; + i0 = (p[3] >> 4) | (p[4] << 4) | ((p[5] & 0x03) << 12); + i1 = (p[5] >> 2) | (p[6] << 6); + *out=gr_complex(float((i0&(1<<13))?i0-16384:i0)*d_scale_i); + out++; + *out=gr_complex(float((i1&(1<<13))?i1-16384:i1)*d_scale_i); + out++; + p+=7; + noutput_items-=4; + } +} + +void any_to_any_impl::convert(const gr_complex *in, std::array * out, int noutput_items) +{ + uint8_t * p = (uint8_t *) &(*out)[0]; + noutput_items*=8; + while(noutput_items) + { + int i0; + int i1; + i0 = std::round(in->real()*d_scale); + in++; + i1 = std::round(in->real()*d_scale); + in++; + p[0] = i0 & 0xff; + p[1] = ((i0 & 0x3f00) >> 8) | ((i1 & 0x03) << 6); + p[2] = (i1 >> 2) & 0xff; + p[3] = (i1 >> 10) & 0x0f; + i0 = std::round(in->real()*d_scale); + in++; + i1 = std::round(in->real()*d_scale); + in++; + p[3] |= (i0 & 0x0f) << 4; + p[4] = (i0 >> 4) & 0xff; + p[5] = ((i0 >> 12) & 0x03) | ((i1 & 0x3f) << 2); + p[6] = i1 >> 6; + p+=7; + noutput_items--; + } +} + //////////////////////////////// // 32 bit accelerated converters //////////////////////////////// @@ -791,6 +844,123 @@ void any_to_any_impl_32::convert(const std::array *in, gr_complex * } } +void any_to_any_impl_32::convert(const gr_complex *in, std::array * out, int noutput_items) +{ + uint8_t buf[16*2*2]; + uint32_t * p = (uint32_t *) &(*out)[0]; + noutput_items *= 2; + while(noutput_items) + { + volk_32f_s32f_convert_16i((int16_t *)buf, (const float *)in, d_scale, 32); + uint32_t * r = (uint32_t *) buf; + *p = (*r & 0x00003fff); //0>>0 + r++; + *p |= ((*r & 0x00003fff) << 14);//0>>14 + r++; + *p |= ((*r & 0x00003fff) << 28);//0>>28 + p++; + *p = ((*r & 0x00003fff) >> 4);//0>>-4 + r++; + *p |= ((*r & 0x00003fff) << 10);//0>>10 + r++; + *p |= ((*r & 0x00003fff) << 24);//0>>24 + p++; + *p = ((*r & 0x00003fff) >> 8);//0>>-8 + r++; + *p |= ((*r & 0x00003fff) << 6);//0>>6 + r++; + *p |= ((*r & 0x00003fff) << 20);//0>>20 + p++; + *p = ((*r & 0x00003fff) >> 12);//0>>-12 + r++; + *p |= ((*r & 0x00003fff) << 2);//0>>2 + r++; + *p |= ((*r & 0x00003fff) << 16);//0>>16 + r++; + *p |= ((*r & 0x00003fff) << 30);//0>>30 + p++; + *p = ((*r & 0x00003fff) >> 2);//0>>-2 + r++; + *p |= ((*r & 0x00003fff) << 12);//0>>12 + r++; + *p |= ((*r & 0x00003fff) << 26);//0>>26 + p++; + *p = ((*r & 0x00003fff) >> 6);//0>>-6 + r++; + *p |= ((*r & 0x00003fff) << 8);//0>>8 + r++; + *p |= ((*r & 0x00003fff) << 22);//0>>22 + p++; + *p = ((*r & 0x00003fff) >> 10);//0>>-10 + r++; + *p |= ((*r & 0x00003fff) << 4);//0>>4 + r++; + *p |= ((*r & 0x00003fff) << 18);//0>>18 + p++; + + in+=16; + noutput_items--; + } +} + +void any_to_any_impl_32::convert(const std::array *in, gr_complex * out, int noutput_items) +{ + uint8_t buf[16*2*2]; + uint32_t * i = (uint32_t *) &(*in)[0]; + while(noutput_items) + { + uint32_t * o = (uint32_t *) buf; + *o = ((*i & 0x00003fff) << 2);//0>>2 + o++; + *o = ((*i & 0x0fffc000) >> 12);//14>>2 + o++; + *o = ((*i & 0xf0000000) >> 26);//28>>2 + i++; + *o |= ((*i & 0x000003ff) << 6);//10>>2 + o++; + *o = ((*i & 0x00fffc00) >> 8);//10>>2 + o++; + *o = ((*i & 0xff000000) >> 22);//24>>2 + i++; + *o |= ((*i & 0x0000003f) << 10);//6>>2 + o++; + *o = ((*i & 0x000fffc0) >> 4);//6>>2 + o++; + *o = ((*i & 0xfff00000) >> 18);//20>>2 + i++; + *o |= ((*i & 0x00000003) << 14);//2>>2 + o++; + *o = (*i & 0x0000fffc); //2>>2 + o++; + *o = ((*i & 0x3fff0000) >> 14);//16>>2 + o++; + *o = ((*i & 0xc0000000) >> 28);//30>>2 + i++; + *o |= ((*i & 0x00000fff) << 4);//12>>2 + o++; + *o = ((*i & 0x03fff000) >> 10);//12>>2 + o++; + *o = ((*i & 0xfc000000) >> 24);//26>>2 + i++; + *o |= ((*i & 0x000000ff) << 8);//8>>2 + o++; + *o = ((*i & 0x003fff00) >> 6);//8>>2 + o++; + *o = ((*i & 0xffc00000) >> 20);//22>>2 + i++; + *o |= ((*i & 0x0000000f) << 12);//4>>2 + o++; + *o = ((*i & 0x0003fff0) >> 2);//4>>2 + o++; + *o = ((*i & 0xfffc0000) >> 16);//18>>2 + i++; + + volk_16i_s32f_convert_32f((float *)out, (const int16_t*)buf,d_scale,32); + out+=16; + noutput_items-=16; + } +} + //////////////////////////////// // 64 bit accelerated converters //////////////////////////////// @@ -1357,6 +1527,156 @@ void any_to_any_impl_64::convert(const std::array *in, gr_complex * } } +void any_to_any_impl_64::convert(const gr_complex *in, std::array * out, int noutput_items) +{ + uint8_t buf[32*2*2]; + uint64_t * p = (uint64_t *) &(*out)[0]; + while(noutput_items) + { + volk_32f_s32f_convert_16i((int16_t *)buf, (const float *)in, d_scale, 64); + uint64_t * r = (uint64_t *) buf; + *p = (*r & 0x0000000000003fff); //0>>0 + *p |= ((*r & 0x00003fff00000000) >> 18);//32>>14 + r++; + *p |= ((*r & 0x0000000000003fff) << 28);//0>>28 + *p |= ((*r & 0x00003fff00000000) << 10);//32>>42 + r++; + *p |= ((*r & 0x0000000000003fff) << 56);//0>>56 + p++; + *p = ((*r & 0x0000000000003fff) >> 8);//0>>-8 + *p |= ((*r & 0x00003fff00000000) >> 26);//32>>6 + r++; + *p |= ((*r & 0x0000000000003fff) << 20);//0>>20 + *p |= ((*r & 0x00003fff00000000) << 2);//32>>34 + r++; + *p |= ((*r & 0x0000000000003fff) << 48);//0>>48 + *p |= ((*r & 0x00003fff00000000) << 30);//32>>62 + p++; + *p = ((*r & 0x00003fff00000000) >> 34);//32>>-2 + r++; + *p |= ((*r & 0x0000000000003fff) << 12);//0>>12 + *p |= ((*r & 0x00003fff00000000) >> 6);//32>>26 + r++; + *p |= ((*r & 0x0000000000003fff) << 40);//0>>40 + *p |= ((*r & 0x00003fff00000000) << 22);//32>>54 + p++; + *p = ((*r & 0x00003fff00000000) >> 42);//32>>-10 + r++; + *p |= ((*r & 0x0000000000003fff) << 4);//0>>4 + *p |= ((*r & 0x00003fff00000000) >> 14);//32>>18 + r++; + *p |= ((*r & 0x0000000000003fff) << 32);//0>>32 + *p |= ((*r & 0x00003fff00000000) << 14);//32>>46 + r++; + *p |= ((*r & 0x0000000000003fff) << 60);//0>>60 + p++; + *p = ((*r & 0x0000000000003fff) >> 4);//0>>-4 + *p |= ((*r & 0x00003fff00000000) >> 22);//32>>10 + r++; + *p |= ((*r & 0x0000000000003fff) << 24);//0>>24 + *p |= ((*r & 0x00003fff00000000) << 6);//32>>38 + r++; + *p |= ((*r & 0x0000000000003fff) << 52);//0>>52 + p++; + *p = ((*r & 0x0000000000003fff) >> 12);//0>>-12 + *p |= ((*r & 0x00003fff00000000) >> 30);//32>>2 + r++; + *p |= ((*r & 0x0000000000003fff) << 16);//0>>16 + *p |= ((*r & 0x00003fff00000000) >> 2);//32>>30 + r++; + *p |= ((*r & 0x0000000000003fff) << 44);//0>>44 + *p |= ((*r & 0x00003fff00000000) << 26);//32>>58 + p++; + *p = ((*r & 0x00003fff00000000) >> 38);//32>>-6 + r++; + *p |= ((*r & 0x0000000000003fff) << 8);//0>>8 + *p |= ((*r & 0x00003fff00000000) >> 10);//32>>22 + r++; + *p |= ((*r & 0x0000000000003fff) << 36);//0>>36 + *p |= ((*r & 0x00003fff00000000) << 18);//32>>50 + p++; + + in+=32; + noutput_items--; + } +} + +void any_to_any_impl_64::convert(const std::array *in, gr_complex * out, int noutput_items) +{ + uint8_t buf[32*2*2]; + noutput_items&=-2; + while(noutput_items) + { + uint64_t * i = (uint64_t *) &(*in)[0]; + uint64_t * o = (uint64_t *) buf; + *o = ((*i & 0x0000000000003fff) << 2);//0>>2 + *o |= ((*i & 0x000000000fffc000) << 20);//14>>34 + o++; + *o = ((*i & 0x000003fff0000000) >> 26);//28>>2 + *o |= ((*i & 0x00fffc0000000000) >> 8);//42>>34 + o++; + *o = ((*i & 0xff00000000000000) >> 54);//56>>2 + i++; + *o |= ((*i & 0x000000000000003f) << 10);//6>>2 + *o |= ((*i & 0x00000000000fffc0) << 28);//6>>34 + o++; + *o = ((*i & 0x00000003fff00000) >> 18);//20>>2 + *o |= (*i & 0x0000fffc00000000); //34>>34 + o++; + *o = ((*i & 0x3fff000000000000) >> 46);//48>>2 + *o |= ((*i & 0xc000000000000000) >> 28);//62>>34 + i++; + *o |= ((*i & 0x0000000000000fff) << 36);//12>>34 + o++; + *o = ((*i & 0x0000000003fff000) >> 10);//12>>2 + *o |= ((*i & 0x000000fffc000000) << 8);//26>>34 + o++; + *o = ((*i & 0x003fff0000000000) >> 38);//40>>2 + *o |= ((*i & 0xffc0000000000000) >> 20);//54>>34 + i++; + *o |= ((*i & 0x000000000000000f) << 44);//4>>34 + o++; + *o = ((*i & 0x000000000003fff0) >> 2);//4>>2 + *o |= ((*i & 0x00000000fffc0000) << 16);//18>>34 + o++; + *o = ((*i & 0x00003fff00000000) >> 30);//32>>2 + *o |= ((*i & 0x0fffc00000000000) >> 12);//46>>34 + o++; + *o = ((*i & 0xf000000000000000) >> 58);//60>>2 + i++; + *o |= ((*i & 0x00000000000003ff) << 6);//10>>2 + *o |= ((*i & 0x0000000000fffc00) << 24);//10>>34 + o++; + *o = ((*i & 0x0000003fff000000) >> 22);//24>>2 + *o |= ((*i & 0x000fffc000000000) >> 4);//38>>34 + o++; + *o = ((*i & 0xfff0000000000000) >> 50);//52>>2 + i++; + *o |= ((*i & 0x0000000000000003) << 14);//2>>2 + *o |= ((*i & 0x000000000000fffc) << 32);//2>>34 + o++; + *o = ((*i & 0x000000003fff0000) >> 14);//16>>2 + *o |= ((*i & 0x00000fffc0000000) << 4);//30>>34 + o++; + *o = ((*i & 0x03fff00000000000) >> 42);//44>>2 + *o |= ((*i & 0xfc00000000000000) >> 24);//58>>34 + i++; + *o |= ((*i & 0x00000000000000ff) << 40);//8>>34 + o++; + *o = ((*i & 0x00000000003fff00) >> 6);//8>>2 + *o |= ((*i & 0x0000000fffc00000) << 12);//22>>34 + o++; + *o = ((*i & 0x0003fff000000000) >> 34);//36>>2 + *o |= ((*i & 0xfffc000000000000) >> 16);//50>>34 + i++; + + volk_16i_s32f_convert_32f((float *)out, (const int16_t*)buf,d_scale,64); + out+=32; + in++; + noutput_items-=32; + } +} + #ifdef __BMI2__ ///////////////////////////////////// // 64 bit bmi2 accelerated converters diff --git a/src/dsp/format_converter.h b/src/dsp/format_converter.h index 982041f83..0c29be12a 100644 --- a/src/dsp/format_converter.h +++ b/src/dsp/format_converter.h @@ -59,6 +59,7 @@ enum file_formats { FILE_FORMAT_S16L, FILE_FORMAT_S10L, FILE_FORMAT_S12L, + FILE_FORMAT_S14L, FILE_FORMAT_COUNT, }; @@ -97,6 +98,7 @@ class any_to_any_base: virtual public gr::sync_block {2,1,"16i","short 16i"}, {5*8,4*8,"10i","10 bit i"}, {3*8,2*8,"12i","12 bit i"}, + {7*8,4*8,"14i","14 bit i"}, }; void set_decimation(unsigned decimation) @@ -196,6 +198,8 @@ class any_to_any_impl : virtual public gr::sync_block, virtual public any_to_any void convert(const std::array *in, gr_complex * out, int noutput_items); void convert(const gr_complex *in, std::array * out, int noutput_items); void convert(const std::array *in, gr_complex * out, int noutput_items); + void convert(const gr_complex *in, std::array * out, int noutput_items); + void convert(const std::array *in, gr_complex * out, int noutput_items); }; /*! @@ -513,6 +517,48 @@ using any_to_any_base::sptr; } } + static sptr make(dispatcher::tag>>) + { + if(is_le()) + { + if(UINTPTR_MAX == 0xffffffffffffffff) + { +#if 0 + #ifdef __BMI2__ + if( __builtin_cpu_supports("bmi2")) + return gnuradio::get_initial_sptr(new any_to_any_bmi64(-float(INT16_MIN>>4),16,1,"f32s12")); + #endif +#endif + return gnuradio::get_initial_sptr(new any_to_any_64(-float(INT16_MIN>>2),16,1,"f32s14")); + }else{ + return gnuradio::get_initial_sptr(new any_to_any_32(-float(INT16_MIN>>2),16,1,"f32s14")); + } + }else{ + return gnuradio::get_initial_sptr(new any_to_any(-float(INT16_MIN>>2),16,1,"f32s14")); + } + } + + static sptr make(dispatcher::tag, gr_complex>>) + { + if(is_le()) + { + if(UINTPTR_MAX == 0xffffffffffffffff) + { +#if 0 + #ifdef __BMI2__ + if( __builtin_cpu_supports("bmi2")) + return gnuradio::get_initial_sptr(new any_to_any_bmi64(-float(INT16_MIN),1,16,"s12f32")); + #endif +#endif + return gnuradio::get_initial_sptr(new any_to_any_64(-float(INT16_MIN),1,16,"s14f32")); + }else{ + return gnuradio::get_initial_sptr(new any_to_any_32(-float(INT16_MIN),1,16,"s14f32")); + } + }else{ + return gnuradio::get_initial_sptr(new any_to_any(-float(INT16_MIN>>2),1,16,"s14f32")); + } + } + any_to_any(const double scale, unsigned decimation, unsigned interpolation, const std::string bname):sync_block(bname, gr::io_signature::make (1, 1, sizeof(T_IN)), gr::io_signature::make (1, 1, sizeof(T_OUT))) @@ -573,6 +619,8 @@ class any_to_any_impl_32 : virtual public gr::sync_block, virtual public any_to_ void convert(const std::array *in, gr_complex * out, int noutput_items); void convert(const gr_complex *in, std::array * out, int noutput_items); void convert(const std::array *in, gr_complex * out, int noutput_items); + void convert(const gr_complex *in, std::array * out, int noutput_items); + void convert(const std::array *in, gr_complex * out, int noutput_items); }; template class BLOCKS_API any_to_any_32 : virtual public gr::sync_block, virtual public any_to_any_base, virtual private any_to_any_impl_32 @@ -639,6 +687,8 @@ class any_to_any_impl_64 : virtual public gr::sync_block, virtual public any_to_ void convert(const std::array *in, gr_complex * out, int noutput_items); void convert(const gr_complex *in, std::array * out, int noutput_items); void convert(const std::array *in, gr_complex * out, int noutput_items); + void convert(const gr_complex *in, std::array * out, int noutput_items); + void convert(const std::array *in, gr_complex * out, int noutput_items); }; template class BLOCKS_API any_to_any_64 : virtual public gr::sync_block, virtual public any_to_any_base, virtual private any_to_any_impl_64 @@ -705,6 +755,8 @@ class any_to_any_impl_bmi64 : virtual public gr::sync_block, virtual public any_ void convert(const std::array *in, gr_complex * out, int noutput_items); void convert(const gr_complex *in, std::array * out, int noutput_items); void convert(const std::array *in, gr_complex * out, int noutput_items); + void convert(const gr_complex *in, std::array * out, int noutput_items); + void convert(const std::array *in, gr_complex * out, int noutput_items); }; template class BLOCKS_API any_to_any_bmi64 : virtual public gr::sync_block, virtual public any_to_any_base, virtual private any_to_any_impl_bmi64