Replace ec_{enc|dec}_bit_prob() with ec_{enc|dec}_bit_logp().
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.
This commit is contained in:
parent
8c23a3a0fd
commit
e86fb268b0
8 changed files with 61 additions and 25 deletions
|
@ -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 (b>2<<BITRES && *remaining_bits > 2<<BITRES)
|
||||||
{
|
{
|
||||||
if (encode)
|
if (encode)
|
||||||
ec_enc_bit_prob(ec, inv, 16384);
|
ec_enc_bit_logp(ec, inv, 2);
|
||||||
else
|
else
|
||||||
inv = ec_dec_bit_prob(ec, 16384);
|
inv = ec_dec_bit_logp(ec, 2);
|
||||||
qalloc = inv ? 16 : 4;
|
qalloc = inv ? 16 : 4;
|
||||||
} else
|
} else
|
||||||
inv = 0;
|
inv = 0;
|
||||||
|
|
|
@ -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)
|
static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM, int tf_select, ec_enc *enc)
|
||||||
{
|
{
|
||||||
int curr, i;
|
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];
|
curr = tf_res[start];
|
||||||
for (i=start+1;i<end;i++)
|
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];
|
curr = tf_res[i];
|
||||||
}
|
}
|
||||||
if (LM!=0)
|
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)
|
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;
|
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];
|
curr = tf_res[start];
|
||||||
for (i=start+1;i<end;i++)
|
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];
|
curr = tf_res[i];
|
||||||
}
|
}
|
||||||
if (LM!=0)
|
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)))
|
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;
|
gain1 = 0;
|
||||||
} else {
|
} else {
|
||||||
int qg;
|
int qg;
|
||||||
|
@ -860,7 +860,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
#else
|
#else
|
||||||
qg = floor(.5+gain1*8)-2;
|
qg = floor(.5+gain1*8)-2;
|
||||||
#endif
|
#endif
|
||||||
ec_enc_bit_prob(enc, 1, 32768);
|
ec_enc_bit_logp(enc, 1, 1);
|
||||||
octave = EC_ILOG(pitch_index)-5;
|
octave = EC_ILOG(pitch_index)-5;
|
||||||
ec_enc_uint(enc, octave, 6);
|
ec_enc_uint(enc, octave, 6);
|
||||||
ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
|
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);*/
|
/*printf("%d %f\n", pitch_index, gain1);*/
|
||||||
#else /* ENABLE_POSTFILTER */
|
#else /* ENABLE_POSTFILTER */
|
||||||
ec_enc_bit_prob(enc, 0, 32768);
|
ec_enc_bit_logp(enc, 0, 1);
|
||||||
#endif /* ENABLE_POSTFILTER */
|
#endif /* ENABLE_POSTFILTER */
|
||||||
|
|
||||||
c=0; do {
|
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);
|
&st->delayedIntra, st->complexity >= 4);
|
||||||
|
|
||||||
if (LM > 0)
|
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);
|
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++)
|
for (i=0;i<st->mode->nbEBands;i++)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
ec_enc_bit_prob(enc, offsets[i]!=0, 1024);
|
ec_enc_bit_logp(enc, offsets[i]!=0, 6);
|
||||||
if (offsets[i]!=0)
|
if (offsets[i]!=0)
|
||||||
{
|
{
|
||||||
for (j=0;j<offsets[i]-1;j++)
|
for (j=0;j<offsets[i]-1;j++)
|
||||||
ec_enc_bit_prob(enc, 1, 32768);
|
ec_enc_bit_logp(enc, 1, 1);
|
||||||
ec_enc_bit_prob(enc, 0, 32768);
|
ec_enc_bit_logp(enc, 0, 1);
|
||||||
}
|
}
|
||||||
offsets[i] *= (6<<BITRES);
|
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;
|
dual_stereo = 0;
|
||||||
else
|
else
|
||||||
dual_stereo = stereo_analysis(st->mode, X, st->mode->nbEBands, LM, C, N);
|
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)
|
if (C==2)
|
||||||
{
|
{
|
||||||
|
@ -1786,7 +1786,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
}
|
}
|
||||||
nbAvailableBytes = len-nbFilledBytes;
|
nbAvailableBytes = len-nbFilledBytes;
|
||||||
|
|
||||||
if (ec_dec_bit_prob(dec, 32768))
|
if (ec_dec_bit_logp(dec, 1))
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_POSTFILTER
|
#ifdef ENABLE_POSTFILTER
|
||||||
int qg, octave;
|
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) */
|
/* 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 */
|
/* Get band energies */
|
||||||
unquant_coarse_energy(st->mode, st->start, st->end, bandE, oldBandE,
|
unquant_coarse_energy(st->mode, st->start, st->end, bandE, oldBandE,
|
||||||
intra_ener, dec, C, LM);
|
intra_ener, dec, C, LM);
|
||||||
|
|
||||||
if (LM > 0)
|
if (LM > 0)
|
||||||
isTransient = ec_dec_bit_prob(dec, 8192);
|
isTransient = ec_dec_bit_logp(dec, 3);
|
||||||
else
|
else
|
||||||
isTransient = 0;
|
isTransient = 0;
|
||||||
|
|
||||||
|
@ -1833,9 +1833,9 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
offsets[i] = 0;
|
offsets[i] = 0;
|
||||||
for (i=0;i<st->mode->nbEBands;i++)
|
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]++;
|
offsets[i]++;
|
||||||
offsets[i] *= (6<<BITRES);
|
offsets[i] *= (6<<BITRES);
|
||||||
|
@ -1847,7 +1847,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
|
|
||||||
if (C==2)
|
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);
|
intensity = ec_dec_uint(dec, 1+st->end-st->start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
/* Decode a bit that has a _prob/65536 probability of being a one */
|
||||||
int ec_dec_bit_prob(ec_dec *_this,unsigned _prob);
|
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.
|
/*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
|
This same number can be computed by the encoder, and is suitable for making
|
||||||
coding decisions.
|
coding decisions.
|
||||||
|
|
|
@ -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 */
|
/* 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);
|
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.
|
/*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
|
This same number can be computed by the decoder, and is suitable for making
|
||||||
coding decisions.
|
coding decisions.
|
||||||
|
|
|
@ -163,7 +163,7 @@ static void quant_coarse_energy_impl(const CELTMode *m, int start, int end,
|
||||||
celt_word16 coef;
|
celt_word16 coef;
|
||||||
celt_word16 beta;
|
celt_word16 beta;
|
||||||
|
|
||||||
ec_enc_bit_prob(enc, intra, 8192);
|
ec_enc_bit_logp(enc, intra, 3);
|
||||||
if (intra)
|
if (intra)
|
||||||
{
|
{
|
||||||
coef = 0;
|
coef = 0;
|
||||||
|
|
|
@ -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.*/
|
/*The probability of having a "one" is given in 1/65536.*/
|
||||||
int ec_dec_bit_prob(ec_dec *_this,unsigned _prob){
|
int ec_dec_bit_prob(ec_dec *_this,unsigned _prob){
|
||||||
ec_uint32 r;
|
ec_uint32 r;
|
||||||
ec_uint32 s;
|
|
||||||
ec_uint32 d;
|
ec_uint32 d;
|
||||||
|
ec_uint32 s;
|
||||||
int val;
|
int val;
|
||||||
r=_this->rng;
|
r=_this->rng;
|
||||||
d=_this->dif;
|
d=_this->dif;
|
||||||
|
@ -203,6 +203,22 @@ int ec_dec_bit_prob(ec_dec *_this,unsigned _prob){
|
||||||
return val;
|
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){
|
int ec_dec_cdf(ec_dec *_this,const int *_cdf,unsigned _ftb){
|
||||||
ec_uint32 r;
|
ec_uint32 r;
|
||||||
ec_uint32 d;
|
ec_uint32 d;
|
||||||
|
|
|
@ -153,6 +153,20 @@ void ec_enc_bit_prob(ec_enc *_this,int _val,unsigned _prob){
|
||||||
ec_enc_normalize(_this);
|
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){
|
void ec_enc_bits(ec_enc *_this,unsigned _fl,unsigned bits){
|
||||||
_this->nb_end_bits += bits;
|
_this->nb_end_bits += bits;
|
||||||
while (bits >= _this->end_bits_left)
|
while (bits >= _this->end_bits_left)
|
||||||
|
|
|
@ -245,11 +245,11 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
|
||||||
fluctuating in and out.*/
|
fluctuating in and out.*/
|
||||||
if (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
ec_enc_bit_prob((ec_enc *)ec, 0, 32768);
|
ec_enc_bit_logp((ec_enc *)ec, 0, 1);
|
||||||
} else if (ec_dec_bit_prob((ec_dec *)ec, 32768)) {
|
} else if (ec_dec_bit_logp((ec_dec *)ec, 1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*We used a bit to skip this band.*/
|
/*We used a bit to skip this band.*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue