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.

This commit is contained in:
Timothy B. Terriberry 2010-05-29 23:02:33 -04:00 committed by Jean-Marc Valin
parent 299747ee24
commit 43e9406201
5 changed files with 14 additions and 14 deletions

View file

@ -615,11 +615,11 @@ static void tf_encode(celt_word16 *bandLogE, celt_word16 *oldBandE, int len, int
else else
tf_res[i] = path0[i+1]; 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]; curr = tf_res[0];
for (i=1;i<len;i++) 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]; curr = tf_res[i];
} }
RESTORE_STACK RESTORE_STACK
@ -629,11 +629,11 @@ static void tf_decode(int len, int C, int isTransient, int *tf_res, ec_dec *dec)
{ {
int i, curr; 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]; curr = tf_res[0];
for (i=1;i<len;i++) 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]; curr = tf_res[i];
} }
} }

View file

@ -110,8 +110,8 @@ ec_uint32 ec_dec_bits(ec_dec *_this,int _ftb);
Return: The decoded bits.*/ Return: The decoded bits.*/
ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft); ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft);
/* Decode a bit that has a _prob/256 probability of being a one */ /* Decode a bit that has a _prob/65536 probability of being a one */
int ec_dec_bit_prob(ec_dec *_this,int _prob); int ec_dec_bit_prob(ec_dec *_this,unsigned _prob);
/*Returns the number of bits "used" by the decoded symbols so far. /*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 The actual number of bits may be larger, due to rounding to whole bytes, or

View file

@ -91,8 +91,8 @@ void ec_enc_bits(ec_enc *_this,ec_uint32 _fl,int _ftb);
This must be at least one, and no more than 2**32-1.*/ 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); 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 */ /* Encode a bit that has a _prob/65536 probability of being a one */
void ec_enc_bit_prob(ec_enc *_this,int val,int _prob); void ec_enc_bit_prob(ec_enc *_this,int val,unsigned _prob);
/*Returns the number of bits "used" by the encoded symbols so far. /*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 The actual number of bits may be larger, due to rounding to whole bytes, or

View file

@ -186,15 +186,15 @@ void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
ec_dec_normalize(_this); ec_dec_normalize(_this);
} }
/*The probability of having a "one" is given in 1/256.*/ /*The probability of having a "one" is given in 1/65536.*/
int ec_dec_bit_prob(ec_dec *_this,int _prob){ int ec_dec_bit_prob(ec_dec *_this,unsigned _prob){
ec_uint32 r; ec_uint32 r;
ec_uint32 s; ec_uint32 s;
ec_uint32 d; ec_uint32 d;
int val; int val;
r=_this->rng; r=_this->rng;
d=_this->dif; d=_this->dif;
s=IMUL32(r>>8,_prob); s=(r>>16)*_prob;
val=d<=s; val=d<=s;
if(!val)_this->dif=d-s; if(!val)_this->dif=d-s;
_this->rng=val?s:r-s; _this->rng=val?s:r-s;

View file

@ -138,14 +138,14 @@ void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){
ec_enc_normalize(_this); ec_enc_normalize(_this);
} }
/*The probability of having a "one" is given in 1/256.*/ /*The probability of having a "one" is given in 1/65536.*/
void ec_enc_bit_prob(ec_enc *_this,int _val,int _prob){ void ec_enc_bit_prob(ec_enc *_this,int _val,unsigned _prob){
ec_uint32 r; ec_uint32 r;
ec_uint32 s; ec_uint32 s;
ec_uint32 l; ec_uint32 l;
r=_this->rng; r=_this->rng;
l=_this->low; l=_this->low;
s=IMUL32(r>>8,_prob); s=(r>>16)*_prob;
r-=s; r-=s;
if(_val)_this->low=l+r; if(_val)_this->low=l+r;
_this->rng=_val?s:r; _this->rng=_val?s:r;