Replace ec_{enc|dec}_bit_prob() with ec_{enc|dec}_bit_logp().
authorTimothy B. Terriberry <tterribe@xiph.org>
Fri, 17 Dec 2010 22:50:19 +0000 (14:50 -0800)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Sat, 18 Dec 2010 14:06:06 +0000 (09:06 -0500)
All of our usage of ec_{enc|dec}_bit_prob had the probability of a
 "one" being a power of two.
This adds a new ec_{enc|dec}_bit_logp() function that takes this
 explicitly into account.
It introduces less rounding error than the bit_prob version, does not
 require 17-bit integers to be emulated by ec_{encode|decode}_bin(),
 and does not require any multiplies or divisions at all.
It is exactly equivalent to
 ec_encode_bin(enc,_val?0:(1<<_logp)-1,(1<<_logp)-(_val?1:0),1<<_logp)

The old ec_{enc|dec}_bit_prob functions are left in place for now,
 because I am not sure if SILK is still using them or not when
 combined in Opus.

libcelt/bands.c
libcelt/celt.c
libcelt/entdec.h
libcelt/entenc.h
libcelt/quant_bands.c
libcelt/rangedec.c
libcelt/rangeenc.c
libcelt/rate.c

index c83fdc5..b978961 100644 (file)
@@ -675,9 +675,9 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
          if (b>2<<BITRES && *remaining_bits > 2<<BITRES)
          {
             if (encode)
-               ec_enc_bit_prob(ec, inv, 16384);
+               ec_enc_bit_logp(ec, inv, 2);
             else
-               inv = ec_dec_bit_prob(ec, 16384);
+               inv = ec_dec_bit_logp(ec, 2);
             qalloc = inv ? 16 : 4;
          } else
             inv = 0;
index a565e04..9d808c8 100644 (file)
@@ -592,11 +592,11 @@ static int tf_analysis(const CELTMode *m, celt_word16 *bandLogE, celt_word16 *ol
 static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM, int tf_select, ec_enc *enc)
 {
    int curr, i;
-   ec_enc_bit_prob(enc, tf_res[start], isTransient ? 16384 : 4096);
+   ec_enc_bit_logp(enc, tf_res[start], isTransient ? 2 : 4);
    curr = tf_res[start];
    for (i=start+1;i<end;i++)
    {
-      ec_enc_bit_prob(enc, tf_res[i] ^ curr, isTransient ? 4096 : 2048);
+      ec_enc_bit_logp(enc, tf_res[i] ^ curr, isTransient ? 4 : 5);
       curr = tf_res[i];
    }
    if (LM!=0)
@@ -609,11 +609,11 @@ static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM,
 static void tf_decode(int start, int end, int C, int isTransient, int *tf_res, int LM, ec_dec *dec)
 {
    int i, curr, tf_select;
-   tf_res[start] = ec_dec_bit_prob(dec, isTransient ? 16384 : 4096);
+   tf_res[start] = ec_dec_bit_logp(dec, isTransient ? 2 : 4);
    curr = tf_res[start];
    for (i=start+1;i<end;i++)
    {
-      tf_res[i] = ec_dec_bit_prob(dec, isTransient ? 4096 : 2048) ^ curr;
+      tf_res[i] = ec_dec_bit_logp(dec, isTransient ? 4 : 5) ^ curr;
       curr = tf_res[i];
    }
    if (LM!=0)
@@ -850,7 +850,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
       }
       if (gain1<QCONST16(.2f,15) || (nbAvailableBytes<30 && gain1<QCONST16(.4f,15)))
       {
-         ec_enc_bit_prob(enc, 0, 32768);
+         ec_enc_bit_logp(enc, 0, 1);
          gain1 = 0;
       } else {
          int qg;
@@ -860,7 +860,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
 #else
          qg = floor(.5+gain1*8)-2;
 #endif
-         ec_enc_bit_prob(enc, 1, 32768);
+         ec_enc_bit_logp(enc, 1, 1);
          octave = EC_ILOG(pitch_index)-5;
          ec_enc_uint(enc, octave, 6);
          ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
@@ -869,7 +869,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
       }
       /*printf("%d %f\n", pitch_index, gain1);*/
 #else /* ENABLE_POSTFILTER */
-      ec_enc_bit_prob(enc, 0, 32768);
+      ec_enc_bit_logp(enc, 0, 1);
 #endif /* ENABLE_POSTFILTER */
 
       c=0; do {
@@ -942,7 +942,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
          &st->delayedIntra, st->complexity >= 4);
 
    if (LM > 0)
-      ec_enc_bit_prob(enc, shortBlocks!=0, 8192);
+      ec_enc_bit_logp(enc, shortBlocks!=0, 3);
 
    tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
 
@@ -994,12 +994,12 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
    for (i=0;i<st->mode->nbEBands;i++)
    {
       int j;
-      ec_enc_bit_prob(enc, offsets[i]!=0, 1024);
+      ec_enc_bit_logp(enc, offsets[i]!=0, 6);
       if (offsets[i]!=0)
       {
          for (j=0;j<offsets[i]-1;j++)
-            ec_enc_bit_prob(enc, 1, 32768);
-         ec_enc_bit_prob(enc, 0, 32768);
+            ec_enc_bit_logp(enc, 1, 1);
+         ec_enc_bit_logp(enc, 0, 1);
       }
       offsets[i] *= (6<<BITRES);
    }
@@ -1088,7 +1088,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
          dual_stereo = 0;
       else
          dual_stereo = stereo_analysis(st->mode, X, st->mode->nbEBands, LM, C, N);
-      ec_enc_bit_prob(enc, dual_stereo, 32768);
+      ec_enc_bit_logp(enc, dual_stereo, 1);
    }
    if (C==2)
    {
@@ -1786,7 +1786,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
    }
    nbAvailableBytes = len-nbFilledBytes;
 
-   if (ec_dec_bit_prob(dec, 32768))
+   if (ec_dec_bit_logp(dec, 1))
    {
 #ifdef ENABLE_POSTFILTER
       int qg, octave;
@@ -1805,13 +1805,13 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
    }
 
    /* Decode the global flags (first symbols in the stream) */
-   intra_ener = ec_dec_bit_prob(dec, 8192);
+   intra_ener = ec_dec_bit_logp(dec, 3);
    /* Get band energies */
    unquant_coarse_energy(st->mode, st->start, st->end, bandE, oldBandE,
          intra_ener, dec, C, LM);
 
    if (LM > 0)
-      isTransient = ec_dec_bit_prob(dec, 8192);
+      isTransient = ec_dec_bit_logp(dec, 3);
    else
       isTransient = 0;
 
@@ -1833,9 +1833,9 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
       offsets[i] = 0;
    for (i=0;i<st->mode->nbEBands;i++)
    {
-      if (ec_dec_bit_prob(dec, 1024))
+      if (ec_dec_bit_logp(dec, 6))
       {
-         while (ec_dec_bit_prob(dec, 32768))
+         while (ec_dec_bit_logp(dec, 1))
             offsets[i]++;
          offsets[i]++;
          offsets[i] *= (6<<BITRES);
@@ -1847,7 +1847,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
 
    if (C==2)
    {
-      dual_stereo = ec_dec_bit_prob(dec, 32768);
+      dual_stereo = ec_dec_bit_logp(dec, 1);
       intensity = ec_dec_uint(dec, 1+st->end-st->start);
    }
 
index 6a3841b..f163b4d 100644 (file)
@@ -124,6 +124,9 @@ int ec_dec_cdf(ec_dec *_this,const int *_cdf,unsigned _ftb);
 /* Decode a bit that has a _prob/65536 probability of being a one */
 int ec_dec_bit_prob(ec_dec *_this,unsigned _prob);
 
+/* Decode a bit that has a 1/(1<<_logp) probability of being a one */
+int ec_dec_bit_logp(ec_dec *_this,unsigned _logp);
+
 /*Returns the number of bits "used" by the encoded symbols so far.
   This same number can be computed by the encoder, and is suitable for making
    coding decisions.
index d86cb7f..2b31f96 100644 (file)
@@ -96,6 +96,9 @@ void ec_enc_uint(ec_enc *_this,ec_uint32 _fl,ec_uint32 _ft);
 /* Encode a bit that has a _prob/65536 probability of being a one */
 void ec_enc_bit_prob(ec_enc *_this,int val,unsigned _prob);
 
+/* Encode a bit that has a 1/(1<<_logp) probability of being a one */
+void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp);
+
 /*Returns the number of bits "used" by the encoded symbols so far.
   This same number can be computed by the decoder, and is suitable for making
    coding decisions.
index ce7cb72..e894aff 100644 (file)
@@ -163,7 +163,7 @@ static void quant_coarse_energy_impl(const CELTMode *m, int start, int end,
    celt_word16 coef;
    celt_word16 beta;
 
-   ec_enc_bit_prob(enc, intra, 8192);
+   ec_enc_bit_logp(enc, intra, 3);
    if (intra)
    {
       coef = 0;
index 97dd7ff..262c0eb 100644 (file)
@@ -190,8 +190,8 @@ void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
 /*The probability of having a "one" is given in 1/65536.*/
 int ec_dec_bit_prob(ec_dec *_this,unsigned _prob){
   ec_uint32 r;
-  ec_uint32 s;
   ec_uint32 d;
+  ec_uint32 s;
   int       val;
   r=_this->rng;
   d=_this->dif;
@@ -203,6 +203,22 @@ int ec_dec_bit_prob(ec_dec *_this,unsigned _prob){
   return val;
 }
 
+/*The probability of having a "one" is 1/(1<<_logp).*/
+int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){
+  ec_uint32 r;
+  ec_uint32 d;
+  ec_uint32 s;
+  int       val;
+  r=_this->rng;
+  d=_this->dif;
+  s=r>>_logp;
+  val=d<s;
+  if(!val)_this->dif=d-s;
+  _this->rng=val?s:r-s;
+  ec_dec_normalize(_this);
+  return val;
+}
+
 int ec_dec_cdf(ec_dec *_this,const int *_cdf,unsigned _ftb){
   ec_uint32 r;
   ec_uint32 d;
index b4a7343..e5040e7 100644 (file)
@@ -153,6 +153,20 @@ void ec_enc_bit_prob(ec_enc *_this,int _val,unsigned _prob){
    ec_enc_normalize(_this);
 }
 
+/*The probability of having a "one" is 1/(1<<_logp).*/
+void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
+   ec_uint32 r;
+   ec_uint32 s;
+   ec_uint32 l;
+   r=_this->rng;
+   l=_this->low;
+   s=r>>_logp;
+   r-=s;
+   if(_val)_this->low=l+r;
+   _this->rng=_val?s:r;
+   ec_enc_normalize(_this);
+}
+
 void ec_enc_bits(ec_enc *_this,unsigned _fl,unsigned bits){
   _this->nb_end_bits += bits;
   while (bits >= _this->end_bits_left)
index 702378a..514562c 100644 (file)
@@ -245,11 +245,11 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
                fluctuating in and out.*/
             if (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
             {
-               ec_enc_bit_prob((ec_enc *)ec, 1, 32768);
+               ec_enc_bit_logp((ec_enc *)ec, 1, 1);
                break;
             }
-            ec_enc_bit_prob((ec_enc *)ec, 0, 32768);
-         } else if (ec_dec_bit_prob((ec_dec *)ec, 32768)) {
+            ec_enc_bit_logp((ec_enc *)ec, 0, 1);
+         } else if (ec_dec_bit_logp((ec_dec *)ec, 1)) {
             break;
          }
          /*We used a bit to skip this band.*/