media/libopus/celt/laplace.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* Copyright (c) 2007 CSIRO
michael@0 2 Copyright (c) 2007-2009 Xiph.Org Foundation
michael@0 3 Written by Jean-Marc Valin */
michael@0 4 /*
michael@0 5 Redistribution and use in source and binary forms, with or without
michael@0 6 modification, are permitted provided that the following conditions
michael@0 7 are met:
michael@0 8
michael@0 9 - Redistributions of source code must retain the above copyright
michael@0 10 notice, this list of conditions and the following disclaimer.
michael@0 11
michael@0 12 - Redistributions in binary form must reproduce the above copyright
michael@0 13 notice, this list of conditions and the following disclaimer in the
michael@0 14 documentation and/or other materials provided with the distribution.
michael@0 15
michael@0 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
michael@0 20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
michael@0 21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
michael@0 22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
michael@0 23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
michael@0 24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
michael@0 25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
michael@0 26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 27 */
michael@0 28
michael@0 29 #ifdef HAVE_CONFIG_H
michael@0 30 #include "config.h"
michael@0 31 #endif
michael@0 32
michael@0 33 #include "laplace.h"
michael@0 34 #include "mathops.h"
michael@0 35
michael@0 36 /* The minimum probability of an energy delta (out of 32768). */
michael@0 37 #define LAPLACE_LOG_MINP (0)
michael@0 38 #define LAPLACE_MINP (1<<LAPLACE_LOG_MINP)
michael@0 39 /* The minimum number of guaranteed representable energy deltas (in one
michael@0 40 direction). */
michael@0 41 #define LAPLACE_NMIN (16)
michael@0 42
michael@0 43 /* When called, decay is positive and at most 11456. */
michael@0 44 static unsigned ec_laplace_get_freq1(unsigned fs0, int decay)
michael@0 45 {
michael@0 46 unsigned ft;
michael@0 47 ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0;
michael@0 48 return ft*(opus_int32)(16384-decay)>>15;
michael@0 49 }
michael@0 50
michael@0 51 void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay)
michael@0 52 {
michael@0 53 unsigned fl;
michael@0 54 int val = *value;
michael@0 55 fl = 0;
michael@0 56 if (val)
michael@0 57 {
michael@0 58 int s;
michael@0 59 int i;
michael@0 60 s = -(val<0);
michael@0 61 val = (val+s)^s;
michael@0 62 fl = fs;
michael@0 63 fs = ec_laplace_get_freq1(fs, decay);
michael@0 64 /* Search the decaying part of the PDF.*/
michael@0 65 for (i=1; fs > 0 && i < val; i++)
michael@0 66 {
michael@0 67 fs *= 2;
michael@0 68 fl += fs+2*LAPLACE_MINP;
michael@0 69 fs = (fs*(opus_int32)decay)>>15;
michael@0 70 }
michael@0 71 /* Everything beyond that has probability LAPLACE_MINP. */
michael@0 72 if (!fs)
michael@0 73 {
michael@0 74 int di;
michael@0 75 int ndi_max;
michael@0 76 ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP;
michael@0 77 ndi_max = (ndi_max-s)>>1;
michael@0 78 di = IMIN(val - i, ndi_max - 1);
michael@0 79 fl += (2*di+1+s)*LAPLACE_MINP;
michael@0 80 fs = IMIN(LAPLACE_MINP, 32768-fl);
michael@0 81 *value = (i+di+s)^s;
michael@0 82 }
michael@0 83 else
michael@0 84 {
michael@0 85 fs += LAPLACE_MINP;
michael@0 86 fl += fs&~s;
michael@0 87 }
michael@0 88 celt_assert(fl+fs<=32768);
michael@0 89 celt_assert(fs>0);
michael@0 90 }
michael@0 91 ec_encode_bin(enc, fl, fl+fs, 15);
michael@0 92 }
michael@0 93
michael@0 94 int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay)
michael@0 95 {
michael@0 96 int val=0;
michael@0 97 unsigned fl;
michael@0 98 unsigned fm;
michael@0 99 fm = ec_decode_bin(dec, 15);
michael@0 100 fl = 0;
michael@0 101 if (fm >= fs)
michael@0 102 {
michael@0 103 val++;
michael@0 104 fl = fs;
michael@0 105 fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP;
michael@0 106 /* Search the decaying part of the PDF.*/
michael@0 107 while(fs > LAPLACE_MINP && fm >= fl+2*fs)
michael@0 108 {
michael@0 109 fs *= 2;
michael@0 110 fl += fs;
michael@0 111 fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15;
michael@0 112 fs += LAPLACE_MINP;
michael@0 113 val++;
michael@0 114 }
michael@0 115 /* Everything beyond that has probability LAPLACE_MINP. */
michael@0 116 if (fs <= LAPLACE_MINP)
michael@0 117 {
michael@0 118 int di;
michael@0 119 di = (fm-fl)>>(LAPLACE_LOG_MINP+1);
michael@0 120 val += di;
michael@0 121 fl += 2*di*LAPLACE_MINP;
michael@0 122 }
michael@0 123 if (fm < fl+fs)
michael@0 124 val = -val;
michael@0 125 else
michael@0 126 fl += fs;
michael@0 127 }
michael@0 128 celt_assert(fl<32768);
michael@0 129 celt_assert(fs>0);
michael@0 130 celt_assert(fl<=fm);
michael@0 131 celt_assert(fm<IMIN(fl+fs,32768));
michael@0 132 ec_dec_update(dec, fl, IMIN(fl+fs,32768), 32768);
michael@0 133 return val;
michael@0 134 }

mercurial