diff options
author | Philipp Maier <pmaier@sysmocom.de> | 2017-12-06 18:08:38 +0100 |
---|---|---|
committer | Philipp Maier <pmaier@sysmocom.de> | 2018-04-17 16:34:53 +0200 |
commit | 69d0d506775c82eb2bde66fe748100a94a3173a0 (patch) | |
tree | 4e94b55c6b97cde07d40a4e76b13611894d21385 /src/osmo-bts-trx/scheduler_trx.c | |
parent | dd4a6518f2118775c12affc02ac1e0dcc848d89a (diff) |
osmo-bts-trx: perform error concealment for FR frames
When a bad voice frame is received, it is replaced by
a silence frame. This may cause unpleasant audio effects.
This change implements a functionality to craft a replacement
frame from the last known good frame using ECU implementation
from libosmocodec. At the moment, only FR is supported.
Depends: libosmocore I06a21f60db01bfe1c2b838f93866fad1d53fdcd1
Change-Id: Iae9e69a9578ae305bca42f834694af96a29084e6
Diffstat (limited to 'src/osmo-bts-trx/scheduler_trx.c')
-rw-r--r-- | src/osmo-bts-trx/scheduler_trx.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c index d96eea09..4a31df2f 100644 --- a/src/osmo-bts-trx/scheduler_trx.c +++ b/src/osmo-bts-trx/scheduler_trx.c @@ -31,6 +31,7 @@ #include <osmocom/core/msgb.h> #include <osmocom/core/talloc.h> #include <osmocom/codec/codec.h> +#include <osmocom/codec/ecu.h> #include <osmocom/core/bits.h> #include <osmocom/gsm/a5.h> #include <osmocom/coding/gsm0503_coding.h> @@ -964,6 +965,7 @@ int rx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, uint8_t tch_data[128]; /* just to be safe */ int rc, amr = 0; int n_errors, n_bits_total; + bool bfi_flag = false; struct gsm_lchan *lchan = get_lchan_by_chan_nr(l1t->trx, trx_chan_desc[chan].chan_nr | tn); @@ -1054,11 +1056,13 @@ int rx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, if (rc < 0) { LOGL1S(DL1P, LOGL_NOTICE, l1t, tn, chan, fn, "Received bad data (%u/%u)\n", fn % l1ts->mf_period, l1ts->mf_period); + bfi_flag = true; goto bfi; } if (rc < 4) { LOGL1S(DL1P, LOGL_NOTICE, l1t, tn, chan, fn, "Received bad data (%u/%u) " "with invalid codec mode %d\n", fn % l1ts->mf_period, l1ts->mf_period, rc); + bfi_flag = true; goto bfi; } @@ -1075,8 +1079,14 @@ bfi: case GSM48_CMODE_SPEECH_V1: /* FR */ if (lchan->tch.dtx.ul_sid) return 0; /* DTXu: pause in progress */ - memset(tch_data, 0, GSM_FR_BYTES); - tch_data[0] = 0xd0; + + /* Perform error concealment if possible */ + rc = osmo_ecu_fr_conceal(&lchan->ecu_state.fr, tch_data); + if (rc) { + memset(tch_data, 0, GSM_FR_BYTES); + tch_data[0] = 0xd0; + } + rc = GSM_FR_BYTES; break; case GSM48_CMODE_SPEECH_EFR: /* EFR */ @@ -1104,6 +1114,10 @@ bfi: if (rsl_cmode != RSL_CMOD_SPD_SPEECH) return 0; + /* Reset ECU with a good frame */ + if (!bfi_flag && tch_mode == GSM48_CMODE_SPEECH_V1) + osmo_ecu_fr_reset(&lchan->ecu_state.fr, tch_data); + /* TCH or BFI */ return _sched_compose_tch_ind(l1t, tn, (fn + GSM_HYPERFRAME - 7) % GSM_HYPERFRAME, chan, tch_data, rc); |