ref: bc2eebdf46a7de8b2927a0144dfd65bead6f1f15
parent: 0c5085ad2fe0f7c3fe8bcd5f3660b31983d87836
author: Jean-Marc Valin <[email protected]>
date: Tue Oct 4 07:59:32 EDT 2011
Fixes glithes when switching between SILK-only and hybrid We now reset the CELT state when swithing to hybrid and we "drain" the CELT MDCT overlap when switching away from hybrid.
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -390,11 +390,21 @@
if (mode != MODE_SILK_ONLY)
{
int celt_frame_size = IMIN(F20, frame_size);
+ /* Make sure to discard any previous CELT state */
+ if (st->prev_mode == MODE_SILK_ONLY)
+ celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
/* Decode CELT */
celt_ret = celt_decode_with_ec(celt_dec, decode_fec?NULL:data, len, pcm, celt_frame_size, &dec);
} else {
+ unsigned char silence[2] = {0xFF, 0xFF};
for (i=0;i<frame_size*st->channels;i++)
pcm[i] = 0;
+ /* For hybrid -> SILK transitions, we let the CELT MDCT do a fade-out by decoding a silence frame */
+ if (st->prev_mode == MODE_HYBRID)
+ {
+ celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
+ celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL);
+ }
}
if (mode != MODE_CELT_ONLY)
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -891,7 +891,7 @@
if (st->mode != MODE_HYBRID || st->stream_channels==1)
- st->silk_mode.stereoWidth_Q14 = 1<<14;
+ st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14 = 1<<14;
if( st->channels == 2 ) {
/* Apply stereo width reduction (at low bitrates) */
if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) {