aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
Diffstat (limited to 'host')
-rw-r--r--host/tests/convert_test.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp
index 3d78ea418..67d035e7a 100644
--- a/host/tests/convert_test.cpp
+++ b/host/tests/convert_test.cpp
@@ -384,6 +384,59 @@ static void test_convert_types_for_floats(size_t nsamps,
}
}
+template <typename data_type>
+static void test_convert_types_for_floats_with_saturation(size_t nsamps,
+ convert::id_type& id,
+ const double extra_scale = 1.0)
+{
+ typedef typename data_type::value_type value_type;
+
+ // fill the input samples
+ std::vector<data_type> input(nsamps), output(nsamps), expected_output(nsamps);
+ for (size_t sample_count = 0; sample_count < nsamps; sample_count++)
+ {
+ value_type real_data = ((std::rand() / (value_type(RAND_MAX) / 2)) - 1) * float(extra_scale);
+ value_type imag_data = ((std::rand() / (value_type(RAND_MAX) / 2)) - 1) * float(extra_scale);
+ value_type expected_real_data = real_data;
+ value_type expected_imag_data = imag_data;
+ if(sample_count & 1)
+ {
+ // To ensure that some samples are out of range and thus should be
+ // saturated, every alternating sample's real and imaginary values
+ // are pushed outside of the [-1..1] range.
+ real_data = (real_data < 0.0) ? real_data - 1.0 : real_data + 1.0;
+ imag_data = (imag_data < 0.0) ? imag_data - 1.0 : imag_data + 1.0;
+
+ // The expected output values after loopback for these samples are
+ // -1.0 or 1.0.
+ expected_real_data = (real_data < 0.0) ? -1.0 : 1.0;
+ expected_imag_data = (imag_data < 0.0) ? -1.0 : 1.0;
+ }
+ input[sample_count] = data_type(real_data, imag_data);
+ expected_output[sample_count] = data_type(expected_real_data, expected_imag_data);
+ }
+
+ // run the loopback and test
+ convert::id_type in_id = id;
+ convert::id_type out_id = id;
+ std::swap(out_id.input_format, out_id.output_format);
+ std::swap(out_id.num_inputs, out_id.num_outputs);
+
+ // make a list of all prio: best/generic combos
+ typedef std::pair<int, int> int_pair_t;
+ const std::vector<int_pair_t> prios{
+ int_pair_t(0, 0), int_pair_t(-1, 0), int_pair_t(0, -1), int_pair_t(-1, -1)};
+
+ // loopback foreach prio combo (generic vs best)
+ for (const auto& prio : prios) {
+ CALL_LOOPBACK_SAFE(nsamps, in_id, out_id, input, output, prio.first, prio.second);
+ for (size_t i = 0; i < nsamps; i++) {
+ MY_CHECK_CLOSE(expected_output[i].real(), output[i].real(), value_type(1. / (1 << 14)));
+ MY_CHECK_CLOSE(expected_output[i].imag(), output[i].imag(), value_type(1. / (1 << 14)));
+ }
+ }
+}
+
BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32)
{
convert::id_type id;
@@ -398,6 +451,20 @@ BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32)
}
}
+BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32_with_saturation)
+{
+ convert::id_type id;
+ id.input_format = "fc32";
+ id.num_inputs = 1;
+ id.output_format = "sc16_item32_be";
+ id.num_outputs = 1;
+
+ // try various lengths to test edge cases
+ for (size_t nsamps = 1; nsamps < 16; nsamps++) {
+ test_convert_types_for_floats_with_saturation<fc32_t>(nsamps, id);
+ }
+}
+
BOOST_TEST_DECORATOR(*boost::unit_test::disabled())
BOOST_AUTO_TEST_CASE(benchmark_convert_types_be_fc32)
{
@@ -428,6 +495,20 @@ BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32)
}
}
+BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32_with_saturation)
+{
+ convert::id_type id;
+ id.input_format = "fc32";
+ id.num_inputs = 1;
+ id.output_format = "sc16_item32_le";
+ id.num_outputs = 1;
+
+ // try various lengths to test edge cases
+ for (size_t nsamps = 1; nsamps < 16; nsamps++) {
+ test_convert_types_for_floats_with_saturation<fc32_t>(nsamps, id);
+ }
+}
+
BOOST_TEST_DECORATOR(*boost::unit_test::disabled())
BOOST_AUTO_TEST_CASE(benchmark_convert_types_le_fc32)
{
@@ -458,6 +539,20 @@ BOOST_AUTO_TEST_CASE(test_convert_types_chdr_fc32)
}
}
+BOOST_AUTO_TEST_CASE(test_convert_types_chdr_fc32_with_saturation)
+{
+ convert::id_type id;
+ id.input_format = "fc32";
+ id.num_inputs = 1;
+ id.output_format = "sc16_chdr";
+ id.num_outputs = 1;
+
+ // try various lengths to test edge cases
+ for (size_t nsamps = 1; nsamps < 16; nsamps++) {
+ test_convert_types_for_floats_with_saturation<fc32_t>(nsamps, id);
+ }
+}
+
BOOST_TEST_DECORATOR(*boost::unit_test::disabled())
BOOST_AUTO_TEST_CASE(benchmark_convert_types_chdr_fc32)
{
@@ -488,6 +583,20 @@ BOOST_AUTO_TEST_CASE(test_convert_types_be_fc64)
}
}
+BOOST_AUTO_TEST_CASE(test_convert_types_be_fc64_with_saturation)
+{
+ convert::id_type id;
+ id.input_format = "fc64";
+ id.num_inputs = 1;
+ id.output_format = "sc16_item32_be";
+ id.num_outputs = 1;
+
+ // try various lengths to test edge cases
+ for (size_t nsamps = 1; nsamps < 16; nsamps++) {
+ test_convert_types_for_floats_with_saturation<fc64_t>(nsamps, id);
+ }
+}
+
BOOST_TEST_DECORATOR(*boost::unit_test::disabled())
BOOST_AUTO_TEST_CASE(benchmark_convert_types_be_fc64)
{
@@ -518,6 +627,20 @@ BOOST_AUTO_TEST_CASE(test_convert_types_le_fc64)
}
}
+BOOST_AUTO_TEST_CASE(test_convert_types_le_fc64_with_saturation)
+{
+ convert::id_type id;
+ id.input_format = "fc64";
+ id.num_inputs = 1;
+ id.output_format = "sc16_item32_le";
+ id.num_outputs = 1;
+
+ // try various lengths to test edge cases
+ for (size_t nsamps = 1; nsamps < 16; nsamps++) {
+ test_convert_types_for_floats_with_saturation<fc64_t>(nsamps, id);
+ }
+}
+
BOOST_TEST_DECORATOR(*boost::unit_test::disabled())
BOOST_AUTO_TEST_CASE(benchmark_convert_types_le_fc64)
{
@@ -548,6 +671,20 @@ BOOST_AUTO_TEST_CASE(test_convert_types_chdr_fc64)
}
}
+BOOST_AUTO_TEST_CASE(test_convert_types_chdr_fc64_with_saturation)
+{
+ convert::id_type id;
+ id.input_format = "fc64";
+ id.num_inputs = 1;
+ id.output_format = "sc16_chdr";
+ id.num_outputs = 1;
+
+ // try various lengths to test edge cases
+ for (size_t nsamps = 1; nsamps < 16; nsamps++) {
+ test_convert_types_for_floats_with_saturation<fc64_t>(nsamps, id);
+ }
+}
+
BOOST_TEST_DECORATOR(*boost::unit_test::disabled())
BOOST_AUTO_TEST_CASE(benchmark_convert_types_chdr_fc64)
{