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