Simplfies the condition for resetting the CELT state
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Wed, 19 Oct 2011 05:56:38 +0000 (01:56 -0400)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Wed, 19 Oct 2011 05:56:38 +0000 (01:56 -0400)
src/opus_decoder.c
src/opus_encoder.c

index 3f965bd..38672b1 100644 (file)
@@ -245,9 +245,10 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
 
     ALLOC(pcm_transition, F5*st->channels, opus_val16);
 
-    if (data!=NULL && !st->prev_redundancy && mode != st->prev_mode && st->prev_mode > 0
-               && !(mode == MODE_SILK_ONLY && st->prev_mode == MODE_HYBRID)
-               && !(mode == MODE_HYBRID && st->prev_mode == MODE_SILK_ONLY))
+    if (data!=NULL && st->prev_mode > 0 && (
+            (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy)
+         || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) )
+         )
     {
        transition = 1;
        if (mode == MODE_CELT_ONLY)
@@ -384,21 +385,17 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
         celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
         celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL);
         celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
-        celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
     }
 
     /* MUST be after PLC */
     celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));
 
-    if (transition)
-       celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
-
     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);
+        int celt_frame_size = IMIN(F20, frame_size);
+        /* Make sure to discard any previous CELT state */
+        if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)
+            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 {
@@ -478,7 +475,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
        st->rangeFinal = dec.rng ^ redundant_rng;
 
     st->prev_mode = mode;
-    st->prev_redundancy = redundancy;
+    st->prev_redundancy = redundancy && !celt_to_silk;
     RESTORE_STACK;
        return celt_ret<0 ? celt_ret : audiosize;
 
index d3b83ae..c1cb2cf 100644 (file)
@@ -852,17 +852,8 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
     {
         celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
         celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
-        if (st->prev_mode == MODE_SILK_ONLY)
-        {
-            unsigned char dummy[10];
-            celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
-            celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
-            celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
-            /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */
-            celt_encode_with_ec(celt_enc, &st->delay_buffer[(st->encoder_buffer-delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10, NULL);
-        } else {
-            celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(2));
-        }
+        /* Allow prediction unless we decide to disable it later */
+        celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(2));
 
         if (st->mode == MODE_HYBRID)
         {
@@ -894,7 +885,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
     }
 
     ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16);
-    if (redundancy && celt_to_silk && st->mode == MODE_HYBRID)
+    if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0)
     {
        for (i=0;i<st->channels*st->Fs/400;i++)
           tmp_prefill[i] = st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels + i];
@@ -978,25 +969,26 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
     /* 5 ms redundant frame for CELT->SILK */
     if (redundancy && celt_to_silk)
     {
-        unsigned char dummy[2];
         celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
         celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
         celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL);
         celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));
         celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
-
-        if (st->mode == MODE_HYBRID)
-        {
-           celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band));
-           celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL);
-           celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
-        }
     }
 
     celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band));
 
     if (st->mode != MODE_SILK_ONLY)
     {
+        if (st->mode != st->prev_mode && st->prev_mode > 0)
+        {
+           unsigned char dummy[2];
+           celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
+
+           /* Prefilling */
+           celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL);
+           celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
+        }
         ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
         if (ret < 0)
            return OPUS_INTERNAL_ERROR;
@@ -1005,6 +997,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
     /* 5 ms redundant frame for SILK->CELT */
     if (redundancy && !celt_to_silk)
     {
+        unsigned char dummy[2];
         int N2, N4;
         N2 = st->Fs/200;
         N4 = st->Fs/400;
@@ -1014,7 +1007,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
         celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
 
         /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */
-        celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes, NULL);
+        celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL);
 
         celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL);
         celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));