Skip to content

Commit

Permalink
iq_formats: add 12bit real format (no BMI acc)
Browse files Browse the repository at this point in the history
  • Loading branch information
vladisslav2011 committed Aug 14, 2023
1 parent 458a6b7 commit ed98f01
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/applications/gqrx/receiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ class receiver
any_to_any<gr_complex,int8_t>::make(),
any_to_any<gr_complex,int16_t>::make(),
any_to_any<gr_complex,std::array<int16_t,20>>::make(),
any_to_any<gr_complex,std::array<int16_t,12>>::make(),
};
std::vector<any_to_any_base::sptr> convert_from
{
Expand All @@ -323,6 +324,7 @@ class receiver
any_to_any<int8_t,gr_complex>::make(),
any_to_any<int16_t,gr_complex>::make(),
any_to_any<std::array<int16_t,20>,gr_complex>::make(),
any_to_any<std::array<int16_t,12>,gr_complex>::make(),
};

gr::blocks::throttle::sptr input_throttle;
Expand Down
193 changes: 193 additions & 0 deletions src/dsp/format_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,44 @@ void any_to_any_impl::convert(const std::array<int16_t,20> *in, gr_complex * out
}
}

void any_to_any_impl::convert(const gr_complex *in, std::array<int16_t,12> * 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 & 0x0f00) >> 8 | (i1 & 0x0f)<<4;
p[2] = i1 >> 4;
p+=3;
noutput_items--;
}
}

void any_to_any_impl::convert(const std::array<int16_t,12> *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] & 0x0f) << 8;
i1 = p[1] >> 4 | p[2] << 4;
*out=gr_complex(float((i0&(1<<11))?i0-4096:i0)*d_scale_i);
out++;
*out=gr_complex(float((i1&(1<<11))?i1-4096:i1)*d_scale_i);
out++;
p+=3;
noutput_items--;
}
}

////////////////////////////////
// 32 bit accelerated converters
////////////////////////////////
Expand Down Expand Up @@ -684,6 +722,75 @@ void any_to_any_impl_32::convert(const std::array<int16_t,20> *in, gr_complex *
}
}

void any_to_any_impl_32::convert(const gr_complex *in, std::array<int16_t,12> * out, int noutput_items)
{
uint8_t buf[8*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, 16);
uint32_t * r = (uint32_t *) buf;
*p = (*r & 0x00000fff); //0>>0
r++;
*p |= ((*r & 0x00000fff) << 12);//0>>12
r++;
*p |= ((*r & 0x00000fff) << 24);//0>>24
p++;
*p = ((*r & 0x00000fff) >> 8);//0>>-8
r++;
*p |= ((*r & 0x00000fff) << 4);//0>>4
r++;
*p |= ((*r & 0x00000fff) << 16);//0>>16
r++;
*p |= ((*r & 0x00000fff) << 28);//0>>28
p++;
*p = ((*r & 0x00000fff) >> 4);//0>>-4
r++;
*p |= ((*r & 0x00000fff) << 8);//0>>8
r++;
*p |= ((*r & 0x00000fff) << 20);//0>>20
p++;

in+=4;
noutput_items--;
}
}

void any_to_any_impl_32::convert(const std::array<int16_t,12> *in, gr_complex * out, int noutput_items)
{
uint8_t buf[8*2*2];
uint32_t * i = (uint32_t *) &(*in)[0];
while(noutput_items)
{
uint32_t * o = (uint32_t *) buf;
*o = ((*i & 0x00000fff) << 4);//0>>4
o++;
*o = ((*i & 0x00fff000) >> 8);//12>>4
o++;
*o = ((*i & 0xff000000) >> 20);//24>>4
i++;
*o |= ((*i & 0x0000000f) << 12);//4>>4
o++;
*o = (*i & 0x0000fff0); //4>>4
o++;
*o = ((*i & 0x0fff0000) >> 12);//16>>4
o++;
*o = ((*i & 0xf0000000) >> 24);//28>>4
i++;
*o |= ((*i & 0x000000ff) << 8);//8>>4
o++;
*o = ((*i & 0x000fff00) >> 4);//8>>4
o++;
*o = ((*i & 0xfff00000) >> 16);//20>>4
i++;

volk_16i_s32f_convert_32f((float *)out, (const int16_t*)buf,d_scale,16);
out+=8;
noutput_items-=8;
}
}

////////////////////////////////
// 64 bit accelerated converters
////////////////////////////////
Expand Down Expand Up @@ -1164,6 +1271,92 @@ void any_to_any_impl_64::convert(const std::array<int16_t,20> *in, gr_complex *
}
}

void any_to_any_impl_64::convert(const gr_complex *in, std::array<int16_t,12> * out, int noutput_items)
{
uint8_t buf[16*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, 32);
uint64_t * r = (uint64_t *) buf;
*p = (*r & 0x0000000000000fff); //0>>0
*p |= ((*r & 0x00000fff00000000) >> 20);//32>>12
r++;
*p |= ((*r & 0x0000000000000fff) << 24);//0>>24
*p |= ((*r & 0x00000fff00000000) << 4);//32>>36
r++;
*p |= ((*r & 0x0000000000000fff) << 48);//0>>48
*p |= ((*r & 0x00000fff00000000) << 28);//32>>60
p++;
*p = ((*r & 0x00000fff00000000) >> 36);//32>>-4
r++;
*p |= ((*r & 0x0000000000000fff) << 8);//0>>8
*p |= ((*r & 0x00000fff00000000) >> 12);//32>>20
r++;
*p |= ((*r & 0x0000000000000fff) << 32);//0>>32
*p |= ((*r & 0x00000fff00000000) << 12);//32>>44
r++;
*p |= ((*r & 0x0000000000000fff) << 56);//0>>56
p++;
*p = ((*r & 0x0000000000000fff) >> 8);//0>>-8
*p |= ((*r & 0x00000fff00000000) >> 28);//32>>4
r++;
*p |= ((*r & 0x0000000000000fff) << 16);//0>>16
*p |= ((*r & 0x00000fff00000000) >> 4);//32>>28
r++;
*p |= ((*r & 0x0000000000000fff) << 40);//0>>40
*p |= ((*r & 0x00000fff00000000) << 20);//32>>52
p++;

in+=16;
noutput_items--;
}
}

void any_to_any_impl_64::convert(const std::array<int16_t,12> *in, gr_complex * out, int noutput_items)
{
uint8_t buf[16*2*2];
noutput_items&=-2;
while(noutput_items)
{
uint64_t * i = (uint64_t *) &(*in)[0];
uint64_t * o = (uint64_t *) buf;
*o = ((*i & 0x0000000000000fff) << 4);//0>>4
*o |= ((*i & 0x0000000000fff000) << 24);//12>>36
o++;
*o = ((*i & 0x0000000fff000000) >> 20);//24>>4
*o |= (*i & 0x0000fff000000000); //36>>36
o++;
*o = ((*i & 0x0fff000000000000) >> 44);//48>>4
*o |= ((*i & 0xf000000000000000) >> 24);//60>>36
i++;
*o |= ((*i & 0x00000000000000ff) << 40);//8>>36
o++;
*o = ((*i & 0x00000000000fff00) >> 4);//8>>4
*o |= ((*i & 0x00000000fff00000) << 16);//20>>36
o++;
*o = ((*i & 0x00000fff00000000) >> 28);//32>>4
*o |= ((*i & 0x00fff00000000000) >> 8);//44>>36
o++;
*o = ((*i & 0xff00000000000000) >> 52);//56>>4
i++;
*o |= ((*i & 0x000000000000000f) << 12);//4>>4
*o |= ((*i & 0x000000000000fff0) << 32);//4>>36
o++;
*o = ((*i & 0x000000000fff0000) >> 12);//16>>4
*o |= ((*i & 0x000000fff0000000) << 8);//28>>36
o++;
*o = ((*i & 0x000fff0000000000) >> 36);//40>>4
*o |= ((*i & 0xfff0000000000000) >> 16);//52>>36
i++;

volk_16i_s32f_convert_32f((float *)out, (const int16_t*)buf,d_scale,32);
out+=16;
in++;
noutput_items-=16;
}
}

#ifdef __BMI2__
/////////////////////////////////////
// 64 bit bmi2 accelerated converters
Expand Down
52 changes: 52 additions & 0 deletions src/dsp/format_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ enum file_formats {
FILE_FORMAT_S8,
FILE_FORMAT_S16L,
FILE_FORMAT_S10L,
FILE_FORMAT_S12L,
FILE_FORMAT_COUNT,
};

Expand Down Expand Up @@ -95,6 +96,7 @@ class any_to_any_base: virtual public gr::sync_block
{1,1,"8i","char 8i"},
{2,1,"16i","short 16i"},
{5*8,4*8,"10i","10 bit i"},
{3*8,2*8,"12i","12 bit i"},
};

void set_decimation(unsigned decimation)
Expand Down Expand Up @@ -192,6 +194,8 @@ class any_to_any_impl : virtual public gr::sync_block, virtual public any_to_any
void convert(const int16_t *in, gr_complex * out, int noutput_items);
void convert(const gr_complex *in, std::array<int16_t,20> * out, int noutput_items);
void convert(const std::array<int16_t,20> *in, gr_complex * out, int noutput_items);
void convert(const gr_complex *in, std::array<int16_t,12> * out, int noutput_items);
void convert(const std::array<int16_t,12> *in, gr_complex * out, int noutput_items);
};

/*!
Expand Down Expand Up @@ -467,6 +471,48 @@ using any_to_any_base::sptr;
}
}

static sptr make(dispatcher::tag<any_to_any<gr_complex, std::array<int16_t,12>>>)
{
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<T_IN, T_OUT>(-float(INT16_MIN>>4),16,1,"f32s12"));
#endif
#endif
return gnuradio::get_initial_sptr(new any_to_any_64<T_IN, T_OUT>(-float(INT16_MIN>>4),16,1,"f32s12"));
}else{
return gnuradio::get_initial_sptr(new any_to_any_32<T_IN, T_OUT>(-float(INT16_MIN>>4),16,1,"f32s12"));
}
}else{
return gnuradio::get_initial_sptr(new any_to_any<T_IN, T_OUT>(-float(INT16_MIN>>4),16,1,"f32s12"));
}
}

static sptr make(dispatcher::tag<any_to_any<std::array<int16_t,12>, 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<T_IN, T_OUT>(-float(INT16_MIN),1,16,"s12f32"));
#endif
#endif
return gnuradio::get_initial_sptr(new any_to_any_64<T_IN, T_OUT>(-float(INT16_MIN),1,16,"s12f32"));
}else{
return gnuradio::get_initial_sptr(new any_to_any_32<T_IN, T_OUT>(-float(INT16_MIN),1,16,"s12f32"));
}
}else{
return gnuradio::get_initial_sptr(new any_to_any<T_IN, T_OUT>(-float(INT16_MIN>>4),1,16,"s12f32"));
}
}

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)))
Expand Down Expand Up @@ -525,6 +571,8 @@ class any_to_any_impl_32 : virtual public gr::sync_block, virtual public any_to_
void convert(const std::array<int8_t,56> *in, gr_complex * out, int noutput_items);
void convert(const gr_complex *in, std::array<int16_t,20> * out, int noutput_items);
void convert(const std::array<int16_t,20> *in, gr_complex * out, int noutput_items);
void convert(const gr_complex *in, std::array<int16_t,12> * out, int noutput_items);
void convert(const std::array<int16_t,12> *in, gr_complex * out, int noutput_items);
};

template <typename T_IN, typename T_OUT> 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
Expand Down Expand Up @@ -589,6 +637,8 @@ class any_to_any_impl_64 : virtual public gr::sync_block, virtual public any_to_
void convert(const std::array<int8_t,56> *in, gr_complex * out, int noutput_items);
void convert(const gr_complex *in, std::array<int16_t,20> * out, int noutput_items);
void convert(const std::array<int16_t,20> *in, gr_complex * out, int noutput_items);
void convert(const gr_complex *in, std::array<int16_t,12> * out, int noutput_items);
void convert(const std::array<int16_t,12> *in, gr_complex * out, int noutput_items);
};

template <typename T_IN, typename T_OUT> 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
Expand Down Expand Up @@ -653,6 +703,8 @@ class any_to_any_impl_bmi64 : virtual public gr::sync_block, virtual public any_
void convert(const std::array<int8_t,56> *in, gr_complex * out, int noutput_items);
void convert(const gr_complex *in, std::array<int16_t,20> * out, int noutput_items);
void convert(const std::array<int16_t,20> *in, gr_complex * out, int noutput_items);
void convert(const gr_complex *in, std::array<int16_t,12> * out, int noutput_items);
void convert(const std::array<int16_t,12> *in, gr_complex * out, int noutput_items);
};

template <typename T_IN, typename T_OUT> 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
Expand Down

0 comments on commit ed98f01

Please sign in to comment.