aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/convert/convert_common.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/convert/convert_common.hpp')
-rw-r--r--host/lib/convert/convert_common.hpp270
1 files changed, 150 insertions, 120 deletions
diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp
index 7626e4d87..933978a8f 100644
--- a/host/lib/convert/convert_common.hpp
+++ b/host/lib/convert/convert_common.hpp
@@ -53,12 +53,12 @@ static const int PRIORITY_EMPTY = -1;
#ifdef __ARM_NEON__
static const int PRIORITY_LIBORC = 3;
-static const int PRIORITY_SIMD = 1; //neon conversions could be implemented better, orc wins
-static const int PRIORITY_TABLE = 2; //tables require large cache, so they are slower on arm
+static const int PRIORITY_SIMD = 2; //neon conversions could be implemented better, orc wins
+static const int PRIORITY_TABLE = 1; //tables require large cache, so they are slower on arm
#else
-static const int PRIORITY_LIBORC = 1;
+static const int PRIORITY_LIBORC = 2;
static const int PRIORITY_SIMD = 3;
-static const int PRIORITY_TABLE = 2;
+static const int PRIORITY_TABLE = 1;
#endif
/***********************************************************************
@@ -77,123 +77,92 @@ typedef boost::int8_t s8_t;
typedef boost::uint32_t item32_t;
-/***********************************************************************
- * Convert complex short buffer to items32 sc16
- **********************************************************************/
-static UHD_INLINE item32_t sc16_to_item32_sc16(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);
-}
+typedef item32_t (*xtox_t)(item32_t);
/***********************************************************************
- * Convert items32 sc16 buffer to complex short
+ * Convert xx to items32 sc16 buffer
**********************************************************************/
-static UHD_INLINE sc16_t item32_sc16_to_sc16(item32_t item, double){
- return sc16_t(
- boost::int16_t(item >> 16),
- boost::int16_t(item >> 0)
- );
-}
-
-/***********************************************************************
- * Convert complex float buffer to items32 sc16
- **********************************************************************/
-static UHD_INLINE item32_t fc32_to_item32_sc16(fc32_t num, double scale_factor){
+template <typename T> UHD_INLINE item32_t xx_to_item32_sc16_x1(
+ const std::complex<T> &num, const double scale_factor
+){
boost::uint16_t real = boost::int16_t(num.real()*float(scale_factor));
boost::uint16_t imag = boost::int16_t(num.imag()*float(scale_factor));
return (item32_t(real) << 16) | (item32_t(imag) << 0);
}
-/***********************************************************************
- * Convert items32 sc16 buffer to complex float
- **********************************************************************/
-static UHD_INLINE fc32_t item32_sc16_to_fc32(item32_t item, double scale_factor){
- return fc32_t(
- float(boost::int16_t(item >> 16)*float(scale_factor)),
- float(boost::int16_t(item >> 0)*float(scale_factor))
- );
-}
-
-/***********************************************************************
- * Convert complex double buffer to items32 sc16
- **********************************************************************/
-static UHD_INLINE item32_t fc64_to_item32_sc16(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);
+template <> UHD_INLINE item32_t xx_to_item32_sc16_x1(
+ const sc16_t &num, const double
+){
+ boost::uint16_t real = boost::int16_t(num.real());
+ boost::uint16_t imag = boost::int16_t(num.imag());
return (item32_t(real) << 16) | (item32_t(imag) << 0);
}
-/***********************************************************************
- * Convert items32 sc16 buffer to complex double
- **********************************************************************/
-static UHD_INLINE fc64_t item32_sc16_to_fc64(item32_t item, double scale_factor){
- return fc64_t(
- float(boost::int16_t(item >> 16)*scale_factor),
- float(boost::int16_t(item >> 0)*scale_factor)
- );
+template <xtox_t to_wire, typename T>
+UHD_INLINE void xx_to_item32_sc16(
+ const std::complex<T> *input,
+ item32_t *output,
+ const size_t nsamps,
+ const double scale_factor
+){
+ for (size_t i = 0; i < nsamps; i++){
+ const item32_t item = xx_to_item32_sc16_x1(input[i], scale_factor);
+ output[i] = to_wire(item);
+ }
}
/***********************************************************************
- * Convert items32 sc8 buffer to complex char
+ * Convert items32 sc16 buffer to xx
**********************************************************************/
-static UHD_INLINE void item32_sc8_to_sc8(item32_t item, sc8_t &out0, sc8_t &out1, double){
- out0 = sc8_t(
- boost::int8_t(item >> 8),
- boost::int8_t(item >> 0)
- );
- out1 = sc8_t(
- boost::int8_t(item >> 24),
- boost::int8_t(item >> 16)
+template <typename T> UHD_INLINE std::complex<T> item32_sc16_x1_to_xx(
+ const item32_t item, const double scale_factor
+){
+ return std::complex<T>(
+ T(boost::int16_t(item >> 16)*float(scale_factor)),
+ T(boost::int16_t(item >> 0)*float(scale_factor))
);
}
-/***********************************************************************
- * Convert items32 sc8 buffer to complex short
- **********************************************************************/
-static UHD_INLINE void item32_sc8_to_sc16(item32_t item, sc16_t &out0, sc16_t &out1, double){
- out0 = sc16_t(
- boost::int8_t(item >> 8),
- boost::int8_t(item >> 0)
- );
- out1 = sc16_t(
- boost::int8_t(item >> 24),
- boost::int8_t(item >> 16)
+template <> UHD_INLINE sc16_t item32_sc16_x1_to_xx(
+ const item32_t item, const double
+){
+ return sc16_t(
+ boost::int16_t(item >> 16), boost::int16_t(item >> 0)
);
}
-/***********************************************************************
- * Convert items32 sc8 buffer to complex float
- **********************************************************************/
-static UHD_INLINE void item32_sc8_to_fc32(item32_t item, fc32_t &out0, fc32_t &out1, double scale_factor){
- out0 = fc32_t(
- float(boost::int8_t(item >> 8)*float(scale_factor)),
- float(boost::int8_t(item >> 0)*float(scale_factor))
- );
- out1 = fc32_t(
- float(boost::int8_t(item >> 24)*float(scale_factor)),
- float(boost::int8_t(item >> 16)*float(scale_factor))
- );
+template <xtox_t to_host, typename T>
+UHD_INLINE void item32_sc16_to_xx(
+ const item32_t *input,
+ std::complex<T> *output,
+ const size_t nsamps,
+ const double scale_factor
+){
+ for (size_t i = 0; i < nsamps; i++){
+ const item32_t item_i = to_host(input[i]);
+ output[i] = item32_sc16_x1_to_xx<T>(item_i, scale_factor);
+ }
}
/***********************************************************************
- * Convert items32 sc8 buffer to complex double
+ * Convert xx to items32 sc8 buffer
**********************************************************************/
-static UHD_INLINE void item32_sc8_to_fc64(item32_t item, fc64_t &out0, fc64_t &out1, double scale_factor){
- out0 = fc64_t(
- float(boost::int8_t(item >> 8)*scale_factor),
- float(boost::int8_t(item >> 0)*scale_factor)
- );
- out1 = fc64_t(
- float(boost::int8_t(item >> 24)*scale_factor),
- float(boost::int8_t(item >> 16)*scale_factor)
- );
+template <typename T> UHD_INLINE item32_t xx_to_item32_sc8_x1(
+ const std::complex<T> &in0, const std::complex<T> &in1, const double scale_factor
+){
+ boost::uint8_t real0 = boost::int8_t(in0.real()*float(scale_factor));
+ boost::uint8_t imag0 = boost::int8_t(in0.imag()*float(scale_factor));
+ boost::uint8_t real1 = boost::int8_t(in1.real()*float(scale_factor));
+ boost::uint8_t imag1 = boost::int8_t(in1.imag()*float(scale_factor));
+ return
+ (item32_t(real0) << 8) | (item32_t(imag0) << 0) |
+ (item32_t(real1) << 24) | (item32_t(imag1) << 16)
+ ;
}
-/***********************************************************************
- * Convert complex char to items32 sc8 buffer
- **********************************************************************/
-static UHD_INLINE item32_t sc8_to_item32_sc8(sc8_t in0, sc8_t in1, double){
+template <> UHD_INLINE item32_t xx_to_item32_sc8_x1(
+ const sc16_t &in0, const sc16_t &in1, const double
+){
boost::uint8_t real0 = boost::int8_t(in0.real());
boost::uint8_t imag0 = boost::int8_t(in0.imag());
boost::uint8_t real1 = boost::int8_t(in1.real());
@@ -204,10 +173,9 @@ static UHD_INLINE item32_t sc8_to_item32_sc8(sc8_t in0, sc8_t in1, double){
;
}
-/***********************************************************************
- * Convert complex short to items32 sc8 buffer
- **********************************************************************/
-static UHD_INLINE item32_t sc16_to_item32_sc8(sc16_t in0, sc16_t in1, double){
+template <> UHD_INLINE item32_t xx_to_item32_sc8_x1(
+ const sc8_t &in0, const sc8_t &in1, const double
+){
boost::uint8_t real0 = boost::int8_t(in0.real());
boost::uint8_t imag0 = boost::int8_t(in0.imag());
boost::uint8_t real1 = boost::int8_t(in1.real());
@@ -218,32 +186,94 @@ static UHD_INLINE item32_t sc16_to_item32_sc8(sc16_t in0, sc16_t in1, double){
;
}
-/***********************************************************************
- * Convert complex float to items32 sc8 buffer
- **********************************************************************/
-static UHD_INLINE item32_t fc32_to_item32_sc8(fc32_t in0, fc32_t in1, double scale_factor){
- boost::uint8_t real0 = boost::int8_t(in0.real()*float(scale_factor));
- boost::uint8_t imag0 = boost::int8_t(in0.imag()*float(scale_factor));
- boost::uint8_t real1 = boost::int8_t(in1.real()*float(scale_factor));
- boost::uint8_t imag1 = boost::int8_t(in1.imag()*float(scale_factor));
- return
- (item32_t(real0) << 8) | (item32_t(imag0) << 0) |
- (item32_t(real1) << 24) | (item32_t(imag1) << 16)
- ;
+template <xtox_t to_wire, typename T>
+UHD_INLINE void xx_to_item32_sc8(
+ const std::complex<T> *input,
+ item32_t *output,
+ const size_t nsamps,
+ const double scale_factor
+){
+ const size_t num_pairs = nsamps/2;
+ for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){
+ const item32_t item = xx_to_item32_sc8_x1(input[j], input[j+1], scale_factor);
+ output[i] = to_wire(item);
+ }
+
+ if (nsamps != num_pairs*2){
+ const item32_t item = xx_to_item32_sc8_x1(input[nsamps-1], std::complex<T>(0), scale_factor);
+ output[num_pairs] = to_wire(item);
+ }
}
/***********************************************************************
- * Convert complex double to items32 sc8 buffer
+ * Convert items32 sc8 buffer to xx
**********************************************************************/
-static UHD_INLINE item32_t fc64_to_item32_sc8(fc64_t in0, fc64_t in1, double scale_factor){
- boost::uint8_t real0 = boost::int8_t(in0.real()*(scale_factor));
- boost::uint8_t imag0 = boost::int8_t(in0.imag()*(scale_factor));
- boost::uint8_t real1 = boost::int8_t(in1.real()*(scale_factor));
- boost::uint8_t imag1 = boost::int8_t(in1.imag()*(scale_factor));
- return
- (item32_t(real0) << 8) | (item32_t(imag0) << 0) |
- (item32_t(real1) << 24) | (item32_t(imag1) << 16)
- ;
+template <typename T> UHD_INLINE void item32_sc8_x1_to_xx(
+ const item32_t item, std::complex<T> &out0, std::complex<T> &out1, const double scale_factor
+){
+ out0 = std::complex<T>(
+ T(boost::int8_t(item >> 8)*float(scale_factor)),
+ T(boost::int8_t(item >> 0)*float(scale_factor))
+ );
+ out1 = std::complex<T>(
+ T(boost::int8_t(item >> 24)*float(scale_factor)),
+ T(boost::int8_t(item >> 16)*float(scale_factor))
+ );
+}
+
+template <> UHD_INLINE void item32_sc8_x1_to_xx(
+ const item32_t item, sc16_t &out0, sc16_t &out1, const double
+){
+ out0 = sc16_t(
+ boost::int16_t(boost::int8_t(item >> 8)),
+ boost::int16_t(boost::int8_t(item >> 0))
+ );
+ out1 = sc16_t(
+ boost::int16_t(boost::int8_t(item >> 24)),
+ boost::int16_t(boost::int8_t(item >> 16))
+ );
+}
+
+template <> UHD_INLINE void item32_sc8_x1_to_xx(
+ const item32_t item, sc8_t &out0, sc8_t &out1, const double
+){
+ out0 = sc8_t(
+ boost::int8_t(boost::int8_t(item >> 8)),
+ boost::int8_t(boost::int8_t(item >> 0))
+ );
+ out1 = sc8_t(
+ boost::int8_t(boost::int8_t(item >> 24)),
+ boost::int8_t(boost::int8_t(item >> 16))
+ );
+}
+
+template <xtox_t to_host, typename T>
+UHD_INLINE void item32_sc8_to_xx(
+ const item32_t *input,
+ std::complex<T> *output,
+ const size_t nsamps,
+ const double scale_factor
+){
+ input = reinterpret_cast<const item32_t *>(size_t(input) & ~0x3);
+ std::complex<T> dummy;
+ size_t num_samps = nsamps;
+
+ if ((size_t(input) & 0x3) != 0){
+ const item32_t item0 = to_host(*input++);
+ item32_sc8_x1_to_xx(item0, dummy, *output++, scale_factor);
+ num_samps--;
+ }
+
+ const size_t num_pairs = num_samps/2;
+ for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){
+ const item32_t item_i = to_host(input[i]);
+ item32_sc8_x1_to_xx(item_i, output[j], output[j+1], scale_factor);
+ }
+
+ if (num_samps != num_pairs*2){
+ const item32_t item_n = to_host(input[num_pairs]);
+ item32_sc8_x1_to_xx(item_n, output[num_samps-1], dummy, scale_factor);
+ }
}
#endif /* INCLUDED_LIBUHD_CONVERT_COMMON_HPP */