shithub: opus

Download patch

ref: 7b0cb4ba0d2b5117d8ed4dbe0ab49c21090c8854
parent: 98acefdc4abedeee79b26a482d99625048a37ed1
author: Jean-Marc Valin <[email protected]>
date: Wed Sep 10 20:20:08 EDT 2008

One-at-a-time allocator now uses direct feedback from ec_*_tell().

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -41,6 +41,7 @@
 #include "stack_alloc.h"
 #include "os_support.h"
 #include "mathops.h"
+#include "rate.h"
 
 const celt_word16_t sqrtC_1[2] = {QCONST16(1.f, 14), QCONST16(1.414214f, 14)};
 
@@ -329,9 +330,9 @@
 
 
 /* Quantisation of the residual */
-void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int shortBlocks, ec_enc *enc)
+void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int shortBlocks, int total_bits, ec_enc *enc)
 {
-   int i, j;
+   int i, j, remaining_bits, balance;
    const celt_int16_t * restrict eBands = m->eBands;
    celt_norm_t * restrict norm;
    VARDECL(celt_norm_t, _norm);
@@ -343,6 +344,7 @@
    ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
    norm = _norm;
 
+   balance = 0;
    /*printf("bits left: %d\n", bits);
    for (i=0;i<m->nbEBands;i++)
       printf ("(%d %d) ", pulses[i], ebits[i]);
@@ -350,9 +352,32 @@
    /*printf ("%d %d\n", ec_enc_tell(enc, 0), compute_allocation(m, m->nbPulses));*/
    for (i=0;i<m->nbEBands;i++)
    {
+      int tell;
       int q;
       celt_word16_t n;
-      q = pulses[i];
+      
+      int curr_balance, curr_bits;
+      
+      tell = ec_enc_tell(enc, 4);
+      if (i != 0)
+         balance -= tell;
+      remaining_bits = (total_bits<<BITRES)-tell-1;
+      curr_balance = (m->nbEBands-i);
+      if (curr_balance > 3)
+         curr_balance = 3;
+      curr_balance = balance / curr_balance;
+      q = bits2pulses(m, m->bits[i], pulses[i]+curr_balance);
+      curr_bits = m->bits[i][q];
+      remaining_bits -= curr_bits;
+      if (remaining_bits < 0)
+      {
+         q--;
+         remaining_bits += curr_bits;
+         curr_bits = m->bits[i][q];
+         remaining_bits -= curr_bits;
+      }
+      balance += pulses[i] + tell;
+      
       n = SHL16(celt_sqrt(C*(eBands[i+1]-eBands[i])),11);
 
       /* If pitch isn't available, use intra-frame prediction */
@@ -389,9 +414,9 @@
 }
 
 /* Decoding of the residual */
-void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int shortBlocks, ec_dec *dec)
+void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int shortBlocks, int total_bits, ec_dec *dec)
 {
-   int i, j;
+   int i, j, remaining_bits, balance;
    const celt_int16_t * restrict eBands = m->eBands;
    celt_norm_t * restrict norm;
    VARDECL(celt_norm_t, _norm);
@@ -403,11 +428,35 @@
    ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
    norm = _norm;
 
+   balance = 0;
    for (i=0;i<m->nbEBands;i++)
    {
+      int tell;
       int q;
       celt_word16_t n;
-      q = pulses[i];
+      
+      int curr_balance, curr_bits;
+      
+      tell = ec_dec_tell(dec, 4);
+      if (i != 0)
+         balance -= tell;
+      remaining_bits = (total_bits<<BITRES)-tell-1;
+      curr_balance = (m->nbEBands-i);
+      if (curr_balance > 3)
+         curr_balance = 3;
+      curr_balance = balance / curr_balance;
+      q = bits2pulses(m, m->bits[i], pulses[i]+curr_balance);
+      curr_bits = m->bits[i][q];
+      remaining_bits -= curr_bits;
+      if (remaining_bits < 0)
+      {
+         q--;
+         remaining_bits += curr_bits;
+         curr_bits = m->bits[i][q];
+         remaining_bits -= curr_bits;
+      }
+      balance += pulses[i] + tell;
+
       n = SHL16(celt_sqrt(C*(eBands[i+1]-eBands[i])),11);
 
       /* If pitch isn't available, use intra-frame prediction */
--- a/libcelt/bands.h
+++ b/libcelt/bands.h
@@ -86,7 +86,7 @@
  * @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_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int time_domain, ec_enc *enc);
+void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int time_domain, int total_bits, ec_enc *enc);
 
 /** Decoding of the residual spectrum
  * @param m Mode data 
@@ -95,7 +95,7 @@
  * @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
  * @param dec Entropy decoder
 */
-void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int time_domain, ec_dec *dec);
+void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int time_domain, int total_bits, ec_dec *dec);
 
 void stereo_decision(const CELTMode *m, celt_norm_t * restrict X, int *stereo_mode, int len);
 
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -597,7 +597,7 @@
    /*for (i=0;i<B*N;i++) printf("%f ",P[i]);printf("\n");*/
 
    /* Residual quantisation */
-   quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, &st->enc);
+   quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, nbCompressedBytes*8, &st->enc);
    
    if (st->pitch_enabled)
    {
@@ -625,6 +625,7 @@
       }
 #endif
    }
+   /*fprintf (stderr, "remaining bits after encode = %d\n", nbCompressedBytes*8-ec_enc_tell(&st->enc, 0));*/
    /*if (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8 - 7)
       celt_warning_int ("many unused bits: ", nbCompressedBytes*8-ec_enc_tell(&st->enc, 0));*/
    /*printf ("%d\n", ec_enc_tell(&st->enc, 0)-8*nbCompressedBytes);*/
@@ -974,7 +975,7 @@
    pitch_quant_bands(st->mode, P, gains);
 
    /* Decode fixed codebook and merge with pitch */
-   unquant_bands(st->mode, X, P, bandE, stereo_mode, pulses, shortBlocks, &dec);
+   unquant_bands(st->mode, X, P, bandE, stereo_mode, pulses, shortBlocks, len*8, &dec);
 
    if (C==2)
    {
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -42,9 +42,6 @@
 #include "entcode.h"
 #include "rate.h"
 
-#define BITRES 4
-#define BITROUND 8
-#define BITOVERFLOW 30000
 
 #ifndef STATIC_MODES
 
@@ -93,31 +90,8 @@
 
 #endif /* !STATIC_MODES */
 
-static inline int bits2pulses(const CELTMode *m, const celt_int16_t *cache, int bits)
-{
-   int i;
-   int lo, hi;
-   lo = 0;
-   hi = MAX_PULSES-1;
-   
-   /* Instead of using the "bisection condition" we use a fixed number of 
-      iterations because it should be faster */
-   /*while (hi-lo != 1)*/
-   for (i=0;i<LOG_MAX_PULSES;i++)
-   {
-      int mid = (lo+hi)>>1;
-      /* OPT: Make sure this is implemented with a conditional move */
-      if (cache[mid] >= bits)
-         hi = mid;
-      else
-         lo = mid;
-   }
-   if (bits-cache[lo] <= cache[hi]-bits)
-      return lo;
-   else
-      return hi;
-}
 
+
 static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cache, int *bits1, int *bits2, int *ebits1, int *ebits2, int total, int *pulses, int *bits, int *ebits, int len)
 {
    int esum, psum;
@@ -238,6 +212,7 @@
       if (bits2[j] < 0)
          bits2[j] = 0;
    }
+#if 0
    remaining_bits = interp_bits2pulses(m, cache, bits1, bits2, ebits1, ebits2, total, pulses, bits, ebits, len);
    {
       int balance = 0;
@@ -260,8 +235,13 @@
          }
          balance += bits[i] - curr_bits;
          pulses[i] = P;
+         printf ("%d ", P);
       }
+      printf ("\n");
    }
+#else
+   remaining_bits = interp_bits2pulses(m, cache, bits1, bits2, ebits1, ebits2, total, bits, pulses, ebits, len);
+#endif
    RESTORE_STACK;
 }
 
--- a/libcelt/rate.h
+++ b/libcelt/rate.h
@@ -35,6 +35,35 @@
 #define MAX_PULSES 128
 #define LOG_MAX_PULSES 7
 
+#define BITRES 4
+#define BITROUND 8
+#define BITOVERFLOW 30000
+
+static inline int bits2pulses(const CELTMode *m, const celt_int16_t *cache, int bits)
+{
+   int i;
+   int lo, hi;
+   lo = 0;
+   hi = MAX_PULSES-1;
+   
+   /* Instead of using the "bisection condition" we use a fixed number of 
+   iterations because it should be faster */
+   /*while (hi-lo != 1)*/
+   for (i=0;i<LOG_MAX_PULSES;i++)
+   {
+      int mid = (lo+hi)>>1;
+      /* OPT: Make sure this is implemented with a conditional move */
+      if (cache[mid] >= bits)
+         hi = mid;
+      else
+         lo = mid;
+   }
+   if (bits-cache[lo] <= cache[hi]-bits)
+      return lo;
+   else
+      return hi;
+}
+
 /** Computes a cache of the pulses->bits mapping in each band */
 celt_int16_t **compute_alloc_cache(CELTMode *m, int C);
 
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -139,6 +139,7 @@
       else if (errors%2 == 1)
          data[rand()%8] ^= 1<<rand()%8;
 #endif
+#if 1 /* Set to zero to use the encoder's output instead */
       /* This is to simulate packet loss */
       if (argc==9 && rand()%1000<atoi(argv[7]))
       /*if (errors && (errors%2==0))*/
@@ -145,6 +146,10 @@
          celt_decode(dec, NULL, len, out);
       else
          celt_decode(dec, data, len, out);
+#else
+      for (i=0;i<frame_size*channels;i++)
+         out[i] = in[i];
+#endif
 #if !(defined (FIXED_POINT) && defined(STATIC_MODES))
       for (i=0;i<frame_size*channels;i++)
       {