Improved transient_analysis() by adding one frame of memory.
[opus.git] / libcelt / celt.c
index d8a12a3..90c484d 100644 (file)
 #include <math.h>
 #include "celt.h"
 #include "pitch.h"
-#include "kiss_fftr.h"
 #include "bands.h"
 #include "modes.h"
 #include "entcode.h"
 #include "quant_bands.h"
-#include "psy.h"
 #include "rate.h"
 #include "stack_alloc.h"
 #include "mathops.h"
 #include "float_cast.h"
 #include <stdarg.h>
 
+#define LPC_ORDER 24
+/* #define NEW_PLC */
+#if !defined(FIXED_POINT) || defined(NEW_PLC)
+#include "plc.c"
+#endif
+
 static const celt_word16 preemph = QCONST16(0.8f,15);
 
 #ifdef FIXED_POINT
@@ -91,6 +95,7 @@ struct CELTEncoder {
    celt_word16 tonal_average;
    int fold_decision;
    celt_word16 gain_prod;
+   celt_word32 frame_max;
 
    /* VBR-related parameters */
    celt_int32 vbr_reservoir;
@@ -178,7 +183,7 @@ CELTEncoder *celt_encoder_create(const CELTMode *mode, int channels, int *error)
    st->pitch_available = 1;
    st->force_intra  = 0;
    st->delayedIntra = 1;
-   st->tonal_average = QCONST16(1.,8);
+   st->tonal_average = QCONST16(1.f,8);
    st->fold_decision = 1;
 
    st->in_mem = celt_alloc(st->overlap*C*sizeof(celt_sig));
@@ -231,7 +236,7 @@ void celt_encoder_destroy(CELTEncoder *st)
    
    celt_free(st->in_mem);
    celt_free(st->out_mem);
-   
+   celt_free(st->pitch_buf);
    celt_free(st->oldBandE);
    
    celt_free(st->preemph_memE);
@@ -262,48 +267,61 @@ static inline celt_word16 SIG2WORD16(celt_sig x)
 #endif
 }
 
-static int transient_analysis(celt_word32 *in, int len, int C, int *transient_time, int *transient_shift)
+static int transient_analysis(const celt_word32 * restrict in, int len, int C,
+                              int *transient_time, int *transient_shift,
+                              celt_word32 *frame_max)
 {
-   int c, i, n;
+   int i, n;
    celt_word32 ratio;
+   celt_word32 threshold;
    VARDECL(celt_word32, begin);
    SAVE_STACK;
-   ALLOC(begin, len, celt_word32);
-   for (i=0;i<len;i++)
-      begin[i] = ABS32(SHR32(in[C*i],SIG_SHIFT));
-   for (c=1;c<C;c++)
+   ALLOC(begin, len+1, celt_word32);
+   begin[0] = 0;
+   if (C==1)
    {
       for (i=0;i<len;i++)
-         begin[i] = MAX32(begin[i], ABS32(SHR32(in[C*i+c],SIG_SHIFT)));
+         begin[i+1] = MAX32(begin[i], ABS32(in[i]));
+   } else {
+      for (i=0;i<len;i++)
+         begin[i+1] = MAX32(begin[i], MAX32(ABS32(in[C*i]),
+                                            ABS32(in[C*i+1])));
    }
-   for (i=1;i<len;i++)
-      begin[i] = MAX32(begin[i-1],begin[i]);
    n = -1;
-   for (i=8;i<len-8;i++)
+
+   threshold = MULT16_32_Q15(QCONST16(.2f,15),begin[len]);
+   /* If the following condition isn't met, there's just no way
+      we'll have a transient*/
+   if (*frame_max < threshold)
    {
-      if (begin[i] < MULT16_32_Q15(QCONST16(.2f,15),begin[len-1]))
-         n=i;
+      /* It's likely we have a transient, now find it */
+      for (i=8;i<len-8;i++)
+      {
+         if (begin[i+1] < threshold)
+            n=i;
+      }
    }
    if (n<32)
    {
       n = -1;
       ratio = 0;
    } else {
-      ratio = DIV32(begin[len-1],1+begin[n-16]);
+      ratio = DIV32(begin[len],1+MAX32(*frame_max, begin[n-16]));
    }
    if (ratio < 0)
       ratio = 0;
    if (ratio > 1000)
       ratio = 1000;
    ratio *= ratio;
-   
+
    if (ratio > 2048)
       *transient_shift = 3;
    else
       *transient_shift = 0;
    
    *transient_time = n;
-   
+   *frame_max = begin[len];
+
    RESTORE_STACK;
    return ratio > 20;
 }
@@ -487,22 +505,28 @@ static void decode_flags(ec_dec *dec, int *intra_ener, int *has_pitch, int *shor
    /*printf ("dec %d: %d %d %d %d\n", flag_bits, *intra_ener, *has_pitch, *shortBlocks, *has_fold);*/
 }
 
-static void deemphasis(celt_sig *in, celt_word16 *pcm, int N, int _C, celt_word16 coef, celt_sig *mem)
+void deemphasis(celt_sig *in, celt_word16 *pcm, int N, int _C, celt_word16 coef, celt_sig *mem)
 {
    const int C = CHANNELS(_C);
    int c;
    for (c=0;c<C;c++)
    {
       int j;
+      celt_sig * restrict x;
+      celt_word16  * restrict y;
+      celt_sig m = mem[c];
+      x = &in[C*(MAX_PERIOD-N)+c];
+      y = pcm+c;
       for (j=0;j<N;j++)
       {
-         celt_sig tmp = MAC16_32_Q15(in[C*(MAX_PERIOD-N)+C*j+c],
-                                       coef,mem[c]);
-         mem[c] = tmp;
-         pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
+         celt_sig tmp = MAC16_32_Q15(*x, coef,m);
+         m = tmp;
+         *y = SCALEOUT(SIG2WORD16(tmp));
+         x+=C;
+         y+=C;
       }
+      mem[c] = m;
    }
-
 }
 
 static void mdct_shape(const CELTMode *mode, celt_norm *X, int start, int end, int N, int nbShortMdcts, int mdct_weight_shift, int _C)
@@ -551,11 +575,13 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig * pcm, celt_sig
    int shortBlocks=0;
    int transient_time;
    int transient_shift;
+   int resynth;
    const int C = CHANNELS(st->channels);
    int mdct_weight_shift = 0;
    int mdct_weight_pos=0;
    int gain_id=0;
    int norm_rate;
+   int start=0;
    SAVE_STACK;
 
    if (check_encoder(st) != CELT_OK)
@@ -599,7 +625,9 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig * pcm, celt_sig
    transient_shift = 0;
    shortBlocks = 0;
 
-   if (st->mode->nbShortMdcts > 1 && transient_analysis(in, N+st->overlap, C, &transient_time, &transient_shift))
+   resynth = st->pitch_available>0 || optional_synthesis!=NULL;
+
+   if (st->mode->nbShortMdcts > 1 && transient_analysis(in, N+st->overlap, C, &transient_time, &transient_shift, &st->frame_max))
    {
 #ifndef FIXED_POINT
       float gain_1;
@@ -644,11 +672,12 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig * pcm, celt_sig
             && norm_rate < 50;
    if (has_pitch)
    {
-      /* FIXME: Should probably do a stack save/pop here */
       VARDECL(celt_word16, x_lp);
+      SAVE_STACK;
       ALLOC(x_lp, (2*N-2*N4)>>1, celt_word16);
       pitch_downsample(in, x_lp, 2*N-2*N4, N, C, &st->xmem, &st->pitch_buf[MAX_PERIOD>>1]);
       pitch_search(st->mode, x_lp, st->pitch_buf, 2*N-2*N4, MAX_PERIOD-(2*N-2*N4), &pitch_index, &st->xmem);
+      RESTORE_STACK;
    }
 
    /* Deferred allocation after find_spectral_pitch() to reduce 
@@ -769,7 +798,7 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig * pcm, celt_sig
 
    /* Bit allocation */
    ALLOC(error, C*st->mode->nbEBands, celt_word16);
-   coarse_needed = quant_coarse_energy(st->mode, bandLogE, st->oldBandE, nbCompressedBytes*4-8, intra_ener, st->mode->prob, error, &enc, C);
+   coarse_needed = quant_coarse_energy(st->mode, start, bandLogE, st->oldBandE, nbCompressedBytes*4-8, intra_ener, st->mode->prob, error, &enc, C);
    coarse_needed = ((coarse_needed*3-1)>>3)+1;
    if (coarse_needed > nbCompressedBytes)
       coarse_needed = nbCompressedBytes;
@@ -836,22 +865,22 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig * pcm, celt_sig
    for (i=0;i<st->mode->nbEBands;i++)
       offsets[i] = 0;
    bits = nbCompressedBytes*8 - ec_enc_tell(&enc, 0) - 1;
-   compute_allocation(st->mode, offsets, bits, pulses, fine_quant, fine_priority, C);
+   compute_allocation(st->mode, start, offsets, bits, pulses, fine_quant, fine_priority, C);
 
-   quant_fine_energy(st->mode, bandE, st->oldBandE, error, fine_quant, &enc, C);
+   quant_fine_energy(st->mode, start, bandE, st->oldBandE, error, fine_quant, &enc, C);
 
    /* Residual quantisation */
    if (C==1)
-      quant_bands(st->mode, X, bandE, pulses, shortBlocks, has_fold, nbCompressedBytes*8, 1, &enc);
+      quant_bands(st->mode, start, X, bandE, pulses, shortBlocks, has_fold, resynth, nbCompressedBytes*8, 1, &enc);
 #ifndef DISABLE_STEREO
    else
-      quant_bands_stereo(st->mode, X, bandE, pulses, shortBlocks, has_fold, nbCompressedBytes*8, &enc);
+      quant_bands_stereo(st->mode, start, X, bandE, pulses, shortBlocks, has_fold, resynth, nbCompressedBytes*8, &enc);
 #endif
 
-   quant_energy_finalise(st->mode, bandE, st->oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(&enc, 0), &enc, C);
+   quant_energy_finalise(st->mode, start, bandE, st->oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(&enc, 0), &enc, C);
 
    /* Re-synthesis of the coded audio if required */
-   if (st->pitch_available>0 || optional_synthesis!=NULL)
+   if (resynth)
    {
       if (st->pitch_available>0 && st->pitch_available<MAX_PERIOD)
         st->pitch_available+=st->frame_size;
@@ -1035,6 +1064,17 @@ int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
          CELT_MEMSET(st->preemph_memE, 0, C);
          CELT_MEMSET(st->preemph_memD, 0, C);
          st->delayedIntra = 1;
+
+         st->fold_decision = 1;
+         st->tonal_average = QCONST16(1.f,8);
+         st->gain_prod = 0;
+         st->vbr_reservoir = 0;
+         st->vbr_drift = 0;
+         st->vbr_offset = 0;
+         st->vbr_count = 0;
+         st->xmem = 0;
+         st->frame_max = 0;
+         CELT_MEMSET(st->pitch_buf, 0, (MAX_PERIOD>>1)+2);
       }
       break;
       default:
@@ -1089,6 +1129,10 @@ struct CELTDecoder {
 
    celt_word16 *oldBandE;
    
+#ifdef NEW_PLC
+   celt_word16 *lpc;
+#endif
+
    int last_pitch_index;
    int loss_count;
 };
@@ -1163,9 +1207,16 @@ CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error)
    
    st->preemph_memD = (celt_sig*)celt_alloc(C*sizeof(celt_sig));
 
+#ifdef NEW_PLC
+   st->lpc = (celt_word16*)celt_alloc(C*LPC_ORDER*sizeof(celt_word16));
+#endif
+
    st->loss_count = 0;
 
    if ((st->decode_mem!=NULL) && (st->out_mem!=NULL) && (st->oldBandE!=NULL) &&
+#ifdef NEW_PLC
+         (st->lpc!=NULL) &&
+#endif
        (st->preemph_memD!=NULL))
    {
       if (error)
@@ -1208,22 +1259,21 @@ void celt_decoder_destroy(CELTDecoder *st)
    celt_free(st->decode_mem);
    celt_free(st->oldBandE);
    celt_free(st->preemph_memD);
+
+#ifdef NEW_PLC
+   celt_free(st->lpc);
+#endif
    
    st->marker = DECODERFREED;
    
    celt_free(st);
 }
 
-/** Handles lost packets by just copying past data with the same
-    offset as the last
-    pitch period */
-#ifdef NEW_PLC
-#include "plc.c"
-#else
 static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict pcm)
 {
    int c, N;
    int pitch_index;
+   int overlap = st->mode->overlap;
    celt_word16 fade = Q15ONE;
    int i, len;
    VARDECL(celt_sig, freq);
@@ -1231,7 +1281,6 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
    int offset;
    SAVE_STACK;
    N = st->block_size;
-   ALLOC(freq,C*N, celt_sig); /**< Interleaved signal MDCTs */
    
    len = N+st->mode->overlap;
    
@@ -1241,10 +1290,10 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
       celt_word32 tmp=0;
       celt_word32 mem0[2]={0,0};
       celt_word16 mem1[2]={0,0};
-      /*find_spectral_pitch(st->mode, st->mode->fft, &st->mode->psy, st->out_mem+MAX_PERIOD-len, st->out_mem, st->mode->window, NULL, len, MAX_PERIOD-len-100, &pitch_index, C);*/
-      /* FIXME: Should do a bit of interpolation while decimating */
-      pitch_downsample(st->out_mem, pitch_buf, MAX_PERIOD, MAX_PERIOD, C, mem0, mem1);
-      pitch_search(st->mode, pitch_buf+((MAX_PERIOD-len)>>1), pitch_buf, len, MAX_PERIOD-len-100, &pitch_index, &tmp);
+      pitch_downsample(st->out_mem, pitch_buf, MAX_PERIOD, MAX_PERIOD,
+                       C, mem0, mem1);
+      pitch_search(st->mode, pitch_buf+((MAX_PERIOD-len)>>1), pitch_buf, len,
+                   MAX_PERIOD-len-100, &pitch_index, &tmp);
       pitch_index = MAX_PERIOD-len-pitch_index;
       st->last_pitch_index = pitch_index;
    } else {
@@ -1255,7 +1304,9 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
          fade = 0;
    }
 
+#ifndef NEW_PLC
    offset = MAX_PERIOD-pitch_index;
+   ALLOC(freq,C*N, celt_sig); /**< Interleaved signal MDCTs */
    while (offset+len >= MAX_PERIOD)
       offset -= pitch_index;
    compute_mdcts(st->mode, 0, st->out_mem+offset*C, freq, C);
@@ -1265,24 +1316,117 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
    CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->mode->overlap-N));
    /* Compute inverse MDCTs */
    compute_inv_mdcts(st->mode, 0, freq, -1, 0, st->out_mem, C);
-
+#else
    for (c=0;c<C;c++)
    {
-      int j;
-      for (j=0;j<N;j++)
+      celt_word32 e[MAX_PERIOD];
+      celt_word16 exc[MAX_PERIOD];
+      float ac[LPC_ORDER+1];
+      float decay = 1;
+      float S1=0;
+      celt_word16 mem[LPC_ORDER]={0};
+
+      offset = MAX_PERIOD-pitch_index;
+      for (i=0;i<MAX_PERIOD;i++)
+         exc[i] = ROUND16(st->out_mem[i*C+c], SIG_SHIFT);
+
+      if (st->loss_count == 0)
+      {
+         _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
+                        LPC_ORDER, MAX_PERIOD);
+
+         /* Noise floor -50 dB */
+         ac[0] *= 1.00001;
+         /* Lag windowing */
+         for (i=1;i<=LPC_ORDER;i++)
+         {
+            /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
+            ac[i] -= ac[i]*(.008*i)*(.008*i);
+         }
+
+         _celt_lpc(st->lpc+c*LPC_ORDER, ac, LPC_ORDER);
+      }
+      fir(exc, st->lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
+      /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
+      /* Check if the waveform is decaying (and if so how fast) */
       {
-         celt_sig tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
-                                preemph,st->preemph_memD[c]);
-         st->preemph_memD[c] = tmp;
-         pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
+         float E1=0, E2=0;
+         int period;
+         if (pitch_index <= MAX_PERIOD/2)
+            period = pitch_index;
+         else
+            period = MAX_PERIOD/2;
+         for (i=0;i<period;i++)
+         {
+            E1 += exc[MAX_PERIOD-period+i]*exc[MAX_PERIOD-period+i];
+            E2 += exc[MAX_PERIOD-2*period+i]*exc[MAX_PERIOD-2*period+i];
+         }
+         decay = sqrt((E1+1)/(E2+1));
+         if (decay > 1)
+            decay = 1;
       }
+
+      /* Copy excitation, taking decay into account */
+      for (i=0;i<len+st->mode->overlap;i++)
+      {
+         if (offset+i >= MAX_PERIOD)
+         {
+            offset -= pitch_index;
+            decay *= decay;
+         }
+         e[i] = decay*SHL32(EXTEND32(exc[offset+i]), SIG_SHIFT);
+         S1 += st->out_mem[offset+i]*1.*st->out_mem[offset+i];
+      }
+
+      iir(e, st->lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
+
+      {
+         float S2=0;
+         for (i=0;i<len+overlap;i++)
+            S2 += e[i]*1.*e[i];
+         /* This checks for an "explosion" in the synthesis (including NaNs) */
+         if (!(S1 > 0.2f*S2))
+         {
+            for (i=0;i<len+overlap;i++)
+               e[i] = 0;
+         } else if (S1 < S2)
+         {
+            float ratio = sqrt((S1+1)/(S2+1));
+            for (i=0;i<len+overlap;i++)
+               e[i] *= ratio;
+         }
+      }
+
+      for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
+         st->out_mem[C*i+c] = st->out_mem[C*(N+i)+c];
+
+      /* Apply TDAC to the concealed audio so that it blends with the
+         previous and next frames */
+      for (i=0;i<overlap/2;i++)
+      {
+         celt_word32 tmp1, tmp2;
+         tmp1 = MULT16_32_Q15(st->mode->window[i          ], e[i          ]) -
+                MULT16_32_Q15(st->mode->window[overlap-i-1], e[overlap-i-1]);
+         tmp2 = MULT16_32_Q15(st->mode->window[i],           e[N+overlap-1-i]) +
+                MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i          ]);
+         tmp1 = MULT16_32_Q15(fade, tmp1);
+         tmp2 = MULT16_32_Q15(fade, tmp2);
+         st->out_mem[C*(MAX_PERIOD+i)+c] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp2);
+         st->out_mem[C*(MAX_PERIOD+overlap-i-1)+c] = MULT16_32_Q15(st->mode->window[i], tmp2);
+         st->out_mem[C*(MAX_PERIOD-N+i)+c] += MULT16_32_Q15(st->mode->window[i], tmp1);
+         st->out_mem[C*(MAX_PERIOD-N+overlap-i-1)+c] -= MULT16_32_Q15(st->mode->window[overlap-i-1], tmp1);
+      }
+      for (i=0;i<N-overlap;i++)
+         st->out_mem[C*(MAX_PERIOD-N+overlap+i)+c] = MULT16_32_Q15(fade, e[overlap+i]);
    }
+#endif
+
+   deemphasis(st->out_mem, pcm, N, C, preemph, st->preemph_memD);
    
    st->loss_count++;
 
    RESTORE_STACK;
 }
-#endif
 
 #ifdef FIXED_POINT
 int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16 * restrict pcm)
@@ -1314,6 +1458,7 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int
    const int C = CHANNELS(st->channels);
    int mdct_weight_pos=0;
    int gain_id=0;
+   int start=0;
    SAVE_STACK;
 
    if (check_decoder(st) != CELT_OK)
@@ -1337,8 +1482,6 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int
       celt_decode_lost(st, pcm);
       RESTORE_STACK;
       return 0;
-   } else {
-      st->loss_count = 0;
    }
    if (len<0) {
      RESTORE_STACK;
@@ -1377,7 +1520,7 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int
 
    ALLOC(fine_quant, st->mode->nbEBands, int);
    /* Get band energies */
-   unquant_coarse_energy(st->mode, bandE, st->oldBandE, len*4-8, intra_ener, st->mode->prob, &dec, C);
+   unquant_coarse_energy(st->mode, start, bandE, st->oldBandE, len*4-8, intra_ener, st->mode->prob, &dec, C);
    
    ALLOC(pulses, st->mode->nbEBands, int);
    ALLOC(offsets, st->mode->nbEBands, int);
@@ -1387,11 +1530,11 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int
       offsets[i] = 0;
 
    bits = len*8 - ec_dec_tell(&dec, 0) - 1;
-   compute_allocation(st->mode, offsets, bits, pulses, fine_quant, fine_priority, C);
+   compute_allocation(st->mode, start, offsets, bits, pulses, fine_quant, fine_priority, C);
    /*bits = ec_dec_tell(&dec, 0);
    compute_fine_allocation(st->mode, fine_quant, (20*C+len*8/5-(ec_dec_tell(&dec, 0)-bits))/C);*/
    
-   unquant_fine_energy(st->mode, bandE, st->oldBandE, fine_quant, &dec, C);
+   unquant_fine_energy(st->mode, start, bandE, st->oldBandE, fine_quant, &dec, C);
 
    ALLOC(pitch_freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
    if (has_pitch) 
@@ -1402,12 +1545,12 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int
 
    /* Decode fixed codebook and merge with pitch */
    if (C==1)
-      quant_bands(st->mode, X, bandE, pulses, shortBlocks, has_fold, len*8, 0, &dec);
+      quant_bands(st->mode, start, X, bandE, pulses, shortBlocks, has_fold, 1, len*8, 0, &dec);
 #ifndef DISABLE_STEREO
    else
-      unquant_bands_stereo(st->mode, X, bandE, pulses, shortBlocks, has_fold, len*8, &dec);
+      unquant_bands_stereo(st->mode, start, X, bandE, pulses, shortBlocks, has_fold, len*8, &dec);
 #endif
-   unquant_energy_finalise(st->mode, bandE, st->oldBandE, fine_quant, fine_priority, len*8-ec_dec_tell(&dec, 0), &dec, C);
+   unquant_energy_finalise(st->mode, start, bandE, st->oldBandE, fine_quant, fine_priority, len*8-ec_dec_tell(&dec, 0), &dec, C);
    
    if (mdct_weight_shift)
    {
@@ -1423,11 +1566,14 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int
    if (has_pitch)
       apply_pitch(st->mode, freq, pitch_freq, gain_id, 0, C);
 
+   for (i=0;i<st->mode->eBands[start];i++)
+      freq[i] = 0;
+
    /* Compute inverse MDCTs */
    compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem, C);
 
    deemphasis(st->out_mem, pcm, N, C, preemph, st->preemph_memD);
-
+   st->loss_count = 0;
    RESTORE_STACK;
    return 0;
 }
@@ -1522,6 +1668,10 @@ int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
          CELT_MEMSET(st->preemph_memD, 0, C);
 
          st->loss_count = 0;
+
+#ifdef NEW_PLC
+         CELT_MEMSET(st->lpc, 0, C*LPC_ORDER);
+#endif
       }
       break;
       default: