ref: 4c6ee567ee8bde030a620b577570bc0cd9620a7d
parent: 987921a067808122ab888421fd64fd87561e8c67
author: Jean-Marc Valin <[email protected]>
date: Tue May 27 18:17:13 EDT 2008
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)
--- a/libcelt/laplace.c
+++ b/libcelt/laplace.c
@@ -40,19 +40,20 @@
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 fl, ft;
int s = 0;
- if (value < 0)
+ int val = *value;
+ if (val < 0)
{
s = 1;
- value = -value;
+ val = -val;
}
ft = 32767;
fl = -fs;
- for (i=0;i<value;i++)
+ for (i=0;i<val;i++)
{
int tmp_l, tmp_s;
tmp_l = fl;
@@ -63,6 +64,10 @@
{
fs = tmp_s;
fl = tmp_l;
+ if (s)
+ *value = -i;
+ else
+ *value = i;
break;
}
}
@@ -75,7 +80,7 @@
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);
ec_laplace_encode_start(enc, value, decay, fs);
--- a/libcelt/laplace.h
+++ b/libcelt/laplace.h
@@ -40,9 +40,9 @@
@param value Value to encode
@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
Laplace-distributed random process
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -179,7 +179,7 @@
if (ec_enc_tell(enc, 0) - bits > budget+16)
qi = -1;
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;
error[i] = f - SHL16(qi,8);