diff --git a/libcelt/celt.c b/libcelt/celt.c index d6c2b4dc6f49569202c905a9144cbc18074bf119..37f3d7cba517fad9e15368658c70cbfcd389a3b2 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -144,6 +144,7 @@ struct CELTEncoder { int vbr; int signalling; int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */ + int loss_rate; /* Everything beyond this point gets cleared on a reset */ #define ENCODER_RESET_START rng @@ -1142,6 +1143,12 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i if (pitch_index > COMBFILTER_MAXPERIOD-2) pitch_index = COMBFILTER_MAXPERIOD-2; gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1); + if (st->loss_rate>2) + gain1 = HALF32(gain1); + if (st->loss_rate>4) + gain1 = HALF32(gain1); + if (st->loss_rate>8) + gain1 = 0; prefilter_tapset = st->tapset_decision; } else { gain1 = 0; @@ -1787,6 +1794,14 @@ int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...) st->force_intra = value==0; } break; + case CELT_SET_LOSS_PERC_REQUEST: + { + int value = va_arg(ap, celt_int32); + if (value<0 || value>100) + goto bad_arg; + st->loss_rate = value; + } + break; case CELT_SET_VBR_CONSTRAINT_REQUEST: { celt_int32 value = va_arg(ap, celt_int32); diff --git a/libcelt/celt.h b/libcelt/celt.h index 11eb425ab70041879c6e8a95fe6aee31f929f008..2bbf506603cc648d031b93f5a1b7432d10db4153 100644 --- a/libcelt/celt.h +++ b/libcelt/celt.h @@ -112,6 +112,9 @@ extern "C" { #define CELT_SET_CHANNELS_REQUEST 18 #define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, _celt_check_int(x) +#define CELT_SET_LOSS_PERC_REQUEST 20 +#define CELT_SET_LOSS_PERC(x) CELT_SET_LOSS_PERC_REQUEST, _celt_check_int(x) + /* Internal */ #define CELT_SET_START_BAND_REQUEST 10000 #define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, _celt_check_int(x)