summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cesar/ce/rx/bitloading/src/bitloading.c25
-rw-r--r--cesar/ce/rx/bitloading/test/src/test_bl.c53
2 files changed, 71 insertions, 7 deletions
diff --git a/cesar/ce/rx/bitloading/src/bitloading.c b/cesar/ce/rx/bitloading/src/bitloading.c
index 141633f587..cd599b06b5 100644
--- a/cesar/ce/rx/bitloading/src/bitloading.c
+++ b/cesar/ce/rx/bitloading/src/bitloading.c
@@ -187,13 +187,24 @@ ce_rx_bl_update_tone_map_at_ber_consign (u64 ber_pt,
}
/* Sanity check: we must have done something! */
dbg_assert (mod != -1);
- /* Remove last one. */
- tm->bits_per_symbol -= CE_BIT_PER_MOD[mod];
- tonemap_write_tone_to_word (tone_word, opti[pos - 1].carrier_index,
- --mod);
- tm->bits_per_symbol += CE_BIT_PER_MOD[mod];
- if (mod == 0)
- tone_en--;
+ /* Remove last tone if we are over target. */
+ if (ber_weighted_sum > ber_pt * tm->bits_per_symbol)
+ {
+ /* Go back to last position. */
+ pos--;
+ dbg_assert (pos < tonemask->carrier_nb);
+ /* Remove last one. */
+ tm->bits_per_symbol -= CE_BIT_PER_MOD[mod];
+ ber_weighted_sum -= (opti[pos].ber_lower + ((u64) opti[pos].ber_diff << 32))
+ * CE_BIT_PER_MOD[mod];
+ /* Write new value. */
+ tonemap_write_tone_to_word (tone_word, opti[pos].carrier_index,
+ --mod);
+ tm->bits_per_symbol += CE_BIT_PER_MOD[mod];
+ ber_weighted_sum += opti[pos].ber_lower * CE_BIT_PER_MOD[mod];
+ if (mod == 0)
+ tone_en--;
+ }
/* Return number of tones enabled. */
return tone_en;
}
diff --git a/cesar/ce/rx/bitloading/test/src/test_bl.c b/cesar/ce/rx/bitloading/test/src/test_bl.c
index d68c56124c..367605bd4e 100644
--- a/cesar/ce/rx/bitloading/test/src/test_bl.c
+++ b/cesar/ce/rx/bitloading/test/src/test_bl.c
@@ -863,6 +863,59 @@ test_suite_ce_rx_bl_optimization_table (test_t t)
tonemap_free (tm);
test_fail_if (assert == true, "access outside of optimization table");
} test_end;
+
+ test_begin (t, "last tone removed after optimization when BER over "
+ "target")
+ {
+ u64 target = ti.carrier_nb / 2;
+ tonemap_t *tm = tonemap_alloc ();
+ TONEMAP_WRITE_BEGIN (tm, ti.tonemask)
+ {
+ TONEMAP_WRITE_MOD (0);
+ }
+ TONEMAP_WRITE_END;
+ tm->bits_per_symbol = 0;
+ uint i;
+ for (i = 0; i < target; i++)
+ {
+ opti[i].carrier_index = i;
+ opti[i].ber_lower = 0;
+ opti[i].ber_diff = 0;
+ }
+ for (i = target; i < ti.carrier_nb; i++)
+ {
+ opti[i].carrier_index = i;
+ opti[i].ber_lower = 0;
+ opti[i].ber_diff = 1;
+ }
+ test_fail_if (ce_rx_bl_update_tone_map_at_ber_consign
+ (1, &ti, &bl, tm, opti, 0, 0) != target);
+ /* Clean. */
+ tonemap_free (tm);
+ } test_end;
+
+ test_begin (t, "do not remove last tone when over optimization table")
+ {
+ tonemap_t *tm = tonemap_alloc ();
+ TONEMAP_WRITE_BEGIN (tm, ti.tonemask)
+ {
+ TONEMAP_WRITE_MOD (0);
+ }
+ TONEMAP_WRITE_END;
+ tm->bits_per_symbol = 0;
+ uint i;
+ for (i = 0; i < ti.carrier_nb; i++)
+ {
+ opti[i].carrier_index = i;
+ opti[i].ber_lower = 0;
+ opti[i].ber_diff = 1;
+ }
+ test_fail_if (ce_rx_bl_update_tone_map_at_ber_consign
+ (CE_RX_BL_BER_DEFAULT_OVER - 1, &ti, &bl, tm, opti, 0, 0)
+ != ti.carrier_nb);
+ /* Clean. */
+ tonemap_free (tm);
+ } test_end;
}
/**