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 +}