media/libopus/celt/laplace.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libopus/celt/laplace.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,134 @@
     1.4 +/* Copyright (c) 2007 CSIRO
     1.5 +   Copyright (c) 2007-2009 Xiph.Org Foundation
     1.6 +   Written by Jean-Marc Valin */
     1.7 +/*
     1.8 +   Redistribution and use in source and binary forms, with or without
     1.9 +   modification, are permitted provided that the following conditions
    1.10 +   are met:
    1.11 +
    1.12 +   - Redistributions of source code must retain the above copyright
    1.13 +   notice, this list of conditions and the following disclaimer.
    1.14 +
    1.15 +   - Redistributions in binary form must reproduce the above copyright
    1.16 +   notice, this list of conditions and the following disclaimer in the
    1.17 +   documentation and/or other materials provided with the distribution.
    1.18 +
    1.19 +   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.20 +   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.21 +   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.22 +   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
    1.23 +   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    1.24 +   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    1.25 +   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    1.26 +   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    1.27 +   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    1.28 +   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    1.29 +   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.30 +*/
    1.31 +
    1.32 +#ifdef HAVE_CONFIG_H
    1.33 +#include "config.h"
    1.34 +#endif
    1.35 +
    1.36 +#include "laplace.h"
    1.37 +#include "mathops.h"
    1.38 +
    1.39 +/* The minimum probability of an energy delta (out of 32768). */
    1.40 +#define LAPLACE_LOG_MINP (0)
    1.41 +#define LAPLACE_MINP (1<<LAPLACE_LOG_MINP)
    1.42 +/* The minimum number of guaranteed representable energy deltas (in one
    1.43 +    direction). */
    1.44 +#define LAPLACE_NMIN (16)
    1.45 +
    1.46 +/* When called, decay is positive and at most 11456. */
    1.47 +static unsigned ec_laplace_get_freq1(unsigned fs0, int decay)
    1.48 +{
    1.49 +   unsigned ft;
    1.50 +   ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0;
    1.51 +   return ft*(opus_int32)(16384-decay)>>15;
    1.52 +}
    1.53 +
    1.54 +void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay)
    1.55 +{
    1.56 +   unsigned fl;
    1.57 +   int val = *value;
    1.58 +   fl = 0;
    1.59 +   if (val)
    1.60 +   {
    1.61 +      int s;
    1.62 +      int i;
    1.63 +      s = -(val<0);
    1.64 +      val = (val+s)^s;
    1.65 +      fl = fs;
    1.66 +      fs = ec_laplace_get_freq1(fs, decay);
    1.67 +      /* Search the decaying part of the PDF.*/
    1.68 +      for (i=1; fs > 0 && i < val; i++)
    1.69 +      {
    1.70 +         fs *= 2;
    1.71 +         fl += fs+2*LAPLACE_MINP;
    1.72 +         fs = (fs*(opus_int32)decay)>>15;
    1.73 +      }
    1.74 +      /* Everything beyond that has probability LAPLACE_MINP. */
    1.75 +      if (!fs)
    1.76 +      {
    1.77 +         int di;
    1.78 +         int ndi_max;
    1.79 +         ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP;
    1.80 +         ndi_max = (ndi_max-s)>>1;
    1.81 +         di = IMIN(val - i, ndi_max - 1);
    1.82 +         fl += (2*di+1+s)*LAPLACE_MINP;
    1.83 +         fs = IMIN(LAPLACE_MINP, 32768-fl);
    1.84 +         *value = (i+di+s)^s;
    1.85 +      }
    1.86 +      else
    1.87 +      {
    1.88 +         fs += LAPLACE_MINP;
    1.89 +         fl += fs&~s;
    1.90 +      }
    1.91 +      celt_assert(fl+fs<=32768);
    1.92 +      celt_assert(fs>0);
    1.93 +   }
    1.94 +   ec_encode_bin(enc, fl, fl+fs, 15);
    1.95 +}
    1.96 +
    1.97 +int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay)
    1.98 +{
    1.99 +   int val=0;
   1.100 +   unsigned fl;
   1.101 +   unsigned fm;
   1.102 +   fm = ec_decode_bin(dec, 15);
   1.103 +   fl = 0;
   1.104 +   if (fm >= fs)
   1.105 +   {
   1.106 +      val++;
   1.107 +      fl = fs;
   1.108 +      fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP;
   1.109 +      /* Search the decaying part of the PDF.*/
   1.110 +      while(fs > LAPLACE_MINP && fm >= fl+2*fs)
   1.111 +      {
   1.112 +         fs *= 2;
   1.113 +         fl += fs;
   1.114 +         fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15;
   1.115 +         fs += LAPLACE_MINP;
   1.116 +         val++;
   1.117 +      }
   1.118 +      /* Everything beyond that has probability LAPLACE_MINP. */
   1.119 +      if (fs <= LAPLACE_MINP)
   1.120 +      {
   1.121 +         int di;
   1.122 +         di = (fm-fl)>>(LAPLACE_LOG_MINP+1);
   1.123 +         val += di;
   1.124 +         fl += 2*di*LAPLACE_MINP;
   1.125 +      }
   1.126 +      if (fm < fl+fs)
   1.127 +         val = -val;
   1.128 +      else
   1.129 +         fl += fs;
   1.130 +   }
   1.131 +   celt_assert(fl<32768);
   1.132 +   celt_assert(fs>0);
   1.133 +   celt_assert(fl<=fm);
   1.134 +   celt_assert(fm<IMIN(fl+fs,32768));
   1.135 +   ec_dec_update(dec, fl, IMIN(fl+fs,32768), 32768);
   1.136 +   return val;
   1.137 +}

mercurial