From c99054dad9053ff7dc30cf0379d8aeb240b2e171 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jmvalin@amazon.com> Date: Fri, 27 Oct 2023 01:29:56 -0400 Subject: [PATCH] Fix CELT deep PLC bugs The sinc filter offset was incorrectly handled. Since it perfectly compensates for the analysis offset, nothing has to be done. Also, the preemphasis memory was never initialized. --- celt/celt_decoder.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/celt/celt_decoder.c b/celt/celt_decoder.c index f2d480282..c0c997f0a 100644 --- a/celt/celt_decoder.c +++ b/celt/celt_decoder.c @@ -568,7 +568,7 @@ static const float sinc_filter[SINC_ORDER+1] = { 4.2931e-05f }; -void update_plc_state(LPCNetPLCState *lpcnet, celt_sig *decode_mem[2], int CC) +void update_plc_state(LPCNetPLCState *lpcnet, celt_sig *decode_mem[2], float *plc_preemphasis_mem, int CC) { int i; int tmp_read_post, tmp_fec_skip; @@ -583,6 +583,7 @@ void update_plc_state(LPCNetPLCState *lpcnet, celt_sig *decode_mem[2], int CC) } /* Down-sample the last 40 ms. */ for (i=1;i<DECODE_BUFFER_SIZE;i++) buf48k[i] += PREEMPHASIS*buf48k[i-1]; + *plc_preemphasis_mem = buf48k[DECODE_BUFFER_SIZE-1]; offset = DECODE_BUFFER_SIZE-SINC_ORDER-1 - 3*(PLC_UPDATE_SAMPLES-1); celt_assert(3*(PLC_UPDATE_SAMPLES-1) + SINC_ORDER + offset == DECODE_BUFFER_SIZE-1); for (i=0;i<PLC_UPDATE_SAMPLES;i++) { @@ -720,7 +721,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM if (loss_duration == 0) { #ifdef ENABLE_DEEP_PLC - update_plc_state(lpcnet, decode_mem, C); + update_plc_state(lpcnet, decode_mem, &st->plc_preemphasis_mem, C); #endif st->last_pitch_index = pitch_index = celt_plc_pitch_search(decode_mem, C, st->arch); } else { @@ -916,7 +917,6 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM if (st->complexity >= 5 || lpcnet->fec_fill_pos > 0) { float overlap_mem; int samples_needed16k; - int ignored = 0; celt_sig *buf; VARDECL(float, buf_copy); buf = decode_mem[0]; @@ -929,9 +929,6 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM and the overlap at the end. */ samples_needed16k = (N+SINC_ORDER+overlap)/3; if (loss_duration == 0) { - /* Ignore the first 8 samples due to the update resampling delay. */ - ignored = SINC_ORDER/6; - samples_needed16k += ignored; st->plc_fill = 0; } while (st->plc_fill < samples_needed16k) { @@ -942,15 +939,15 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM for (i=0;i<(N+overlap)/3;i++) { int j; float sum; - for (sum=0, j=0;j<17;j++) sum += 3*st->plc_pcm[ignored+i+j]*sinc_filter[3*j]; + for (sum=0, j=0;j<17;j++) sum += 3*st->plc_pcm[i+j]*sinc_filter[3*j]; buf[DECODE_BUFFER_SIZE-N+3*i] = sum; - for (sum=0, j=0;j<16;j++) sum += 3*st->plc_pcm[ignored+i+j+1]*sinc_filter[3*j+2]; + for (sum=0, j=0;j<16;j++) sum += 3*st->plc_pcm[i+j+1]*sinc_filter[3*j+2]; buf[DECODE_BUFFER_SIZE-N+3*i+1] = sum; - for (sum=0, j=0;j<16;j++) sum += 3*st->plc_pcm[ignored+i+j+1]*sinc_filter[3*j+1]; + for (sum=0, j=0;j<16;j++) sum += 3*st->plc_pcm[i+j+1]*sinc_filter[3*j+1]; buf[DECODE_BUFFER_SIZE-N+3*i+1] = sum; } - OPUS_MOVE(st->plc_pcm, &st->plc_pcm[N/3+ignored], st->plc_fill-N/3-ignored); - st->plc_fill -= N/3+ignored; + OPUS_MOVE(st->plc_pcm, &st->plc_pcm[N/3], st->plc_fill-N/3); + st->plc_fill -= N/3; for (i=0;i<N;i++) { float tmp = buf[DECODE_BUFFER_SIZE-N+i]; buf[DECODE_BUFFER_SIZE-N+i] -= PREEMPHASIS*st->plc_preemphasis_mem; -- GitLab