Removed unnecessary calls to log2Amp()
[opus.git] / libcelt / quant_bands.c
1 /* Copyright (c) 2007-2008 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    - Neither the name of the Xiph.org Foundation nor the names of its
17    contributors may be used to endorse or promote products derived from
18    this software without specific prior written permission.
19    
20    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #include "quant_bands.h"
38 #include "laplace.h"
39 #include <math.h>
40 #include "os_support.h"
41 #include "arch.h"
42 #include "mathops.h"
43 #include "stack_alloc.h"
44
45 #define E_MEANS_SIZE (5)
46
47 const celt_word16 eMeans[E_MEANS_SIZE] = {QCONST16(7.5f,DB_SHIFT), -QCONST16(1.33f,DB_SHIFT), -QCONST16(2.f,DB_SHIFT), -QCONST16(0.42f,DB_SHIFT), QCONST16(0.17f,DB_SHIFT)};
48
49 /* FIXME: Implement for stereo */
50 int intra_decision(celt_word16 *eBands, celt_word16 *oldEBands, int len)
51 {
52    int i;
53    celt_word32 dist = 0;
54    for (i=0;i<len;i++)
55    {
56       celt_word16 d = SUB16(eBands[i], oldEBands[i]);
57       dist = MAC16_16(dist, d,d);
58    }
59    return SHR32(dist,2*DB_SHIFT) > 2*len;
60 }
61
62 int *quant_prob_alloc(const CELTMode *m)
63 {
64    int i;
65    int *prob;
66    prob = celt_alloc(4*m->nbEBands*sizeof(int));
67    if (prob==NULL)
68      return NULL;
69    for (i=0;i<m->nbEBands;i++)
70    {
71       prob[2*i] = 6000-i*200;
72       prob[2*i+1] = ec_laplace_get_start_freq(prob[2*i]);
73    }
74    for (i=0;i<m->nbEBands;i++)
75    {
76       prob[2*m->nbEBands+2*i] = 9000-i*240;
77       prob[2*m->nbEBands+2*i+1] = ec_laplace_get_start_freq(prob[2*m->nbEBands+2*i]);
78    }
79    return prob;
80 }
81
82 void quant_prob_free(int *freq)
83 {
84    celt_free(freq);
85 }
86
87 unsigned quant_coarse_energy(const CELTMode *m, int start, celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C)
88 {
89    int i, c;
90    unsigned bits_used = 0;
91    celt_word32 prev[2] = {0,0};
92    celt_word16 coef = m->ePredCoef;
93    celt_word16 beta;
94    const int C = CHANNELS(_C);
95
96    if (intra)
97    {
98       coef = 0;
99       prob += 2*m->nbEBands;
100    }
101    /* The .8 is a heuristic */
102    beta = MULT16_16_P15(QCONST16(.8f,15),coef);
103
104    /* Encode at a fixed coarse resolution */
105    for (i=start;i<m->nbEBands;i++)
106    {
107       c=0;
108       do {
109          int qi;
110          celt_word16 q;
111          celt_word16 x;
112          celt_word32 f;
113          celt_word32 mean =  (i-start < E_MEANS_SIZE) ? SUB32(SHL32(EXTEND32(eMeans[i-start]),15), MULT16_16(coef,eMeans[i-start])) : 0;
114          x = eBands[i+c*m->nbEBands];
115 #ifdef FIXED_POINT
116          f = SHL32(EXTEND32(x),15)-mean -MULT16_16(coef,oldEBands[i+c*m->nbEBands])-prev[c];
117          /* Rounding to nearest integer here is really important! */
118          qi = (f+QCONST32(.5,DB_SHIFT+15))>>(DB_SHIFT+15);
119 #else
120          f = x-mean-coef*oldEBands[i+c*m->nbEBands]-prev[c];
121          /* Rounding to nearest integer here is really important! */
122          qi = (int)floor(.5f+f);
123 #endif
124          /* If we don't have enough bits to encode all the energy, just assume something safe.
125             We allow slightly busting the budget here */
126          bits_used=ec_enc_tell(enc, 0);
127          if (bits_used > budget)
128          {
129             qi = -1;
130             error[i+c*m->nbEBands] = QCONST16(.5f,DB_SHIFT);
131          } else {
132             ec_laplace_encode_start(enc, &qi, prob[2*i], prob[2*i+1]);
133             error[i+c*m->nbEBands] = PSHR32(f,15) - SHL16(qi,DB_SHIFT);
134          }
135          q = SHL16(qi,DB_SHIFT);
136          
137          oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]) + mean + prev[c] + SHL32(EXTEND32(q),15), 15);
138          prev[c] = mean + prev[c] + SHL32(EXTEND32(q),15) - MULT16_16(beta,q);
139       } while (++c < C);
140    }
141    return bits_used;
142 }
143
144 void quant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C)
145 {
146    int i, c;
147    const int C = CHANNELS(_C);
148
149    /* Encode finer resolution */
150    for (i=start;i<m->nbEBands;i++)
151    {
152       celt_int16 frac = 1<<fine_quant[i];
153       if (fine_quant[i] <= 0)
154          continue;
155       c=0;
156       do {
157          int q2;
158          celt_word16 offset;
159 #ifdef FIXED_POINT
160          /* Has to be without rounding */
161          q2 = (error[i+c*m->nbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]);
162 #else
163          q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac);
164 #endif
165          if (q2 > frac-1)
166             q2 = frac-1;
167          ec_enc_bits(enc, q2, fine_quant[i]);
168 #ifdef FIXED_POINT
169          offset = SUB16(SHR16(SHL16(q2,DB_SHIFT)+QCONST16(.5,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
170 #else
171          offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
172 #endif
173          oldEBands[i+c*m->nbEBands] += offset;
174          error[i+c*m->nbEBands] -= offset;
175          /*printf ("%f ", error[i] - offset);*/
176       } while (++c < C);
177    }
178    for (i=start;i<C*m->nbEBands;i++)
179       eBands[i] = log2Amp(oldEBands[i]);
180 }
181
182 void quant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C)
183 {
184    int i, prio, c;
185    const int C = CHANNELS(_C);
186
187    /* Use up the remaining bits */
188    for (prio=0;prio<2;prio++)
189    {
190       for (i=start;i<m->nbEBands && bits_left>=C ;i++)
191       {
192          if (fine_quant[i] >= 7 || fine_priority[i]!=prio)
193             continue;
194          c=0;
195          do {
196             int q2;
197             celt_word16 offset;
198             q2 = error[i+c*m->nbEBands]<0 ? 0 : 1;
199             ec_enc_bits(enc, q2, 1);
200 #ifdef FIXED_POINT
201             offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5,DB_SHIFT),fine_quant[i]+1);
202 #else
203             offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
204 #endif
205             oldEBands[i+c*m->nbEBands] += offset;
206             eBands[i+c*m->nbEBands] = log2Amp(oldEBands[i+c*m->nbEBands]);
207             bits_left--;
208          } while (++c < C);
209       }
210    }
211    for (i=start;i<C*m->nbEBands;i++)
212    {
213       if (oldEBands[i] < -QCONST16(7.f,DB_SHIFT))
214          oldEBands[i] = -QCONST16(7.f,DB_SHIFT);
215    }
216 }
217
218 void unquant_coarse_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C)
219 {
220    int i, c;
221    celt_word32 prev[2] = {0, 0};
222    celt_word16 coef = m->ePredCoef;
223    celt_word16 beta;
224    const int C = CHANNELS(_C);
225
226    if (intra)
227    {
228       coef = 0;
229       prob += 2*m->nbEBands;
230    }
231    /* The .8 is a heuristic */
232    beta = MULT16_16_P15(QCONST16(.8f,15),coef);
233
234    /* Decode at a fixed coarse resolution */
235    for (i=start;i<m->nbEBands;i++)
236    {
237       c=0;
238       do {
239          int qi;
240          celt_word16 q;
241          celt_word32 mean =  (i-start < E_MEANS_SIZE) ? SUB32(SHL32(EXTEND32(eMeans[i-start]),15), MULT16_16(coef,eMeans[i-start])) : 0;
242          /* If we didn't have enough bits to encode all the energy, just assume something safe.
243             We allow slightly busting the budget here */
244          if (ec_dec_tell(dec, 0) > budget)
245             qi = -1;
246          else
247             qi = ec_laplace_decode_start(dec, prob[2*i], prob[2*i+1]);
248          q = SHL16(qi,DB_SHIFT);
249
250          oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]) + mean + prev[c] + SHL32(EXTEND32(q),15), 15);
251          prev[c] = mean + prev[c] + SHL32(EXTEND32(q),15) - MULT16_16(beta,q);
252       } while (++c < C);
253    }
254 }
255
256 void unquant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C)
257 {
258    int i, c;
259    const int C = CHANNELS(_C);
260    /* Decode finer resolution */
261    for (i=start;i<m->nbEBands;i++)
262    {
263       if (fine_quant[i] <= 0)
264          continue;
265       c=0; 
266       do {
267          int q2;
268          celt_word16 offset;
269          q2 = ec_dec_bits(dec, fine_quant[i]);
270 #ifdef FIXED_POINT
271          offset = SUB16(SHR16(SHL16(q2,DB_SHIFT)+QCONST16(.5,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
272 #else
273          offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
274 #endif
275          oldEBands[i+c*m->nbEBands] += offset;
276       } while (++c < C);
277    }
278    for (i=start;i<C*m->nbEBands;i++)
279       eBands[i] = log2Amp(oldEBands[i]);
280 }
281
282 void unquant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant,  int *fine_priority, int bits_left, ec_dec *dec, int _C)
283 {
284    int i, prio, c;
285    const int C = CHANNELS(_C);
286
287    /* Use up the remaining bits */
288    for (prio=0;prio<2;prio++)
289    {
290       for (i=start;i<m->nbEBands && bits_left>=C ;i++)
291       {
292          if (fine_quant[i] >= 7 || fine_priority[i]!=prio)
293             continue;
294          c=0;
295          do {
296             int q2;
297             celt_word16 offset;
298             q2 = ec_dec_bits(dec, 1);
299 #ifdef FIXED_POINT
300             offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5,DB_SHIFT),fine_quant[i]+1);
301 #else
302             offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
303 #endif
304             oldEBands[i+c*m->nbEBands] += offset;
305             eBands[i+c*m->nbEBands] = log2Amp(oldEBands[i+c*m->nbEBands]);
306             bits_left--;
307          } while (++c < C);
308       }
309    }
310    for (i=start;i<C*m->nbEBands;i++)
311    {
312       if (oldEBands[i] < -QCONST16(7.f,DB_SHIFT))
313          oldEBands[i] = -QCONST16(7.f,DB_SHIFT);
314    }
315 }