shithub: opus

Download patch

ref: 8952c45ea54a5608cd61fe2e137e39d0c3b19853
parent: 85f41b20df8559dc85780201603352eb66489df5
author: Jean-Marc Valin <[email protected]>
date: Fri Jul 16 17:48:44 EDT 2010

The encoder and decoder can now process audio encoded at a higher rate
than what they're running at.

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -902,7 +902,7 @@
    M = 1<<LM;
    B = shortBlocks ? M : 1;
    spread = fold ? B : 0;
-   ALLOC(_norm, M*eBands[m->nbEBands+1], celt_norm);
+   ALLOC(_norm, M*eBands[m->nbEBands], celt_norm);
    norm = _norm;
 
    balance = 0;
@@ -949,6 +949,12 @@
          lowband = NULL;
 
       tf_change = tf_res[i];
+      if (i>=m->effEBands)
+      {
+         X=norm;
+         if (_Y!=NULL)
+            Y = norm;
+      }
       quant_band(encode, m, i, X, Y, N, b, spread, tf_change, lowband, resynth, ec, &remaining_bits, LM, norm+M*eBands[i], bandE, 0);
 
       balance += pulses[i] + tell;
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -158,9 +158,7 @@
    st->channels = channels;
 
    st->start = 0;
-   st->end = st->mode->nbEBands;
-   while (st->mode->eBands[st->end] > st->mode->shortMdctSize)
-      st->end--;
+   st->end = st->mode->effEBands;
 
    st->vbr_rate_norm = 0;
    st->pitch_enabled = 1;
@@ -1059,8 +1057,7 @@
    quant_fine_energy(st->mode, st->start, st->end, bandE, st->oldBandE, error, fine_quant, enc, C);
 
    /* Residual quantisation */
-   /* FIXME: we can't just stop at effEnd because we'll have an allocation mismatch */
-   quant_all_bands(1, st->mode, st->start, effEnd, X, C==2 ? X+N : NULL, bandE, pulses, shortBlocks, has_fold, tf_res, resynth, nbCompressedBytes*8, enc, LM);
+   quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, bandE, pulses, shortBlocks, has_fold, tf_res, resynth, nbCompressedBytes*8, enc, LM);
 
    quant_energy_finalise(st->mode, st->start, st->end, bandE, st->oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
 
@@ -1435,9 +1432,7 @@
    st->channels = channels;
 
    st->start = 0;
-   st->end = st->mode->nbEBands;
-   while (st->mode->eBands[st->end] > st->mode->shortMdctSize)
-      st->end--;
+   st->end = st->mode->effEBands;
 
    st->decode_mem = (celt_sig*)celt_alloc((DECODE_BUFFER_SIZE+st->overlap)*C*sizeof(celt_sig));
    st->out_mem = st->decode_mem+DECODE_BUFFER_SIZE-MAX_PERIOD;
@@ -1827,8 +1822,7 @@
    }
 
    /* Decode fixed codebook and merge with pitch */
-   /* FIXME: we can't just stop at effEnd because we'll have an allocation mismatch */
-   quant_all_bands(0, st->mode, st->start, effEnd, X, C==2 ? X+N : NULL, NULL, pulses, shortBlocks, has_fold, tf_res, 1, len*8, dec, LM);
+   quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, NULL, pulses, shortBlocks, has_fold, tf_res, 1, len*8, dec, LM);
 
    unquant_energy_finalise(st->mode, st->start, st->end, bandE, st->oldBandE, fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
 
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -123,10 +123,9 @@
    if (Fs == 400*(celt_int32)frame_size)
    {
       *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
-      eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+2));
-      for (i=0;i<*nbEBands+2;i++)
+      eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+1));
+      for (i=0;i<*nbEBands+1;i++)
          eBands[i] = eband5ms[i];
-      eBands[*nbEBands+1] = frame_size;
       return eBands;
    }
    /* Find the number of critical bands supported by our sampling rate */
@@ -164,9 +163,8 @@
       if (eBands[i] < i)
          eBands[i] = i;
    eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res;
-   eBands[*nbEBands+1] = frame_size;
-   if (eBands[*nbEBands] > eBands[*nbEBands+1])
-      eBands[*nbEBands] = eBands[*nbEBands+1];
+   if (eBands[*nbEBands] > frame_size)
+      eBands[*nbEBands] = frame_size;
    for (i=1;i<*nbEBands-1;i++)
    {
       if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
@@ -235,7 +233,8 @@
             /* Move to next eband */
             current = 0;
             eband++;
-            edge = mode->eBands[eband+1]*res;
+            if (eband < mode->nbEBands)
+               edge = mode->eBands[eband+1]*res;
          }
          current += alloc;
       }