Skip to content
Snippets Groups Projects
Verified Commit d1309dd2 authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

Simplifying the DRED/PLC code

parent 8c7c03e5
No related branches found
No related tags found
No related merge requests found
...@@ -154,11 +154,13 @@ static int get_fec_or_pred(LPCNetPLCState *st, float *out) { ...@@ -154,11 +154,13 @@ static int get_fec_or_pred(LPCNetPLCState *st, float *out) {
} }
} }
static void fec_rewind(LPCNetPLCState *st, int offset) { static void queue_features(LPCNetPLCState *st, const float *features) {
st->fec_read_pos -= offset; OPUS_MOVE(&st->cont_features[0], &st->cont_features[NB_FEATURES], (CONT_VECTORS-1)*NB_FEATURES);
if (st->fec_read_pos < st->fec_keep_pos) { OPUS_COPY(&st->cont_features[(CONT_VECTORS-1)*NB_FEATURES], features, NB_FEATURES);
st->fec_read_pos = st->fec_keep_pos; }
}
static void replace_features(LPCNetPLCState *st, const float *features) {
OPUS_COPY(&st->cont_features[(CONT_VECTORS-1)*NB_FEATURES], features, NB_FEATURES);
} }
/* In this causal version of the code, the DNN model implemented by compute_plc_pred() /* In this causal version of the code, the DNN model implemented by compute_plc_pred()
...@@ -170,29 +172,18 @@ int lpcnet_plc_update(LPCNetPLCState *st, opus_int16 *pcm) { ...@@ -170,29 +172,18 @@ int lpcnet_plc_update(LPCNetPLCState *st, opus_int16 *pcm) {
float plc_features[2*NB_BANDS+NB_FEATURES+1]; float plc_features[2*NB_BANDS+NB_FEATURES+1];
for (i=0;i<FRAME_SIZE;i++) x[i] = pcm[i]; for (i=0;i<FRAME_SIZE;i++) x[i] = pcm[i];
burg_cepstral_analysis(plc_features, x); burg_cepstral_analysis(plc_features, x);
lpcnet_compute_single_frame_features_float(&st->enc, x, st->features);
if (st->blend) { if (st->blend) {
replace_features(st, st->features);
if (FEATURES_DELAY > 0) st->plc_net = st->plc_copy[FEATURES_DELAY-1]; if (FEATURES_DELAY > 0) st->plc_net = st->plc_copy[FEATURES_DELAY-1];
fec_rewind(st, FEATURES_DELAY); } else {
} queue_features(st, st->features);
/* Update state. */ OPUS_COPY(&plc_features[2*NB_BANDS], st->features, NB_FEATURES);
/*fprintf(stderr, "update state\n");*/
for (i=0;i<FRAME_SIZE;i++) x[i] = pcm[i];
preemphasis(x, &st->enc.mem_preemph, x, PREEMPHASIS, FRAME_SIZE);
compute_frame_features(&st->enc, x);
process_single_frame(&st->enc, NULL);
if (!st->blend) {
OPUS_COPY(&plc_features[2*NB_BANDS], st->enc.features, NB_FEATURES);
plc_features[2*NB_BANDS+NB_FEATURES] = 1; plc_features[2*NB_BANDS+NB_FEATURES] = 1;
compute_plc_pred(st, st->features, plc_features); compute_plc_pred(st, st->features, plc_features);
/* Discard an FEC frame that we know we will no longer need. */
if (st->fec_skip) st->fec_skip--;
else if (st->fec_read_pos < st->fec_fill_pos) st->fec_read_pos++;
st->fec_keep_pos = IMAX(0, IMAX(st->fec_keep_pos, st->fec_read_pos-FEATURES_DELAY-1));
OPUS_MOVE(&st->cont_features[0], &st->cont_features[NB_FEATURES], (CONT_VECTORS-1)*NB_FEATURES);
} }
OPUS_COPY(&st->cont_features[(CONT_VECTORS-1)*NB_FEATURES], st->enc.features, NB_FEATURES); OPUS_MOVE(st->pcm, &st->pcm[FRAME_SIZE], PLC_BUF_SIZE-FRAME_SIZE);
OPUS_MOVE(st->pcm, &st->pcm[FRAME_SIZE], FARGAN_CONT_SAMPLES-FRAME_SIZE); for (i=0;i<FRAME_SIZE;i++) st->pcm[PLC_BUF_SIZE-FRAME_SIZE+i] = (1.f/32768.f)*pcm[i];
for (i=0;i<FRAME_SIZE;i++) st->pcm[FARGAN_CONT_SAMPLES-FRAME_SIZE+i] = (1.f/32768.f)*pcm[i];
st->loss_count = 0; st->loss_count = 0;
st->blend = 0; st->blend = 0;
return 0; return 0;
...@@ -203,12 +194,10 @@ int lpcnet_plc_conceal(LPCNetPLCState *st, opus_int16 *pcm) { ...@@ -203,12 +194,10 @@ int lpcnet_plc_conceal(LPCNetPLCState *st, opus_int16 *pcm) {
int i; int i;
if (st->blend == 0) { if (st->blend == 0) {
get_fec_or_pred(st, st->features); get_fec_or_pred(st, st->features);
OPUS_MOVE(&st->cont_features[0], &st->cont_features[NB_FEATURES], (CONT_VECTORS-1)*NB_FEATURES); queue_features(st, st->features);
OPUS_COPY(&st->cont_features[(CONT_VECTORS-1)*NB_FEATURES], st->features, NB_FEATURES);
get_fec_or_pred(st, st->features); get_fec_or_pred(st, st->features);
OPUS_MOVE(&st->cont_features[0], &st->cont_features[NB_FEATURES], (CONT_VECTORS-1)*NB_FEATURES); queue_features(st, st->features);
OPUS_COPY(&st->cont_features[(CONT_VECTORS-1)*NB_FEATURES], st->features, NB_FEATURES); fargan_cont(&st->fargan, &st->pcm[PLC_BUF_SIZE-FARGAN_CONT_SAMPLES], st->cont_features);
fargan_cont(&st->fargan, st->pcm, st->cont_features);
} }
OPUS_MOVE(&st->plc_copy[1], &st->plc_copy[0], FEATURES_DELAY); OPUS_MOVE(&st->plc_copy[1], &st->plc_copy[0], FEATURES_DELAY);
st->plc_copy[0] = st->plc_net; st->plc_copy[0] = st->plc_net;
...@@ -217,18 +206,11 @@ int lpcnet_plc_conceal(LPCNetPLCState *st, opus_int16 *pcm) { ...@@ -217,18 +206,11 @@ int lpcnet_plc_conceal(LPCNetPLCState *st, opus_int16 *pcm) {
if (st->loss_count >= 10) st->features[0] = MAX16(-10, st->features[0]+att_table[9] - 2*(st->loss_count-9)); if (st->loss_count >= 10) st->features[0] = MAX16(-10, st->features[0]+att_table[9] - 2*(st->loss_count-9));
else st->features[0] = MAX16(-10, st->features[0]+att_table[st->loss_count]); else st->features[0] = MAX16(-10, st->features[0]+att_table[st->loss_count]);
fargan_synthesize_int(&st->fargan, pcm, &st->features[0]); fargan_synthesize_int(&st->fargan, pcm, &st->features[0]);
{ lpcnet_compute_single_frame_features(&st->enc, pcm, st->features);
float x[FRAME_SIZE];
/* FIXME: Can we do better? */
for (i=0;i<FRAME_SIZE;i++) x[i] = pcm[i];
preemphasis(x, &st->enc.mem_preemph, x, PREEMPHASIS, FRAME_SIZE);
compute_frame_features(&st->enc, x);
process_single_frame(&st->enc, NULL);
}
OPUS_MOVE(&st->cont_features[0], &st->cont_features[NB_FEATURES], (CONT_VECTORS-1)*NB_FEATURES); OPUS_MOVE(&st->cont_features[0], &st->cont_features[NB_FEATURES], (CONT_VECTORS-1)*NB_FEATURES);
OPUS_COPY(&st->cont_features[(CONT_VECTORS-1)*NB_FEATURES], st->enc.features, NB_FEATURES); OPUS_COPY(&st->cont_features[(CONT_VECTORS-1)*NB_FEATURES], st->features, NB_FEATURES);
OPUS_MOVE(st->pcm, &st->pcm[FRAME_SIZE], FARGAN_CONT_SAMPLES-FRAME_SIZE); OPUS_MOVE(st->pcm, &st->pcm[FRAME_SIZE], PLC_BUF_SIZE-FRAME_SIZE);
for (i=0;i<FRAME_SIZE;i++) st->pcm[FARGAN_CONT_SAMPLES-FRAME_SIZE+i] = (1.f/32768.f)*pcm[i]; for (i=0;i<FRAME_SIZE;i++) st->pcm[PLC_BUF_SIZE-FRAME_SIZE+i] = (1.f/32768.f)*pcm[i];
st->blend = 1; st->blend = 1;
return 0; return 0;
} }
...@@ -46,7 +46,7 @@ struct LPCNetEncState{ ...@@ -46,7 +46,7 @@ struct LPCNetEncState{
float burg_cepstrum[2*NB_BANDS]; float burg_cepstrum[2*NB_BANDS];
}; };
#define PLC_BUF_SIZE (FEATURES_DELAY*FRAME_SIZE + FRAME_SIZE) #define PLC_BUF_SIZE (CONT_VECTORS*FRAME_SIZE)
struct LPCNetPLCState { struct LPCNetPLCState {
PLCModel model; PLCModel model;
FARGANState fargan; FARGANState fargan;
...@@ -60,7 +60,7 @@ struct LPCNetPLCState { ...@@ -60,7 +60,7 @@ struct LPCNetPLCState {
int fec_read_pos; int fec_read_pos;
int fec_fill_pos; int fec_fill_pos;
int fec_skip; int fec_skip;
float pcm[FARGAN_CONT_SAMPLES]; float pcm[PLC_BUF_SIZE];
int blend; int blend;
float features[NB_TOTAL_FEATURES]; float features[NB_TOTAL_FEATURES];
float cont_features[CONT_VECTORS*NB_FEATURES]; float cont_features[CONT_VECTORS*NB_FEATURES];
......
...@@ -678,6 +678,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, ...@@ -678,6 +678,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
init_frames = (st->lpcnet.blend == 0) ? 2 : 0; init_frames = (st->lpcnet.blend == 0) ? 2 : 0;
features_per_frame = IMAX(1, frame_size/F10); features_per_frame = IMAX(1, frame_size/F10);
needed_feature_frames = init_frames + features_per_frame; needed_feature_frames = init_frames + features_per_frame;
lpcnet_plc_fec_clear(&st->lpcnet);
for (i=0;i<needed_feature_frames;i++) { for (i=0;i<needed_feature_frames;i++) {
int feature_offset; int feature_offset;
/* We floor instead of rounding because 5-ms overlap compensates for the missing 0.5 rounding offset. */ /* We floor instead of rounding because 5-ms overlap compensates for the missing 0.5 rounding offset. */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment