

//#ifdef HAVE_CONFIG_H
#include "config.h"
//#endif

#include "ssc_lap.h"
#include "ssc_math.h"

/* The minimum probability of an energy delta (out of 32768). */
#define LAPLACE_LOG_MINP (0)

#ifndef HW_OPTI3
#define LAPLACE_MINP (1<<LAPLACE_LOG_MINP)
#else
#define LAPLACE_MINP (1)
#endif
/* The minimum number of guaranteed representable energy deltas (in one
    direction). */
#define LAPLACE_NMIN (16)




/* When called, decay is positive and at most 11456. */
static unsigned ec_laplace_get_freq1(unsigned fs0, int decay)
{
   unsigned ft;
#ifndef HW_OPTI3 
   ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0;
#else
   ft = 32736 - fs0;
#endif
   return ft*(int)(16384-decay)>>15;
}


int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay)
{
   int val=0;
   unsigned fl;
   unsigned fm;
   fm = rc_dec_bin(dec, 15);
   fl = 0;
   if (fm >= fs)
   {
      val++;
      fl = fs;
      fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP;
      /* Search the decaying part of the PDF.*/
      while(fs > LAPLACE_MINP && fm >= fl+2*fs)
      {
         fs *= 2;
         fl += fs;
#ifndef HW_OPTI3         
         fs = ((fs-2*LAPLACE_MINP)*(int)decay)>>15;
#else
         fs = ((fs-2)*(int)decay)>>15;
#endif
         fs += LAPLACE_MINP;
         val++;
      }
      /* Everything beyond that has probability LAPLACE_MINP. */
      if (fs <= LAPLACE_MINP)
      {
         int di;
#ifndef HW_OPTI3        
         di = (fm-fl)>>(LAPLACE_LOG_MINP+1);
#else
         di = (fm-fl)>>(1);
#endif
         val += di;
#ifndef HW_OPTI3          
         fl += 2*di*LAPLACE_MINP;
#else
         fl += (di<<1);
#endif
      }
      if (fm < fl+fs)
         val = -val;
      else
         fl += fs;
   }
   audio_assert(fl<32768);
   audio_assert(fs>0);
   audio_assert(fl<=fm);
   audio_assert(fm<IMIN(fl+fs,32768));
   rc_decode_upd(dec, fl, IMIN(fl+fs,32768), 32768);
   return val;
}
