shithub: opus

Download patch

ref: 4f177e8510a24131c137d181af8d81b6ec9edcf5
parent: fb031119d39fbb9bb94f5f1d0bb7fac946f71c7a
author: Jean-Marc Valin <[email protected]>
date: Fri Nov 26 05:32:03 EST 2010

Intensity stereo now in the bit-stream

Bands that are intensity-coded also get less bits than the others

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -476,7 +476,7 @@
    in two and transmit the energy difference with the two half-bands. It
    can be called recursively so bands can end up being split in 8 parts. */
 static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_norm *Y,
-      int N, int b, int spread, int B, int tf_change, celt_norm *lowband, int resynth, void *ec,
+      int N, int b, int spread, int B, int intensity, int tf_change, celt_norm *lowband, int resynth, void *ec,
       celt_int32 *remaining_bits, int LM, celt_norm *lowband_out, const celt_ener *bandE, int level,
       celt_int32 *seed, celt_word16 gain, celt_norm *lowband_scratch)
 {
@@ -601,7 +601,7 @@
       offset = ((m->logN[i]+(LM<<BITRES))>>1) - (stereo ? QTHETA_OFFSET_STEREO : QTHETA_OFFSET);
       qn = compute_qn(N, b, offset, stereo);
       qalloc = 0;
-      if (stereo && b<12*N && i>=9)
+      if (stereo && i>=intensity)
          qn = 1;
       if (qn!=1)
       {
@@ -745,7 +745,7 @@
             }
          }
          sign = 2*sign - 1;
-         quant_band(encode, m, i, x2, NULL, N, mbits, spread, B, tf_change, lowband, resynth, ec, remaining_bits, LM, lowband_out, NULL, level, seed, gain, lowband_scratch);
+         quant_band(encode, m, i, x2, NULL, N, mbits, spread, B, intensity, tf_change, lowband, resynth, ec, remaining_bits, LM, lowband_out, NULL, level, seed, gain, lowband_scratch);
          y2[0] = -sign*x2[1];
          y2[1] = sign*x2[0];
          if (resynth)
@@ -790,10 +790,10 @@
          else
             next_level = level+1;
 
-         quant_band(encode, m, i, X, NULL, N, mbits, spread, B, tf_change,
+         quant_band(encode, m, i, X, NULL, N, mbits, spread, B, intensity, tf_change,
                lowband, resynth, ec, remaining_bits, LM, next_lowband_out1,
                NULL, next_level, seed, MULT16_16_P15(gain,mid), lowband_scratch);
-         quant_band(encode, m, i, Y, NULL, N, sbits, spread, B, tf_change,
+         quant_band(encode, m, i, Y, NULL, N, sbits, spread, B, intensity, tf_change,
                next_lowband2, resynth, ec, remaining_bits, LM, NULL,
                NULL, next_level, seed, MULT16_16_P15(gain,side), NULL);
       }
@@ -900,7 +900,10 @@
    }
 }
 
-void quant_all_bands(int encode, const CELTMode *m, int start, int end, celt_norm *_X, celt_norm *_Y, const celt_ener *bandE, int *pulses, int shortBlocks, int fold, int *tf_res, int resynth, int total_bits, void *ec, int LM, int codedBands)
+void quant_all_bands(int encode, const CELTMode *m, int start, int end,
+      celt_norm *_X, celt_norm *_Y, const celt_ener *bandE, int *pulses,
+      int shortBlocks, int fold, int intensity, int *tf_res, int resynth,
+      int total_bits, void *ec, int LM, int codedBands)
 {
    int i, balance;
    celt_int32 remaining_bits;
@@ -922,6 +925,31 @@
    ALLOC(lowband_scratch, M*(eBands[m->nbEBands]-eBands[m->nbEBands-1]), celt_norm);
    norm = _norm;
 
+   if (C==2)
+   {
+      int j;
+      int left = 0;
+      for (j=intensity;j<codedBands;j++)
+      {
+         int tmp = pulses[j]/2;
+         left += tmp;
+         pulses[j] -= tmp;
+      }
+      if (codedBands) {
+         int perband;
+         perband = left/(m->eBands[codedBands]-m->eBands[start]);
+         for (j=start;j<codedBands;j++)
+            pulses[j] += perband*(m->eBands[j+1]-m->eBands[j]);
+         left = left-(m->eBands[codedBands]-m->eBands[start])*perband;
+         for (j=start;j<codedBands;j++)
+         {
+            int tmp = IMIN(left, m->eBands[j+1]-m->eBands[j]);
+            pulses[j] += tmp;
+            left -= tmp;
+         }
+      }
+   }
+
    if (encode)
       seed = ((ec_enc*)ec)->rng;
    else
@@ -987,7 +1015,7 @@
          if (effective_lowband < norm+M*eBands[start])
             effective_lowband = norm+M*eBands[start];
       }
-      quant_band(encode, m, i, X, Y, N, b, fold, B, tf_change,
+      quant_band(encode, m, i, X, Y, N, b, fold, B, intensity, tf_change,
             effective_lowband, resynth, ec, &remaining_bits, LM,
             norm+M*eBands[i], bandE, 0, &seed, Q15ONE, lowband_scratch);
 
--- a/libcelt/bands.h
+++ b/libcelt/bands.h
@@ -78,7 +78,10 @@
  * @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
  * @param enc Entropy encoder
  */
-void quant_all_bands(int encode, const CELTMode *m, int start, int end, celt_norm * X, celt_norm * Y, const celt_ener *bandE, int *pulses, int time_domain, int fold, int *tf_res, int resynth, int total_bits, void *enc, int M, int codedBands);
+void quant_all_bands(int encode, const CELTMode *m, int start, int end,
+      celt_norm * X, celt_norm * Y, const celt_ener *bandE, int *pulses,
+      int time_domain, int fold, int intensity, int *tf_res, int resynth,
+      int total_bits, void *enc, int M, int codedBands);
 
 
 void stereo_decision(const CELTMode *m, celt_norm * restrict X, int *stereo_mode, int len, int M);
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -685,6 +685,7 @@
    int alloc_trim;
    int pitch_index=0;
    celt_word16 gain1 = 0;
+   int intensity=0;
    SAVE_STACK;
 
    if (nbCompressedBytes<0 || pcm==NULL)
@@ -997,6 +998,37 @@
      ec_byte_shrink(&buf, nbCompressedBytes);
    }
 
+   if (C==2)
+   {
+      int effectiveRate;
+
+      if (st->vbr_rate_norm>0)
+         effectiveRate = st->vbr_rate_norm>>BITRES<<LM;
+      else
+         effectiveRate = nbCompressedBytes*8;
+      /* Account for coarse energy */
+      effectiveRate -= 80;
+      effectiveRate >>= LM;
+      /* effectiveRate in kb/s */
+      effectiveRate = 2*effectiveRate/5;
+      if (effectiveRate<35)
+         intensity = 6;
+      else if (effectiveRate<50)
+         intensity = 12;
+      else if (effectiveRate<68)
+         intensity = 16;
+      else if (effectiveRate<84)
+         intensity = 18;
+      else if (effectiveRate<102)
+         intensity = 19;
+      else if (effectiveRate<130)
+         intensity = 20;
+      else
+         intensity = 100;
+      intensity = IMIN(st->end,IMAX(st->start, intensity));
+      ec_enc_uint(enc, intensity, 1+st->end-st->start);
+   }
+
    /* Bit allocation */
    ALLOC(fine_quant, st->mode->nbEBands, int);
    ALLOC(pulses, st->mode->nbEBands, int);
@@ -1019,7 +1051,9 @@
 #endif
 
    /* Residual quantisation */
-   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, codedBands);
+   quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL,
+         bandE, pulses, shortBlocks, has_fold, intensity, tf_res, resynth,
+         nbCompressedBytes*8, enc, LM, codedBands);
 
    quant_energy_finalise(st->mode, st->start, st->end, bandE, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
 
@@ -1581,6 +1615,7 @@
    int alloc_trim;
    int postfilter_pitch;
    celt_word16 postfilter_gain;
+   int intensity=0;
    SAVE_STACK;
 
    if (pcm==NULL)
@@ -1708,6 +1743,9 @@
       ec_dec_update(dec, trim_cdf[alloc_trim], trim_cdf[alloc_trim+1], 128);
    }
 
+   if (C==2)
+      intensity = ec_dec_uint(dec, 1+st->end-st->start);
+
    bits = len*8 - ec_dec_tell(dec, 0) - 1;
    codedBands = compute_allocation(st->mode, st->start, st->end, offsets, alloc_trim, bits, pulses, fine_quant, fine_priority, C, LM);
    
@@ -1714,7 +1752,9 @@
    unquant_fine_energy(st->mode, st->start, st->end, bandE, oldBandE, fine_quant, dec, C);
 
    /* Decode fixed codebook */
-   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, codedBands);
+   quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL,
+         NULL, pulses, shortBlocks, has_fold, intensity, tf_res, 1,
+         len*8, dec, LM, codedBands);
 
    unquant_energy_finalise(st->mode, st->start, st->end, bandE, oldBandE,
          fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);