shithub: opus

Download patch

ref: 845dfa19860c9e4806b6ad9bed0c8a8581626bce
parent: 79d76a2e3ae1a41365eab08f544732750d73b42e
author: Timothy B. Terriberry <[email protected]>
date: Sun Jan 2 11:53:28 EST 2011

Changes to ec_dec_cdf() to support 8-bit tables.

This renames ec_dec_cdf() to ec_dec_icdf(), and changes the
 functionality to use an "inverse" CDF table, where
 icdf[i]=ft-cdf[i+1].
The first entry is omitted entirely.
It also adds a corresonding ec_enc_icdf() to the encoder, which uses
 the same table.
One could use ec_encode_bin() by converting the values in the tables
 back to normal CDF values, but the icdf[] table already has them in
 the form ec_encode_bin() wants to use them, so there's no reason to
 translate them and then translate them back.

This is done primarily to allow SILK to use the range coder with
 8-bit probability tables containing cumulative frequencies that
 span the full range 0...256.
With an 8-bit table, the final 256 of a normal CDF becomes 0 in the
 "inverse" CDF.
It's the 0 at the start of a normal CDF which would become 256, but
 this is the value we omit, as it already has to be special-cased in
 the encoder, and is not used at all in the decoder.

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -53,8 +53,9 @@
 #include <stdarg.h>
 #include "plc.h"
 
-static const unsigned trim_cdf[12] = {0, 2, 4, 9, 19, 41, 87, 109, 119, 124, 126, 128};
-static const unsigned spread_cdf[5] = {0, 7, 9, 30, 32};
+static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0};
+/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
+static const unsigned char spread_icdf[4] = {25, 23, 2, 0};
 
 #define COMBFILTER_MAXPERIOD 1024
 #define COMBFILTER_MINPERIOD 16
@@ -975,9 +976,7 @@
    } else {
       st->spread_decision = spreading_decision(st->mode, X, &st->tonal_average, st->spread_decision, effEnd, C, M);
    }
-   /* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
-   ec_encode_bin(enc, spread_cdf[st->spread_decision],
-         spread_cdf[st->spread_decision+1], 5);
+   ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
 
    ALLOC(offsets, st->mode->nbEBands, int);
 
@@ -1030,7 +1029,7 @@
       }
    }
    alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE, st->mode->nbEBands, LM, C, N);
-   ec_encode_bin(enc, trim_cdf[alloc_trim], trim_cdf[alloc_trim+1], 7);
+   ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
 
    /* Variable bitrate */
    if (st->vbr_rate_norm>0)
@@ -1850,7 +1849,7 @@
    ALLOC(tf_res, st->mode->nbEBands, int);
    tf_decode(st->start, st->end, C, isTransient, tf_res, LM, dec);
 
-   spread_decision = ec_dec_cdf(dec, spread_cdf, 5);
+   spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
 
    ALLOC(pulses, st->mode->nbEBands, int);
    ALLOC(offsets, st->mode->nbEBands, int);
@@ -1878,7 +1877,7 @@
    }
 
    ALLOC(fine_quant, st->mode->nbEBands, int);
-   alloc_trim = ec_dec_cdf(dec, trim_cdf, 7);
+   alloc_trim = ec_dec_icdf(dec, trim_icdf, 7);
 
    if (C==2)
    {
--- a/libcelt/entdec.h
+++ b/libcelt/entdec.h
@@ -113,15 +113,15 @@
        This must be at least one, and no more than 2**32-1.
   Return: The decoded bits.*/
 ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft);
-/*Decodes a symbol given its CDF.
+/*Decodes a symbol given an "inverse" CDF table.
   No call to ec_dec_update() is necessary after this call.
-  _cdf: The CDF, such that symbol s falls in the range [_cdf[s],_cdf[s+1]).
-        The first value must be 0, the last value must be (1<<_ftb), and the
-         values must be monotonicly non-decreasing.
+  _icdf: The "inverse" CDF, such that symbol s falls in the range
+          [s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb.
+         The values must be monotonically non-increasing, and the last value
+          must be 0.
   _ftb: The number of bits of precision in the cumulative distribution.
-  Return: The decoded symbol s, which must have been encoded with
-   ec_encode_bin(enc,_cdf[s],_cdf[s+1],_ftb).*/
-int ec_dec_cdf(ec_dec *_this,const unsigned *_cdf,unsigned _ftb);
+  Return: The decoded symbol s.*/
+int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,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);
--- a/libcelt/entenc.h
+++ b/libcelt/entenc.h
@@ -100,6 +100,15 @@
 /* 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);
 
+/*Encodes a symbol given an "inverse" CDF table.
+  _s:    The index of the symbol to encode.
+  _icdf: The "inverse" CDF, such that symbol _s falls in the range
+          [_s>0?ft-_icdf[_s-1]:0,ft-_icdf[_s]), where ft=1<<_ftb.
+         The values must be monotonically non-increasing, and the last value
+          must be 0.
+  _ftb: The number of bits of precision in the cumulative distribution.*/
+void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb);
+
 /*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.
--- a/libcelt/rangedec.c
+++ b/libcelt/rangedec.c
@@ -187,7 +187,7 @@
   return val;
 }
 
-int ec_dec_cdf(ec_dec *_this,const unsigned *_cdf,unsigned _ftb){
+int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){
   ec_uint32 r;
   ec_uint32 d;
   ec_uint32 s;
@@ -199,7 +199,7 @@
   val=0;
   do{
     t=s;
-    s=IMUL32(r,(1<<_ftb)-_cdf[++val]);
+    s=IMUL32(r,_icdf[val++]);
   }
   while(d<s);
   _this->dif=d-s;
--- a/libcelt/rangeenc.c
+++ b/libcelt/rangeenc.c
@@ -169,6 +169,17 @@
   ec_enc_normalize(_this);
 }
 
+void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){
+  ec_uint32 r;
+  r=_this->rng>>_ftb;
+  if(_s>0){
+    _this->low+=_this->rng-IMUL32(r,_icdf[_s-1]);
+    _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
+  }
+  else _this->rng-=IMUL32(r,_icdf[_s]);
+  ec_enc_normalize(_this);
+}
+
 void ec_enc_bits(ec_enc *_this,ec_uint32 _fl,unsigned _bits){
   ec_window window;
   int       used;
--- a/tests/ectest.c
+++ b/tests/ectest.c
@@ -188,7 +188,7 @@
     for(j=0;j<sz;j++){
       data[j]=rand()/((RAND_MAX>>1)+1);
       logp1[j]=(rand()%15)+1;
-      enc_method[j]=rand()%3;
+      enc_method[j]=rand()/((RAND_MAX>>2)+1);
       switch(enc_method[j]){
         case 0:{
           ec_encode(&enc,data[j]?(1<<logp1[j])-1:0,
@@ -201,6 +201,12 @@
         case 2:{
           ec_enc_bit_logp(&enc,data[j],logp1[j]);
         }break;
+        case 3:{
+          unsigned icdf[2];
+          icdf[0]=1;
+          icdf[1]=0;
+          ec_enc_icdf(&enc,data[j],icdf,logp1[j]);
+        }break;
       }
       tell[j+1]=ec_enc_tell(&enc,3);
     }
@@ -238,11 +244,10 @@
           sym=ec_dec_bit_logp(&dec,logp1[j]);
         }break;
         case 3:{
-          unsigned cdf[3];
-          cdf[0]=0;
-          cdf[1]=(1<<logp1[j])-1;
-          cdf[2]=1<<logp1[j];
-          sym=ec_dec_cdf(&dec,cdf,logp1[j]);
+          unsigned icdf[2];
+          icdf[0]=1;
+          icdf[1]=0;
+          sym=ec_dec_icdf(&dec,icdf,logp1[j]);
         }break;
       }
       if(sym!=data[j]){