diff options
author | Josh Blum <josh@joshknows.com> | 2011-05-23 13:37:05 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-06-14 17:27:46 -0700 |
commit | 86f12cd1c1c606bbfbc6f0ddbd98166fe9251a13 (patch) | |
tree | 94cb1723707957dc0ff7288220ff24c6ca6bbb9e | |
parent | fb85b0c9eb5a50a16e7568140d144650794774de (diff) | |
download | uhd-86f12cd1c1c606bbfbc6f0ddbd98166fe9251a13.tar.gz uhd-86f12cd1c1c606bbfbc6f0ddbd98166fe9251a13.tar.bz2 uhd-86f12cd1c1c606bbfbc6f0ddbd98166fe9251a13.zip |
uhd: added scaling factor to conversion routines
-rw-r--r-- | host/include/uhd/convert.hpp | 2 | ||||
-rw-r--r-- | host/lib/convert/convert_common.hpp | 40 | ||||
-rw-r--r-- | host/lib/convert/convert_with_neon.cpp | 8 | ||||
-rw-r--r-- | host/lib/convert/convert_with_sse2.cpp | 16 | ||||
-rw-r--r-- | host/lib/convert/gen_convert_general.py | 8 | ||||
-rw-r--r-- | host/lib/transport/vrt_packet_handler.hpp | 4 | ||||
-rw-r--r-- | host/tests/convert_test.cpp | 12 |
7 files changed, 41 insertions, 49 deletions
diff --git a/host/include/uhd/convert.hpp b/host/include/uhd/convert.hpp index 8fc2f38db..99f1860ae 100644 --- a/host/include/uhd/convert.hpp +++ b/host/include/uhd/convert.hpp @@ -29,7 +29,7 @@ namespace uhd{ namespace convert{ typedef uhd::ref_vector<void *> output_type; typedef uhd::ref_vector<const void *> input_type; - typedef boost::function<void(const input_type&, const output_type&, size_t)> function_type; + typedef boost::function<void(const input_type&, const output_type&, size_t, double)> function_type; /*! * Describe the priority of a converter function. diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp index c2ca233d9..7f513b124 100644 --- a/host/lib/convert/convert_common.hpp +++ b/host/lib/convert/convert_common.hpp @@ -27,7 +27,7 @@ static void fcn( \ const uhd::convert::input_type &inputs, \ const uhd::convert::output_type &outputs, \ - size_t nsamps \ + size_t nsamps, double scale_factor \ ); \ UHD_STATIC_BLOCK(register_##fcn##_##prio){ \ uhd::convert::register_converter(#fcn, fcn, prio); \ @@ -35,7 +35,7 @@ static void fcn( \ const uhd::convert::input_type &inputs, \ const uhd::convert::output_type &outputs, \ - size_t nsamps \ + size_t nsamps, double scale_factor \ ) /*********************************************************************** @@ -50,7 +50,7 @@ typedef boost::uint32_t item32_t; /*********************************************************************** * Convert complex short buffer to items32 **********************************************************************/ -static UHD_INLINE item32_t sc16_to_item32(sc16_t num){ +static UHD_INLINE item32_t sc16_to_item32(sc16_t num, double){ boost::uint16_t real = num.real(); boost::uint16_t imag = num.imag(); return (item32_t(real) << 16) | (item32_t(imag) << 0); @@ -59,7 +59,7 @@ static UHD_INLINE item32_t sc16_to_item32(sc16_t num){ /*********************************************************************** * Convert items32 buffer to complex short **********************************************************************/ -static UHD_INLINE sc16_t item32_to_sc16(item32_t item){ +static UHD_INLINE sc16_t item32_to_sc16(item32_t item, double){ return sc16_t( boost::int16_t(item >> 16), boost::int16_t(item >> 0) @@ -69,46 +69,38 @@ static UHD_INLINE sc16_t item32_to_sc16(item32_t item){ /*********************************************************************** * Convert complex float buffer to items32 (no swap) **********************************************************************/ -static const float shorts_per_float = float(32767); - -static UHD_INLINE item32_t fc32_to_item32(fc32_t num){ - boost::uint16_t real = boost::int16_t(num.real()*shorts_per_float); - boost::uint16_t imag = boost::int16_t(num.imag()*shorts_per_float); +static UHD_INLINE item32_t fc32_to_item32(fc32_t num, float scale_factor){ + boost::uint16_t real = boost::int16_t(num.real()*scale_factor); + boost::uint16_t imag = boost::int16_t(num.imag()*scale_factor); return (item32_t(real) << 16) | (item32_t(imag) << 0); } /*********************************************************************** * Convert items32 buffer to complex float **********************************************************************/ -static const float floats_per_short = float(1.0/shorts_per_float); - -static UHD_INLINE fc32_t item32_to_fc32(item32_t item){ +static UHD_INLINE fc32_t item32_to_fc32(item32_t item, float scale_factor){ return fc32_t( - float(boost::int16_t(item >> 16)*floats_per_short), - float(boost::int16_t(item >> 0)*floats_per_short) + float(boost::int16_t(item >> 16)*scale_factor), + float(boost::int16_t(item >> 0)*scale_factor) ); } /*********************************************************************** * Convert complex double buffer to items32 (no swap) **********************************************************************/ -static const double shorts_per_double = double(32767); - -static UHD_INLINE item32_t fc64_to_item32(fc64_t num){ - boost::uint16_t real = boost::int16_t(num.real()*shorts_per_double); - boost::uint16_t imag = boost::int16_t(num.imag()*shorts_per_double); +static UHD_INLINE item32_t fc64_to_item32(fc64_t num, double scale_factor){ + boost::uint16_t real = boost::int16_t(num.real()*scale_factor); + boost::uint16_t imag = boost::int16_t(num.imag()*scale_factor); return (item32_t(real) << 16) | (item32_t(imag) << 0); } /*********************************************************************** * Convert items32 buffer to complex double **********************************************************************/ -static const double doubles_per_short = double(1.0/shorts_per_double); - -static UHD_INLINE fc64_t item32_to_fc64(item32_t item){ +static UHD_INLINE fc64_t item32_to_fc64(item32_t item, double scale_factor){ return fc64_t( - float(boost::int16_t(item >> 16)*doubles_per_short), - float(boost::int16_t(item >> 0)*doubles_per_short) + float(boost::int16_t(item >> 16)*scale_factor), + float(boost::int16_t(item >> 0)*scale_factor) ); } diff --git a/host/lib/convert/convert_with_neon.cpp b/host/lib/convert/convert_with_neon.cpp index 3d677db5b..e5f08cad9 100644 --- a/host/lib/convert/convert_with_neon.cpp +++ b/host/lib/convert/convert_with_neon.cpp @@ -26,7 +26,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){ size_t i; - float32x4_t Q0 = vdupq_n_f32(shorts_per_float); + float32x4_t Q0 = vdupq_n_f32(float(scale_factor)); for (i=0; i < (nsamps & ~0x03); i+=2) { float32x4_t Q1 = vld1q_f32(reinterpret_cast<const float *>(&input[i])); float32x4_t Q2 = vmulq_f32(Q1, Q0); @@ -37,7 +37,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){ } for (; i < nsamps; i++) - output[i] = fc32_to_item32(input[i]); + output[i] = fc32_to_item32(input[i], float(scale_factor)); } DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){ @@ -46,7 +46,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){ size_t i; - float32x4_t Q1 = vdupq_n_f32(floats_per_short); + float32x4_t Q1 = vdupq_n_f32(float(scale_factor)); for (i=0; i < (nsamps & ~0x03); i+=2) { int16x4_t D0 = vld1_s16(reinterpret_cast<const int16_t *>(&input[i])); int16x4_t D1 = vrev32_s16(D0); @@ -57,5 +57,5 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){ } for (; i < nsamps; i++) - output[i] = item32_to_fc32(input[i]); + output[i] = item32_to_fc32(input[i], float(scale_factor)); } diff --git a/host/lib/convert/convert_with_sse2.cpp b/host/lib/convert/convert_with_sse2.cpp index 96ee9134c..52beea24a 100644 --- a/host/lib/convert/convert_with_sse2.cpp +++ b/host/lib/convert/convert_with_sse2.cpp @@ -25,7 +25,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){ const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]); item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); - __m128 scalar = _mm_set_ps1(shorts_per_float); + __m128 scalar = _mm_set_ps1(float(scale_factor)); //convert blocks of samples with intrinsics size_t i = 0; for (; i < (nsamps & ~0x3); i+=4){ @@ -48,7 +48,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = fc32_to_item32(input[i]); + output[i] = fc32_to_item32(input[i], float(scale_factor)); } } @@ -56,7 +56,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){ const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]); item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); - __m128 scalar = _mm_set_ps1(shorts_per_float); + __m128 scalar = _mm_set_ps1(float(scale_factor)); //convert blocks of samples with intrinsics size_t i = 0; for (; i < (nsamps & ~0x3); i+=4){ @@ -78,7 +78,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = uhd::byteswap(fc32_to_item32(input[i])); + output[i] = uhd::byteswap(fc32_to_item32(input[i], float(scale_factor))); } } @@ -86,7 +86,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){ const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]); - __m128 scalar = _mm_set_ps1(floats_per_short/(1 << 16)); + __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 16)); __m128i zeroi = _mm_setzero_si128(); //convert blocks of samples with intrinsics @@ -111,7 +111,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = item32_to_fc32(input[i]); + output[i] = item32_to_fc32(input[i], float(scale_factor)); } } @@ -119,7 +119,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){ const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]); - __m128 scalar = _mm_set_ps1(floats_per_short/(1 << 16)); + __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 16)); __m128i zeroi = _mm_setzero_si128(); //convert blocks of samples with intrinsics @@ -143,6 +143,6 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){ //convert remainder for (; i < nsamps; i++){ - output[i] = item32_to_fc32(uhd::byteswap(input[i])); + output[i] = item32_to_fc32(uhd::byteswap(input[i]), float(scale_factor)); } } diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index f03448047..8c3138bda 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -34,7 +34,7 @@ DECLARE_CONVERTER(convert_$(cpu_type)_1_to_item32_1_$(swap), PRIORITY_GENERAL){ item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); for (size_t i = 0; i < nsamps; i++){ - output[i] = $(swap_fcn)($(cpu_type)_to_item32(input[i])); + output[i] = $(swap_fcn)($(cpu_type)_to_item32(input[i], float(scale_factor))); } } @@ -43,7 +43,7 @@ DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_1_$(swap), PRIORITY_GENERAL){ $(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]); for (size_t i = 0; i < nsamps; i++){ - output[i] = item32_to_$(cpu_type)($(swap_fcn)(input[i])); + output[i] = item32_to_$(cpu_type)($(swap_fcn)(input[i]), float(scale_factor)); } } """ @@ -56,7 +56,7 @@ DECLARE_CONVERTER(convert_$(cpu_type)_$(width)_to_item32_1_$(swap), PRIORITY_GEN for (size_t i = 0, j = 0; i < nsamps; i++){ #for $w in range($width) - output[j++] = $(swap_fcn)($(cpu_type)_to_item32(input$(w)[i])); + output[j++] = $(swap_fcn)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor))); #end for } } @@ -69,7 +69,7 @@ DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_$(width)_$(swap), PRIORITY_GEN for (size_t i = 0, j = 0; i < nsamps; i++){ #for $w in range($width) - output$(w)[i] = item32_to_$(cpu_type)($(swap_fcn)(input[j++])); + output$(w)[i] = item32_to_$(cpu_type)($(swap_fcn)(input[j++]), float(scale_factor)); #end for } } diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp index d74b2c13c..26dbe1806 100644 --- a/host/lib/transport/vrt_packet_handler.hpp +++ b/host/lib/transport/vrt_packet_handler.hpp @@ -203,7 +203,7 @@ template <typename T> UHD_INLINE T get_context_code( } //copy-convert the samples from the recv buffer - converter(state.copy_buffs[i], state.io_buffs, nsamps_to_copy_per_io_buff); + converter(state.copy_buffs[i], state.io_buffs, nsamps_to_copy_per_io_buff, 1/32767.); //update the rx copy buffer to reflect the bytes copied state.copy_buffs[i] += bytes_to_copy; @@ -354,7 +354,7 @@ template <typename T> UHD_INLINE T get_context_code( otw_mem += if_packet_info.num_header_words32; //copy-convert the samples into the send buffer - converter(state.io_buffs, otw_mem, num_samps); + converter(state.io_buffs, otw_mem, num_samps, 32767.); //commit the samples to the zero-copy interface size_t num_bytes_total = (vrt_header_offset_words32+if_packet_info.num_packet_words32)*sizeof(boost::uint32_t); diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp index d1c2b7625..ff37d4a0a 100644 --- a/host/tests/convert_test.cpp +++ b/host/tests/convert_test.cpp @@ -55,12 +55,12 @@ template <typename Range> static void loopback( //convert to intermediate type convert::get_converter_cpu_to_otw( io_type, otw_type, input0.size(), output0.size() - )(input0, output0, nsamps); + )(input0, output0, nsamps, 1/32767.); //convert back to host type convert::get_converter_otw_to_cpu( io_type, otw_type, input1.size(), output1.size() - )(input1, output1, nsamps); + )(input1, output1, nsamps, 32767.); } /*********************************************************************** @@ -207,12 +207,12 @@ BOOST_AUTO_TEST_CASE(test_convert_types_fc32_to_sc16){ //convert float to intermediate convert::get_converter_cpu_to_otw( io_type_in, otw_type, input0.size(), output0.size() - )(input0, output0, nsamps); + )(input0, output0, nsamps, 1/32767.); //convert intermediate to short convert::get_converter_otw_to_cpu( io_type_out, otw_type, input1.size(), output1.size() - )(input1, output1, nsamps); + )(input1, output1, nsamps, 32767.); //test that the inputs and outputs match for (size_t i = 0; i < nsamps; i++){ @@ -247,12 +247,12 @@ BOOST_AUTO_TEST_CASE(test_convert_types_sc16_to_fc32){ //convert short to intermediate convert::get_converter_cpu_to_otw( io_type_in, otw_type, input0.size(), output0.size() - )(input0, output0, nsamps); + )(input0, output0, nsamps, 32767.); //convert intermediate to float convert::get_converter_otw_to_cpu( io_type_out, otw_type, input1.size(), output1.size() - )(input1, output1, nsamps); + )(input1, output1, nsamps, 1/32767.); //test that the inputs and outputs match for (size_t i = 0; i < nsamps; i++){ |