Add support for intra-coding of the coarse energy.
[opus.git] / libcelt / laplace.c
index 8fac282..abfe576 100644 (file)
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include "entenc.h"
-#include "entdec.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "laplace.h"
 
-static int ec_laplace_get_total(int decay)
+int ec_laplace_get_start_freq(int decay)
 {
-   return (1<<30)/((1<<14) - decay) - (1<<15) + 1;
+   return (((ec_uint32)32767)*(16384-decay))/(16384+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)
 {
-   int i, fl, fs, ft;
+   int i;
+   int fl, ft;
    int s = 0;
-   if (value < 0)
+   int val = *value;
+   if (val < 0)
    {
       s = 1;
-      value = -value;
+      val = -val;
    }
-   ft = ec_laplace_get_total(decay);
-   fl = -(1<<15);
-   fs = 1<<15;
-   for (i=0;i<value;i++)
+   ft = 32767;
+   fl = -fs;
+   for (i=0;i<val;i++)
    {
       int tmp_l, tmp_s;
       tmp_l = fl;
       tmp_s = fs;
       fl += fs*2;
-      fs = (fs*decay)>>14;
+      fs = (fs*(ec_int32)decay)>>14;
       if (fs == 0)
       {
          fs = tmp_s;
          fl = tmp_l;
+         if (s)
+            *value = -i;
+         else
+            *value = i;
          break;
       }
    }
@@ -67,25 +75,32 @@ void ec_laplace_encode(ec_enc *enc, int value, int decay)
       fl = 0;
    if (s)
       fl += fs;
-   //printf ("enc: %d %d %d\n", fl, fs, ft);
+   /*DEBUG*/
+   /*printf ("enc: %d %d %d\n", fl, fs, ft);*/
    ec_encode(enc, fl, fl+fs, ft);
 }
 
-int ec_laplace_decode(ec_dec *dec, 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);
+}
+
+
+int ec_laplace_decode_start(ec_dec *dec, int decay, int fs)
 {
    int val=0;
-   int fl, fh, fs, ft, fm;
-   ft = ec_laplace_get_total(decay);
-   
-   fm = ec_decode(dec, ft);
-   //printf ("fm: %d/%d\n", fm, ft);
+   int fl, fh, ft, fm;
    fl = 0;
-   fs = 1<<15;
+   ft = 32767;
    fh = fs;
+   fm = ec_decode(dec, ft);
+   /*DEBUG*/
+   /*printf ("fm: %d/%d\n", fm, ft);*/
    while (fm >= fh && fs != 0)
    {
       fl = fh;
-      fs = (fs*decay)>>14;
+      fs = (fs*(ec_int32)decay)>>14;
       fh += fs*2;
       val++;
    }
@@ -102,47 +117,14 @@ int ec_laplace_decode(ec_dec *dec, int decay)
    /* Preventing an infinite loop in case something screws up in the decoding */
    if (fl==fh)
       fl--;
+   /*DEBUG*/
+   /*printf ("update: %d %d %d\n", fl, fh, ft);*/
    ec_dec_update(dec, fl, fh, ft);
    return val;
 }
 
-#if 0
-#include <stdio.h>
-int main()
+int ec_laplace_decode(ec_dec *dec, int decay)
 {
-   int val;
-   ec_enc enc;
-   ec_dec dec;
-   ec_byte_buffer buf;
-   
-   ec_byte_writeinit(&buf);
-   ec_enc_init(&enc,&buf);
-   
-   ec_laplace_encode(&enc, 9, 10000);
-   ec_laplace_encode(&enc, -5, 12000);
-   ec_laplace_encode(&enc, -2, 9000);
-   ec_laplace_encode(&enc, 20, 15000);
-   ec_laplace_encode(&enc, 2, 900);
-   
-   ec_enc_done(&enc);
-
-   ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
-   ec_dec_init(&dec,&buf);
-
-   val = ec_laplace_decode(&dec, 10000);
-   printf ("dec: %d\n", val);
-   val = ec_laplace_decode(&dec, 12000);
-   printf ("dec: %d\n", val);
-   val = ec_laplace_decode(&dec, 9000);
-   printf ("dec: %d\n", val);
-   val = ec_laplace_decode(&dec, 15000);
-   printf ("dec: %d\n", val);
-   val = ec_laplace_decode(&dec, 900);
-   printf ("dec: %d\n", val);
-   
-   
-   ec_byte_writeclear(&buf);
-   return 0;
+   int fs = ec_laplace_get_start_freq(decay);
+   return ec_laplace_decode_start(dec, decay, fs);
 }
-#endif
-