Preventing encoder-decoder mismatch when energy values are too large to be

represented by the laplace encoder (would have a probability of zero due
to finite precision)
This commit is contained in:
Jean-Marc Valin 2008-05-27 22:17:13 +10:00
parent 987921a067
commit 4c6ee567ee
3 changed files with 13 additions and 8 deletions

View file

@ -40,19 +40,20 @@ int ec_laplace_get_start_freq(int decay)
return (((ec_uint32)32767)*(16384-decay))/(16384+decay); return (((ec_uint32)32767)*(16384-decay))/(16384+decay);
} }
void ec_laplace_encode_start(ec_enc *enc, int value, int decay, int fs) void ec_laplace_encode_start(ec_enc *enc, int *value, int decay, int fs)
{ {
int i; int i;
int fl, ft; int fl, ft;
int s = 0; int s = 0;
if (value < 0) int val = *value;
if (val < 0)
{ {
s = 1; s = 1;
value = -value; val = -val;
} }
ft = 32767; ft = 32767;
fl = -fs; fl = -fs;
for (i=0;i<value;i++) for (i=0;i<val;i++)
{ {
int tmp_l, tmp_s; int tmp_l, tmp_s;
tmp_l = fl; tmp_l = fl;
@ -63,6 +64,10 @@ void ec_laplace_encode_start(ec_enc *enc, int value, int decay, int fs)
{ {
fs = tmp_s; fs = tmp_s;
fl = tmp_l; fl = tmp_l;
if (s)
*value = -i;
else
*value = i;
break; break;
} }
} }
@ -75,7 +80,7 @@ void ec_laplace_encode_start(ec_enc *enc, int value, int decay, int fs)
ec_encode(enc, fl, fl+fs, ft); ec_encode(enc, fl, fl+fs, ft);
} }
void ec_laplace_encode(ec_enc *enc, int value, int decay) void ec_laplace_encode(ec_enc *enc, int *value, int decay)
{ {
int fs = ec_laplace_get_start_freq(decay); int fs = ec_laplace_get_start_freq(decay);
ec_laplace_encode_start(enc, value, decay, fs); ec_laplace_encode_start(enc, value, decay, fs);

View file

@ -40,9 +40,9 @@ int ec_laplace_get_start_freq(int decay);
@param value Value to encode @param value Value to encode
@param decay Probability of the value +/- 1, multiplied by 16384 @param decay Probability of the value +/- 1, multiplied by 16384
*/ */
void ec_laplace_encode(ec_enc *enc, int value, int decay); void ec_laplace_encode(ec_enc *enc, int *value, int decay);
void ec_laplace_encode_start(ec_enc *enc, int value, int decay, int fs); void ec_laplace_encode_start(ec_enc *enc, int *value, int decay, int fs);
/** Decode a value that is assumed to be the realisation of a /** Decode a value that is assumed to be the realisation of a
Laplace-distributed random process Laplace-distributed random process

View file

@ -179,7 +179,7 @@ static void quant_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word1
if (ec_enc_tell(enc, 0) - bits > budget+16) if (ec_enc_tell(enc, 0) - bits > budget+16)
qi = -1; qi = -1;
else else
ec_laplace_encode_start(enc, qi, prob[2*i], prob[2*i+1]); ec_laplace_encode_start(enc, &qi, prob[2*i], prob[2*i+1]);
q = qi*base_resolution; q = qi*base_resolution;
error[i] = f - SHL16(qi,8); error[i] = f - SHL16(qi,8);