shithub: opus

Download patch

ref: 9ce95e0bd0877df44230dcef2456e9c504ecadf5
parent: 72a554775facd90985235d2c0505d1a1ff9ddbd8
author: Jean-Marc Valin <[email protected]>
date: Tue Jan 25 14:12:06 EST 2011

anti-collapse tuning

Using the min energy of the two last non-transient frames rather
than the min of just the two last frames. Also slightly increasing
the "thresh" upper bound coefficient to 0.5.

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -231,7 +231,7 @@
       depth = (1+pulses[i])/(m->eBands[i+1]-m->eBands[i]<<LM);
 
 #ifdef FIXED_POINT
-      thresh = MULT16_32_Q15(QCONST16(0.3f, 15), MIN32(32767,SHR32(celt_exp2(-SHL16(depth, 11-BITRES)),1) ));
+      thresh = MULT16_32_Q15(QCONST16(0.5f, 15), MIN32(32767,SHR32(celt_exp2(-SHL16(depth, 11-BITRES)),1) ));
       {
          celt_word32 t;
          t = N0<<LM;
@@ -240,7 +240,7 @@
          sqrt_1 = celt_rsqrt_norm(t);
       }
 #else
-      thresh = .3f*celt_exp2(-.125f*depth);
+      thresh = .5f*celt_exp2(-.125f*depth);
       sqrt_1 = celt_rsqrt(N0<<LM);
 #endif
 
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -124,7 +124,7 @@
    int size = sizeof(struct CELTEncoder)
          + (2*channels*mode->overlap-1)*sizeof(celt_sig)
          + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig)
-         + 2*channels*mode->nbEBands*sizeof(celt_word16);
+         + 3*channels*mode->nbEBands*sizeof(celt_word16);
    return size;
 }
 
@@ -787,7 +787,6 @@
    VARDECL(celt_norm, X);
    VARDECL(celt_ener, bandE);
    VARDECL(celt_word16, bandLogE);
-   VARDECL(celt_word16, oldLogE);
    VARDECL(int, fine_quant);
    VARDECL(celt_word16, error);
    VARDECL(int, pulses);
@@ -797,7 +796,7 @@
    VARDECL(unsigned char, collapse_masks);
    celt_sig *_overlap_mem;
    celt_sig *prefilter_mem;
-   celt_word16 *oldBandE, *oldLogE2;
+   celt_word16 *oldBandE, *oldLogE, *oldLogE2;
    int shortBlocks=0;
    int isTransient=0;
    int resynth;
@@ -840,7 +839,8 @@
    _overlap_mem = prefilter_mem+C*COMBFILTER_MAXPERIOD;
    /*_overlap_mem = st->in_mem+C*(st->overlap);*/
    oldBandE = (celt_word16*)(st->in_mem+C*(2*st->overlap+COMBFILTER_MAXPERIOD));
-   oldLogE2 = oldBandE + C*st->mode->nbEBands;
+   oldLogE = oldBandE + C*st->mode->nbEBands;
+   oldLogE2 = oldLogE + C*st->mode->nbEBands;
 
    if (enc==NULL)
    {
@@ -1067,9 +1067,6 @@
    for (i=effEnd;i<st->end;i++)
       tf_res[i] = tf_res[effEnd-1];
 
-   ALLOC(oldLogE, C*st->mode->nbEBands, celt_word16);
-   for (i=0;i<C*st->mode->nbEBands;i++)
-      oldLogE[i] = oldBandE[i];
    ALLOC(error, C*st->mode->nbEBands, celt_word16);
    quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE,
          oldBandE, total_bits, error, enc,
@@ -1387,8 +1384,13 @@
       for (i=st->end;i<st->mode->nbEBands;i++)
          oldBandE[c*st->mode->nbEBands+i]=0;
    } while (++c<C);
-   for (i=0;i<C*st->mode->nbEBands;i++)
-      oldLogE2[i] = oldLogE[i];
+   if (!isTransient)
+   {
+      for (i=0;i<C*st->mode->nbEBands;i++)
+         oldLogE2[i] = oldLogE[i];
+      for (i=0;i<C*st->mode->nbEBands;i++)
+         oldLogE[i] = oldBandE[i];
+   }
    if (isTransient)
       st->consec_transient++;
    else
@@ -1621,6 +1623,7 @@
    celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
    /* celt_word16 lpc[],  Size = channels*LPC_ORDER */
    /* celt_word16 oldEBands[], Size = channels*mode->nbEBands */
+   /* celt_word16 oldLogE[], Size = channels*mode->nbEBands */
    /* celt_word16 oldLogE2[], Size = channels*mode->nbEBands */
    /* celt_word16 backgroundLogE[], Size = channels*mode->nbEBands */
 };
@@ -1630,7 +1633,7 @@
    int size = sizeof(struct CELTDecoder)
             + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
             + channels*LPC_ORDER*sizeof(celt_word16)
-            + 3*channels*mode->nbEBands*sizeof(celt_word16);
+            + 4*channels*mode->nbEBands*sizeof(celt_word16);
    return size;
 }
 
@@ -1917,7 +1920,6 @@
    VARDECL(celt_sig, freq);
    VARDECL(celt_norm, X);
    VARDECL(celt_ener, bandE);
-   VARDECL(celt_word16, oldLogE);
    VARDECL(int, fine_quant);
    VARDECL(int, pulses);
    VARDECL(int, offsets);
@@ -1929,7 +1931,7 @@
    celt_sig *overlap_mem[2];
    celt_sig *out_syn[2];
    celt_word16 *lpc;
-   celt_word16 *oldBandE, *oldLogE2, *backgroundLogE;
+   celt_word16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
 
    int shortBlocks;
    int isTransient;
@@ -1968,7 +1970,8 @@
    } while (++c<C);
    lpc = (celt_word16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
    oldBandE = lpc+C*LPC_ORDER;
-   oldLogE2 = oldBandE + C*st->mode->nbEBands;
+   oldLogE = oldBandE + C*st->mode->nbEBands;
+   oldLogE2 = oldLogE + C*st->mode->nbEBands;
    backgroundLogE = oldLogE2  + C*st->mode->nbEBands;
 
    N = M*st->mode->shortMdctSize;
@@ -2045,10 +2048,6 @@
    else
       shortBlocks = 0;
 
-   ALLOC(oldLogE, C*st->mode->nbEBands, celt_word16);
-   for (i=0;i<C*st->mode->nbEBands;i++)
-      oldLogE[i] = oldBandE[i];
-
    /* Decode the global flags (first symbols in the stream) */
    intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;
    /* Get band energies */
@@ -2189,11 +2188,15 @@
       for (i=st->end;i<st->mode->nbEBands;i++)
          oldBandE[c*st->mode->nbEBands+i]=0;
    } while (++c<C);
-   for (i=0;i<C*st->mode->nbEBands;i++)
-      oldLogE2[i] = oldLogE[i];
-   for (i=0;i<C*st->mode->nbEBands;i++)
-      backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldLogE[i]);
-
+   if (!isTransient)
+   {
+      for (i=0;i<C*st->mode->nbEBands;i++)
+         oldLogE2[i] = oldLogE[i];
+      for (i=0;i<C*st->mode->nbEBands;i++)
+         oldLogE[i] = oldBandE[i];
+      for (i=0;i<C*st->mode->nbEBands;i++)
+         backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]);
+   }
    st->rng = dec->rng;
 
    deemphasis(out_syn, pcm, N, C, st->mode->preemph, st->preemph_memD);