Fixes a few issues with PLC-based mode switching
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Tue, 8 Mar 2011 04:53:53 +0000 (23:53 -0500)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Tue, 8 Mar 2011 04:53:53 +0000 (23:53 -0500)
src/opus_decoder.c
src/opus_encoder.c

index 6eb081c..13daf6a 100644 (file)
@@ -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;i<plc_length;i++)
                pcm[i] = pcm_transition[i];
 
-       overlap = IMIN(st->Fs/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
index 0150442..30dd4d4 100644 (file)
@@ -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));
         }