Energy quantization tuning.
[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 (3)
46
47 static const celt_word16 eMeans[E_MEANS_SIZE] = {QCONST16(7.5f,DB_SHIFT), -QCONST16(1.f,DB_SHIFT), -QCONST16(.5f,DB_SHIFT)};
48
49 /* prediction coefficients: 0.9, 0.8, 0.65, 0.5 */
50 #ifdef FIXED_POINT
51 static const celt_word16 pred_coef[4] = {29440, 26112, 21248, 16384};
52 #else
53 static const celt_word16 pred_coef[4] = {29440/32768., 26112/32768., 21248/32768., 16384/32768.};
54 #endif
55
56 /* FIXME: Implement for stereo */
57 int intra_decision(celt_word16 *eBands, celt_word16 *oldEBands, int len)
58 {
59    int i;
60    celt_word32 dist = 0;
61    for (i=0;i<len;i++)
62    {
63       celt_word16 d = SUB16(eBands[i], oldEBands[i]);
64       dist = MAC16_16(dist, d,d);
65    }
66    return SHR32(dist,2*DB_SHIFT) > 2*len;
67 }
68
69 int *quant_prob_alloc(const CELTMode *m)
70 {
71    int i;
72    int *prob;
73    prob = celt_alloc(4*m->nbEBands*sizeof(int));
74    if (prob==NULL)
75      return NULL;
76    for (i=0;i<m->nbEBands;i++)
77    {
78       prob[2*i] = 7000-i*200;
79       prob[2*i+1] = ec_laplace_get_start_freq(prob[2*i]);
80    }
81    for (i=0;i<m->nbEBands;i++)
82    {
83       prob[2*m->nbEBands+2*i] = 9000-i*220;
84       prob[2*m->nbEBands+2*i+1] = ec_laplace_get_start_freq(prob[2*m->nbEBands+2*i]);
85    }
86    return prob;
87 }
88
89 void quant_prob_free(int *freq)
90 {
91    celt_free(freq);
92 }
93
94 void quant_coarse_energy(const CELTMode *m, int start, int end, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, int LM, celt_word16 max_decay)
95 {
96    int i, c;
97    celt_word32 prev[2] = {0,0};
98    celt_word16 coef;
99    celt_word16 beta;
100    const int C = CHANNELS(_C);
101
102    coef = pred_coef[LM];
103
104    if (intra)
105    {
106       coef = 0;
107       prob += 2*m->nbEBands;
108    }
109    /* No theoretical justification for this, it just works */
110    beta = MULT16_16_P15(coef,coef);
111    /* Encode at a fixed coarse resolution */
112    for (i=start;i<end;i++)
113    {
114       c=0;
115       do {
116          int bits_left;
117          int qi;
118          celt_word16 q;
119          celt_word16 x;
120          celt_word32 f;
121          celt_word32 mean =  (i-start < E_MEANS_SIZE) ? SUB32(SHL32(EXTEND32(eMeans[i-start]),15), MULT16_16(coef,eMeans[i-start])) : 0;
122          x = eBands[i+c*m->nbEBands];
123 #ifdef FIXED_POINT
124          f = SHL32(EXTEND32(x),15)-mean -MULT16_16(coef,oldEBands[i+c*m->nbEBands])-prev[c];
125          /* Rounding to nearest integer here is really important! */
126          qi = (f+QCONST32(.5,DB_SHIFT+15))>>(DB_SHIFT+15);
127 #else
128          f = x-mean-coef*oldEBands[i+c*m->nbEBands]-prev[c];
129          /* Rounding to nearest integer here is really important! */
130          qi = (int)floor(.5f+f);
131 #endif
132          /* Prevent the energy from going down too quickly (e.g. for bands
133             that have just one bin) */
134          if (qi < 0 && x < oldEBands[i+c*m->nbEBands]-max_decay)
135          {
136             qi += SHR16(oldEBands[i+c*m->nbEBands]-max_decay-x, DB_SHIFT);
137             if (qi > 0)
138                qi = 0;
139          }
140          /* If we don't have enough bits to encode all the energy, just assume something safe.
141             We allow slightly busting the budget here */
142          bits_left = budget-(int)ec_enc_tell(enc, 0)-2*C*(end-i);
143          if (bits_left < 24)
144          {
145             if (qi > 1)
146                qi = 1;
147             if (qi < -1)
148                qi = -1;
149             if (bits_left<8)
150                qi = 0;
151          }
152          ec_laplace_encode_start(enc, &qi, prob[2*i], prob[2*i+1]);
153          error[i+c*m->nbEBands] = PSHR32(f,15) - SHL16(qi,DB_SHIFT);
154          q = SHL16(qi,DB_SHIFT);
155          
156          oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]) + mean + prev[c] + SHL32(EXTEND32(q),15), 15);
157          prev[c] = mean + prev[c] + SHL32(EXTEND32(q),15) - MULT16_16(beta,q);
158       } while (++c < C);
159    }
160 }
161
162 void quant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C)
163 {
164    int i, c;
165    const int C = CHANNELS(_C);
166
167    /* Encode finer resolution */
168    for (i=start;i<end;i++)
169    {
170       celt_int16 frac = 1<<fine_quant[i];
171       if (fine_quant[i] <= 0)
172          continue;
173       c=0;
174       do {
175          int q2;
176          celt_word16 offset;
177 #ifdef FIXED_POINT
178          /* Has to be without rounding */
179          q2 = (error[i+c*m->nbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]);
180 #else
181          q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac);
182 #endif
183          if (q2 > frac-1)
184             q2 = frac-1;
185          if (q2<0)
186             q2 = 0;
187          ec_enc_bits(enc, q2, fine_quant[i]);
188 #ifdef FIXED_POINT
189          offset = SUB16(SHR16(SHL16(q2,DB_SHIFT)+QCONST16(.5,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
190 #else
191          offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
192 #endif
193          oldEBands[i+c*m->nbEBands] += offset;
194          error[i+c*m->nbEBands] -= offset;
195          /*printf ("%f ", error[i] - offset);*/
196       } while (++c < C);
197    }
198 }
199
200 void quant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C)
201 {
202    int i, prio, c;
203    const int C = CHANNELS(_C);
204
205    /* Use up the remaining bits */
206    for (prio=0;prio<2;prio++)
207    {
208       for (i=start;i<end && bits_left>=C ;i++)
209       {
210          if (fine_quant[i] >= 7 || fine_priority[i]!=prio)
211             continue;
212          c=0;
213          do {
214             int q2;
215             celt_word16 offset;
216             q2 = error[i+c*m->nbEBands]<0 ? 0 : 1;
217             ec_enc_bits(enc, q2, 1);
218 #ifdef FIXED_POINT
219             offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5,DB_SHIFT),fine_quant[i]+1);
220 #else
221             offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
222 #endif
223             oldEBands[i+c*m->nbEBands] += offset;
224             bits_left--;
225          } while (++c < C);
226       }
227    }
228    c=0;
229    do {
230       for (i=start;i<m->nbEBands;i++)
231       {
232          eBands[i+c*m->nbEBands] = log2Amp(oldEBands[i+c*m->nbEBands]);
233          if (oldEBands[i+c*m->nbEBands] < -QCONST16(7.f,DB_SHIFT))
234             oldEBands[i+c*m->nbEBands] = -QCONST16(7.f,DB_SHIFT);
235       }
236    } while (++c < C);
237 }
238
239 void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int intra, int *prob, ec_dec *dec, int _C, int LM)
240 {
241    int i, c;
242    celt_word32 prev[2] = {0, 0};
243    celt_word16 coef;
244    celt_word16 beta;
245    const int C = CHANNELS(_C);
246
247    coef = pred_coef[LM];
248
249    if (intra)
250    {
251       coef = 0;
252       prob += 2*m->nbEBands;
253    }
254    /* No theoretical justification for this, it just works */
255    beta = MULT16_16_P15(coef,coef);
256
257    /* Decode at a fixed coarse resolution */
258    for (i=start;i<end;i++)
259    {
260       c=0;
261       do {
262          int qi;
263          celt_word16 q;
264          celt_word32 mean =  (i-start < E_MEANS_SIZE) ? SUB32(SHL32(EXTEND32(eMeans[i-start]),15), MULT16_16(coef,eMeans[i-start])) : 0;
265          qi = ec_laplace_decode_start(dec, prob[2*i], prob[2*i+1]);
266          q = SHL16(qi,DB_SHIFT);
267
268          oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]) + mean + prev[c] + SHL32(EXTEND32(q),15), 15);
269          prev[c] = mean + prev[c] + SHL32(EXTEND32(q),15) - MULT16_16(beta,q);
270       } while (++c < C);
271    }
272 }
273
274 void unquant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C)
275 {
276    int i, c;
277    const int C = CHANNELS(_C);
278    /* Decode finer resolution */
279    for (i=start;i<end;i++)
280    {
281       if (fine_quant[i] <= 0)
282          continue;
283       c=0; 
284       do {
285          int q2;
286          celt_word16 offset;
287          q2 = ec_dec_bits(dec, fine_quant[i]);
288 #ifdef FIXED_POINT
289          offset = SUB16(SHR16(SHL16(q2,DB_SHIFT)+QCONST16(.5,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
290 #else
291          offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
292 #endif
293          oldEBands[i+c*m->nbEBands] += offset;
294       } while (++c < C);
295    }
296 }
297
298 void unquant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant,  int *fine_priority, int bits_left, ec_dec *dec, int _C)
299 {
300    int i, prio, c;
301    const int C = CHANNELS(_C);
302
303    /* Use up the remaining bits */
304    for (prio=0;prio<2;prio++)
305    {
306       for (i=start;i<end && bits_left>=C ;i++)
307       {
308          if (fine_quant[i] >= 7 || fine_priority[i]!=prio)
309             continue;
310          c=0;
311          do {
312             int q2;
313             celt_word16 offset;
314             q2 = ec_dec_bits(dec, 1);
315 #ifdef FIXED_POINT
316             offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5,DB_SHIFT),fine_quant[i]+1);
317 #else
318             offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
319 #endif
320             oldEBands[i+c*m->nbEBands] += offset;
321             bits_left--;
322          } while (++c < C);
323       }
324    }
325    c=0;
326    do {
327       for (i=start;i<m->nbEBands;i++)
328       {
329          eBands[i+c*m->nbEBands] = log2Amp(oldEBands[i+c*m->nbEBands]);
330          if (oldEBands[i+c*m->nbEBands] < -QCONST16(7.f,DB_SHIFT))
331             oldEBands[i+c*m->nbEBands] = -QCONST16(7.f,DB_SHIFT);
332       }
333    } while (++c < C);
334 }