From 1b16fec48451f12ad9ca6f2565b710e159e99791 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Mon, 7 Mar 2011 23:53:53 -0500 Subject: [PATCH] Fixes a few issues with PLC-based mode switching --- src/opus_decoder.c | 9 +++------ src/opus_encoder.c | 14 ++++++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/opus_decoder.c b/src/opus_decoder.c index 6eb081cc..13daf6a4 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -152,7 +152,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, } if (audiosize > frame_size) { - fprintf(stderr, "PCM buffer too small"); + fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode); return -1; } else { frame_size = audiosize; @@ -302,14 +302,11 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, if (transition) { int plc_length, overlap; - if (mode == MODE_CELT_ONLY) - plc_length = IMIN(audiosize, 10+st->Fs/200); - else - plc_length = IMIN(audiosize, 10+st->Fs/400); + plc_length = IMIN(audiosize, 10+st->Fs/400); for (i=0;iFs/100, IMAX(0, audiosize-plc_length)); + overlap = IMIN(st->Fs/400, IMAX(0, audiosize-plc_length)); smooth_fade(pcm_transition+plc_length, pcm+plc_length, pcm+plc_length, overlap, st->channels); } #if OPUS_TEST_RANGE_CODER_STATE diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 01504420..30dd4d4f 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -124,8 +124,14 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, celt_to_silk = (st->mode != MODE_CELT_ONLY); if (!celt_to_silk) { - st->mode = st->prev_mode; - to_celt = 1; + /* Switch to SILK/hybrid if frame size is 10 ms or more*/ + if (frame_size >= st->Fs/100) + { + st->mode = st->prev_mode; + to_celt = 1; + } else { + redundancy=0; + } } } @@ -230,12 +236,12 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(510000)); if (st->prev_mode == MODE_SILK_ONLY) { - unsigned char dummy[2]; + unsigned char dummy[10]; celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE); celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0)); celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0)); /* FIXME: This wastes CPU a bit compared to just prefilling the buffer */ - celt_encode(st->celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-120)*st->channels], 120, dummy, 10); + celt_encode(st->celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10); } else { celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(2)); }