shithub: opus

Download patch

ref: 43e940620151128e0cea9f05ee9ec58d1d64c93f
parent: 299747ee24851f2f20a8a466a3a5b58f1b116768
author: Timothy B. Terriberry <[email protected]>
date: Sat May 29 19:02:33 EDT 2010

Change ec_{enc|dec}_bit_prob to take probabilities in units of 1/65536 instead of 1/256. This allows them to use a single 16x16->32 multiply instead of a 24x8->32 multiply. Also change the time-frequency resolution flag coding to ensure that "0" is always the most-probable symbol (i.e., that prob("1")<50%), as that's where all the rounding error accumulates.

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -615,11 +615,11 @@
       else
          tf_res[i] = path0[i+1];
    }
-   ec_enc_bit_prob(enc, tf_res[0], isTransient ? 64 : 16);
+   ec_enc_bit_prob(enc, tf_res[0], isTransient ? 16384 : 4096);
    curr = tf_res[0];
    for (i=1;i<len;i++)
    {
-      ec_enc_bit_prob(enc, tf_res[i], curr ? 240: 16);
+      ec_enc_bit_prob(enc, tf_res[i] ^ curr, 4096);
       curr = tf_res[i];
    }
    RESTORE_STACK
@@ -629,11 +629,11 @@
 {
    int i, curr;
 
-   tf_res[0] = ec_dec_bit_prob(dec, isTransient ? 64 : 16);
+   tf_res[0] = ec_dec_bit_prob(dec, isTransient ? 16384 : 4096);
    curr = tf_res[0];
    for (i=1;i<len;i++)
    {
-      tf_res[i] = ec_dec_bit_prob(dec, curr ? 240: 16);
+      tf_res[i] = ec_dec_bit_prob(dec, 4096) ^ curr;
       curr = tf_res[i];
    }
 }
--- a/libcelt/entdec.h
+++ b/libcelt/entdec.h
@@ -110,8 +110,8 @@
   Return: The decoded bits.*/
 ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft);
 
-/* Decode a bit that has a _prob/256 probability of being a one */
-int ec_dec_bit_prob(ec_dec *_this,int _prob);
+/* Decode a bit that has a _prob/65536 probability of being a one */
+int ec_dec_bit_prob(ec_dec *_this,unsigned _prob);
 
 /*Returns the number of bits "used" by the decoded symbols so far.
   The actual number of bits may be larger, due to rounding to whole bytes, or
--- a/libcelt/entenc.h
+++ b/libcelt/entenc.h
@@ -91,8 +91,8 @@
        This must be at least one, and no more than 2**32-1.*/
 void ec_enc_uint(ec_enc *_this,ec_uint32 _fl,ec_uint32 _ft);
 
-/* Encode a bit that has a _prob/256 probability of being a one */
-void ec_enc_bit_prob(ec_enc *_this,int val,int _prob);
+/* 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);
 
 /*Returns the number of bits "used" by the encoded symbols so far.
   The actual number of bits may be larger, due to rounding to whole bytes, or
--- a/libcelt/rangedec.c
+++ b/libcelt/rangedec.c
@@ -186,8 +186,8 @@
   ec_dec_normalize(_this);
 }
 
-/*The probability of having a "one" is given in 1/256.*/
-int ec_dec_bit_prob(ec_dec *_this,int _prob){
+/*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;
@@ -194,7 +194,7 @@
   int       val;
   r=_this->rng;
   d=_this->dif;
-  s=IMUL32(r>>8,_prob);
+  s=(r>>16)*_prob;
   val=d<=s;
   if(!val)_this->dif=d-s;
   _this->rng=val?s:r-s;
--- a/libcelt/rangeenc.c
+++ b/libcelt/rangeenc.c
@@ -138,14 +138,14 @@
    ec_enc_normalize(_this);
 }
 
-/*The probability of having a "one" is given in 1/256.*/
-void ec_enc_bit_prob(ec_enc *_this,int _val,int _prob){
+/*The probability of having a "one" is given in 1/65536.*/
+void ec_enc_bit_prob(ec_enc *_this,int _val,unsigned _prob){
    ec_uint32 r;
    ec_uint32 s;
    ec_uint32 l;
    r=_this->rng;
    l=_this->low;
-   s=IMUL32(r>>8,_prob);
+   s=(r>>16)*_prob;
    r-=s;
    if(_val)_this->low=l+r;
    _this->rng=_val?s:r;