Moving intra decision to quant_coarse_energy()
[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 #ifdef FIXED_POINT
46 /* Mean energy in each band quantized in Q6 */
47 const signed char eMeans[25] = {
48      124,122,115,106,100,
49       95, 91, 90, 99, 96,
50       94, 93, 98, 91, 86,
51       90, 88, 88, 90, 85,
52       64, 64, 64, 64, 64};
53 #else
54 /* Mean energy in each band quantized in Q6 and converted back to float */
55 const celt_word16 eMeans[25] = {
56       7.750000f, 7.625000f, 7.187500f, 6.625000f, 6.250000f,
57       5.937500f, 5.687500f, 5.625000f, 6.187500f, 6.000000f,
58       5.875000f, 5.812500f, 6.125000f, 5.687500f, 5.375000f,
59       5.625000f, 5.500000f, 5.500000f, 5.625000f, 5.312500f,
60       4.000000f, 4.000000f, 4.000000f, 4.000000f, 4.000000f};
61 #endif
62 /* prediction coefficients: 0.9, 0.8, 0.65, 0.5 */
63 #ifdef FIXED_POINT
64 static const celt_word16 pred_coef[4] = {29440, 26112, 21248, 16384};
65 #else
66 static const celt_word16 pred_coef[4] = {29440/32768., 26112/32768., 21248/32768., 16384/32768.};
67 #endif
68
69 static int intra_decision(const celt_word16 *eBands, celt_word16 *oldEBands, int start, int end, int len, int C)
70 {
71    int c, i;
72    celt_word32 dist = 0;
73    for (c=0;c<C;c++)
74    {
75       for (i=start;i<end;i++)
76       {
77          celt_word16 d = SUB16(eBands[i+c*len], oldEBands[i+c*len]);
78          dist = MAC16_16(dist, d,d);
79       }
80    }
81    return SHR32(dist,2*DB_SHIFT) > 2*C*(end-start);
82 }
83
84 int *quant_prob_alloc(const CELTMode *m)
85 {
86    int i;
87    int *prob;
88    prob = celt_alloc(4*m->nbEBands*sizeof(int));
89    if (prob==NULL)
90      return NULL;
91    for (i=0;i<m->nbEBands;i++)
92    {
93       prob[2*i] = 7000-i*200;
94       prob[2*i+1] = ec_laplace_get_start_freq(prob[2*i]);
95    }
96    for (i=0;i<m->nbEBands;i++)
97    {
98       prob[2*m->nbEBands+2*i] = 9000-i*220;
99       prob[2*m->nbEBands+2*i+1] = ec_laplace_get_start_freq(prob[2*m->nbEBands+2*i]);
100    }
101    return prob;
102 }
103
104 void quant_prob_free(int *freq)
105 {
106    celt_free(freq);
107 }
108
109 void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
110       const celt_word16 *eBands, celt_word16 *oldEBands, int budget,
111       int *prob, celt_word16 *error, ec_enc *enc, int _C, int LM,
112       int nbAvailableBytes, int force_intra, int *delayedIntra)
113 {
114    int i, c;
115    celt_word32 prev[2] = {0,0};
116    celt_word16 coef;
117    celt_word16 beta;
118    const int C = CHANNELS(_C);
119    int intra;
120    celt_word16 max_decay;
121
122    intra = force_intra || (*delayedIntra && nbAvailableBytes > end);
123    if (/*shortBlocks || */intra_decision(eBands, oldEBands, start, effEnd, m->nbEBands, C))
124       *delayedIntra = 1;
125    else
126       *delayedIntra = 0;
127
128    /* Encode the global flags using a simple probability model
129       (first symbols in the stream) */
130    ec_enc_bit_prob(enc, intra, 8192);
131
132 #ifdef FIXED_POINT
133       max_decay = MIN32(QCONST16(16,DB_SHIFT), SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3));
134 #else
135    max_decay = MIN32(16.f, .125f*nbAvailableBytes);
136 #endif
137
138    coef = pred_coef[LM];
139
140    if (intra)
141    {
142       coef = 0;
143       prob += 2*m->nbEBands;
144    }
145    /* No theoretical justification for this, it just works */
146    beta = MULT16_16_P15(coef,coef);
147    /* Encode at a fixed coarse resolution */
148    for (i=start;i<end;i++)
149    {
150       c=0;
151       do {
152          int bits_left;
153          int qi;
154          celt_word16 q;
155          celt_word16 x;
156          celt_word32 f;
157          x = eBands[i+c*m->nbEBands];
158 #ifdef FIXED_POINT
159          f = SHL32(EXTEND32(x),15) -MULT16_16(coef,oldEBands[i+c*m->nbEBands])-prev[c];
160          /* Rounding to nearest integer here is really important! */
161          qi = (f+QCONST32(.5,DB_SHIFT+15))>>(DB_SHIFT+15);
162 #else
163          f = x-coef*oldEBands[i+c*m->nbEBands]-prev[c];
164          /* Rounding to nearest integer here is really important! */
165          qi = (int)floor(.5f+f);
166 #endif
167          /* Prevent the energy from going down too quickly (e.g. for bands
168             that have just one bin) */
169          if (qi < 0 && x < oldEBands[i+c*m->nbEBands]-max_decay)
170          {
171             qi += SHR16(oldEBands[i+c*m->nbEBands]-max_decay-x, DB_SHIFT);
172             if (qi > 0)
173                qi = 0;
174          }
175          /* If we don't have enough bits to encode all the energy, just assume something safe.
176             We allow slightly busting the budget here */
177          bits_left = budget-(int)ec_enc_tell(enc, 0)-2*C*(end-i);
178          if (bits_left < 24)
179          {
180             if (qi > 1)
181                qi = 1;
182             if (qi < -1)
183                qi = -1;
184             if (bits_left<8)
185                qi = 0;
186          }
187          ec_laplace_encode_start(enc, &qi, prob[2*i], prob[2*i+1]);
188          error[i+c*m->nbEBands] = PSHR32(f,15) - SHL16(qi,DB_SHIFT);
189          q = SHL16(qi,DB_SHIFT);
190          
191          oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]) + prev[c] + SHL32(EXTEND32(q),15), 15);
192          prev[c] = prev[c] + SHL32(EXTEND32(q),15) - MULT16_16(beta,q);
193       } while (++c < C);
194    }
195 }
196
197 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)
198 {
199    int i, c;
200    const int C = CHANNELS(_C);
201
202    /* Encode finer resolution */
203    for (i=start;i<end;i++)
204    {
205       celt_int16 frac = 1<<fine_quant[i];
206       if (fine_quant[i] <= 0)
207          continue;
208       c=0;
209       do {
210          int q2;
211          celt_word16 offset;
212 #ifdef FIXED_POINT
213          /* Has to be without rounding */
214          q2 = (error[i+c*m->nbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]);
215 #else
216          q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac);
217 #endif
218          if (q2 > frac-1)
219             q2 = frac-1;
220          if (q2<0)
221             q2 = 0;
222          ec_enc_bits(enc, q2, fine_quant[i]);
223 #ifdef FIXED_POINT
224          offset = SUB16(SHR16(SHL16(q2,DB_SHIFT)+QCONST16(.5,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
225 #else
226          offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
227 #endif
228          oldEBands[i+c*m->nbEBands] += offset;
229          error[i+c*m->nbEBands] -= offset;
230          /*printf ("%f ", error[i] - offset);*/
231       } while (++c < C);
232    }
233 }
234
235 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)
236 {
237    int i, prio, c;
238    const int C = CHANNELS(_C);
239
240    /* Use up the remaining bits */
241    for (prio=0;prio<2;prio++)
242    {
243       for (i=start;i<end && bits_left>=C ;i++)
244       {
245          if (fine_quant[i] >= 7 || fine_priority[i]!=prio)
246             continue;
247          c=0;
248          do {
249             int q2;
250             celt_word16 offset;
251             q2 = error[i+c*m->nbEBands]<0 ? 0 : 1;
252             ec_enc_bits(enc, q2, 1);
253 #ifdef FIXED_POINT
254             offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5,DB_SHIFT),fine_quant[i]+1);
255 #else
256             offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
257 #endif
258             oldEBands[i+c*m->nbEBands] += offset;
259             bits_left--;
260          } while (++c < C);
261       }
262    }
263 }
264
265 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)
266 {
267    int i, c;
268    celt_word32 prev[2] = {0, 0};
269    celt_word16 coef;
270    celt_word16 beta;
271    const int C = CHANNELS(_C);
272
273    coef = pred_coef[LM];
274
275    if (intra)
276    {
277       coef = 0;
278       prob += 2*m->nbEBands;
279    }
280    /* No theoretical justification for this, it just works */
281    beta = MULT16_16_P15(coef,coef);
282
283    /* Decode at a fixed coarse resolution */
284    for (i=start;i<end;i++)
285    {
286       c=0;
287       do {
288          int qi;
289          celt_word16 q;
290          qi = ec_laplace_decode_start(dec, prob[2*i], prob[2*i+1]);
291          q = SHL16(qi,DB_SHIFT);
292
293          oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]) + prev[c] + SHL32(EXTEND32(q),15), 15);
294          prev[c] = prev[c] + SHL32(EXTEND32(q),15) - MULT16_16(beta,q);
295       } while (++c < C);
296    }
297 }
298
299 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)
300 {
301    int i, c;
302    const int C = CHANNELS(_C);
303    /* Decode finer resolution */
304    for (i=start;i<end;i++)
305    {
306       if (fine_quant[i] <= 0)
307          continue;
308       c=0; 
309       do {
310          int q2;
311          celt_word16 offset;
312          q2 = ec_dec_bits(dec, fine_quant[i]);
313 #ifdef FIXED_POINT
314          offset = SUB16(SHR16(SHL16(q2,DB_SHIFT)+QCONST16(.5,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
315 #else
316          offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
317 #endif
318          oldEBands[i+c*m->nbEBands] += offset;
319       } while (++c < C);
320    }
321 }
322
323 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)
324 {
325    int i, prio, c;
326    const int C = CHANNELS(_C);
327
328    /* Use up the remaining bits */
329    for (prio=0;prio<2;prio++)
330    {
331       for (i=start;i<end && bits_left>=C ;i++)
332       {
333          if (fine_quant[i] >= 7 || fine_priority[i]!=prio)
334             continue;
335          c=0;
336          do {
337             int q2;
338             celt_word16 offset;
339             q2 = ec_dec_bits(dec, 1);
340 #ifdef FIXED_POINT
341             offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5,DB_SHIFT),fine_quant[i]+1);
342 #else
343             offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
344 #endif
345             oldEBands[i+c*m->nbEBands] += offset;
346             bits_left--;
347          } while (++c < C);
348       }
349    }
350 }
351
352 void log2Amp(const CELTMode *m, int start, int end,
353       celt_ener *eBands, celt_word16 *oldEBands, int _C)
354 {
355    int c, i;
356    const int C = CHANNELS(_C);
357    c=0;
358    do {
359       for (i=start;i<m->nbEBands;i++)
360       {
361          celt_word16 lg = oldEBands[i+c*m->nbEBands]
362                         + SHL16((celt_word16)eMeans[i],6);
363          eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(SHL16(lg,11-DB_SHIFT)),4);
364          if (oldEBands[i+c*m->nbEBands] < -QCONST16(14.f,DB_SHIFT))
365             oldEBands[i+c*m->nbEBands] = -QCONST16(14.f,DB_SHIFT);
366       }
367    } while (++c < C);
368 }
369
370 void amp2Log2(const CELTMode *m, int effEnd, int end,
371       celt_ener *bandE, celt_word16 *bandLogE, int _C)
372 {
373    int c, i;
374    const int C = CHANNELS(_C);
375    c=0;
376    do {
377       for (i=0;i<effEnd;i++)
378          bandLogE[i+c*m->nbEBands] =
379                celt_log2(MAX32(QCONST32(.001f,14),SHL32(bandE[i+c*m->nbEBands],2)))
380                - SHL16((celt_word16)eMeans[i],6);
381       for (i=effEnd;i<end;i++)
382          bandLogE[c*m->nbEBands+i] = -QCONST16(14.f,DB_SHIFT);
383    } while (++c < C);
384 }