Preventing encoder/decoder mismatch when coarse energy budget is busted
[opus.git] / libcelt / quant_bands.c
1 /* (C) 2007-2008 Jean-Marc Valin, CSIRO
2 */
3 /*
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7    
8    - Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10    
11    - Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14    
15    - Neither the name of the Xiph.org Foundation nor the names of its
16    contributors may be used to endorse or promote products derived from
17    this software without specific prior written permission.
18    
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include "quant_bands.h"
37 #include "laplace.h"
38 #include <math.h>
39 #include "os_support.h"
40 #include "arch.h"
41 #include "mathops.h"
42 #include "stack_alloc.h"
43
44 #ifdef FIXED_POINT
45 const celt_word16_t eMeans[24] = {11520, -2048, -3072, -640, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
46 #else
47 const celt_word16_t eMeans[24] = {45.f, -8.f, -12.f, -2.5f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
48 #endif
49
50
51 #ifdef FIXED_POINT
52 static inline celt_ener_t dB2Amp(celt_ener_t dB)
53 {
54    celt_ener_t amp;
55    amp = PSHR32(celt_exp2(MULT16_16_Q14(21771,dB)),2)-QCONST16(.3f, 14);
56    if (amp < 0)
57       amp = 0;
58    return amp;
59 }
60
61 #define DBofTWO 24661
62 static inline celt_word16_t amp2dB(celt_ener_t amp)
63 {
64    /* equivalent to return 6.0207*log2(.3+amp) */
65    return ROUND16(MULT16_16(24661,celt_log2(ADD32(QCONST32(.3f,14),amp))),12);
66    /* return DB_SCALING*20*log10(.3+ENER_SCALING_1*amp); */
67 }
68 #else
69 static inline celt_ener_t dB2Amp(celt_ener_t dB)
70 {
71    celt_ener_t amp;
72    amp = pow(10, .05*dB)-.3;
73    if (amp < 0)
74       amp = 0;
75    return amp;
76 }
77 static inline celt_word16_t amp2dB(celt_ener_t amp)
78 {
79    return 20*log10(.3+amp);
80 }
81 #endif
82
83 static const celt_word16_t base_resolution = QCONST16(6.f,8);
84
85 int *quant_prob_alloc(const CELTMode *m)
86 {
87    int i;
88    int *prob;
89    prob = celt_alloc(2*m->nbEBands*sizeof(int));
90    for (i=0;i<m->nbEBands;i++)
91    {
92       prob[2*i] = 6000-i*200;
93       prob[2*i+1] = ec_laplace_get_start_freq(prob[2*i]);
94    }
95    return prob;
96 }
97
98 void quant_prob_free(int *freq)
99 {
100    celt_free(freq);
101 }
102
103 static void quant_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, unsigned budget, int *prob, celt_word16_t *error, ec_enc *enc)
104 {
105    int i;
106    unsigned bits;
107    celt_word16_t prev = 0;
108    celt_word16_t coef = m->ePredCoef;
109    celt_word16_t beta;
110    /* The .7 is a heuristic */
111    beta = MULT16_16_Q15(QCONST16(.8f,15),coef);
112    
113    bits = ec_enc_tell(enc, 0);
114    /* Encode at a fixed coarse resolution */
115    for (i=0;i<m->nbEBands;i++)
116    {
117       int qi;
118       celt_word16_t q;   /* dB */
119       celt_word16_t x;   /* dB */
120       celt_word16_t f;   /* Q8 */
121       celt_word16_t mean = MULT16_16_Q15(Q15ONE-coef,eMeans[i]);
122       x = amp2dB(eBands[i]);
123       f = EXTRACT16(celt_div(SHL32(EXTEND32(x-mean-MULT16_16_Q15(coef,oldEBands[i])-prev),8),base_resolution));
124 #ifdef FIXED_POINT
125       /* Rounding to nearest integer here is really important! */
126       qi = (f+128)>>8;
127 #else
128       qi = (int)floor(.5+f);
129 #endif
130       /* If we don't have enough bits to encode all the energy, just assume something safe.
131          We allow slightly busting the budget here */
132       if (ec_enc_tell(enc, 0) - bits > budget)
133       {
134          qi = -1;
135          error[i] = 128;
136       } else {
137          ec_laplace_encode_start(enc, &qi, prob[2*i], prob[2*i+1]);
138          error[i] = f - SHL16(qi,8);
139       }
140       q = qi*base_resolution;
141       
142       oldEBands[i] = mean+MULT16_16_Q15(coef,oldEBands[i])+prev+q;
143       if (oldEBands[i] < -QCONST16(12.f,8))
144          oldEBands[i] = -QCONST16(12.f,8);
145       prev = mean+prev+MULT16_16_Q15(Q15ONE-beta,q);
146    }
147 }
148
149 static void quant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, ec_enc *enc)
150 {
151    int i;
152    /* Encode finer resolution */
153    for (i=0;i<m->nbEBands;i++)
154    {
155       int q2;
156       celt_int16_t frac = 1<<fine_quant[i];
157       celt_word16_t offset = (error[i]+QCONST16(.5f,8))*frac;
158       if (fine_quant[i] <= 0)
159          continue;
160 #ifdef FIXED_POINT
161       /* Has to be without rounding */
162       q2 = offset>>8;
163 #else
164       q2 = (int)floor(offset);
165 #endif
166       if (q2 > frac-1)
167          q2 = frac-1;
168       ec_enc_bits(enc, q2, fine_quant[i]);
169       offset = EXTRACT16(celt_div(SHL16(q2,8)+QCONST16(.5,8),frac)-QCONST16(.5f,8));
170       oldEBands[i] += PSHR32(MULT16_16(DB_SCALING*6,offset),8);
171       /*printf ("%f ", error[i] - offset);*/
172    }
173    for (i=0;i<m->nbEBands;i++)
174    {
175       eBands[i] = dB2Amp(oldEBands[i]);
176    }
177    /*printf ("%d\n", ec_enc_tell(enc, 0)-9);*/
178
179    /*printf ("\n");*/
180 }
181
182 static void unquant_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, unsigned budget, int *prob, ec_dec *dec)
183 {
184    int i;
185    unsigned bits;
186    celt_word16_t prev = 0;
187    celt_word16_t coef = m->ePredCoef;
188    /* The .7 is a heuristic */
189    celt_word16_t beta = MULT16_16_Q15(QCONST16(.8f,15),coef);
190    
191    bits = ec_dec_tell(dec, 0);
192    /* Decode at a fixed coarse resolution */
193    for (i=0;i<m->nbEBands;i++)
194    {
195       int qi;
196       celt_word16_t q;
197       celt_word16_t mean = MULT16_16_Q15(Q15ONE-coef,eMeans[i]);
198       /* If we didn't have enough bits to encode all the energy, just assume something safe.
199          We allow slightly busting the budget here */
200       if (ec_dec_tell(dec, 0) - bits > budget)
201          qi = -1;
202       else
203          qi = ec_laplace_decode_start(dec, prob[2*i], prob[2*i+1]);
204       q = qi*base_resolution;
205       
206       oldEBands[i] = mean+MULT16_16_Q15(coef,oldEBands[i])+prev+q;
207       if (oldEBands[i] < -QCONST16(12.f,8))
208          oldEBands[i] = -QCONST16(12.f,8);
209       
210       prev = mean+prev+MULT16_16_Q15(Q15ONE-beta,q);
211    }
212 }
213
214 static void unquant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec)
215 {
216    int i;
217    /* Decode finer resolution */
218    for (i=0;i<m->nbEBands;i++)
219    {
220       int q2;
221       celt_int16_t frac = 1<<fine_quant[i];
222       celt_word16_t offset;
223       if (fine_quant[i] <= 0)
224          continue;
225       q2 = ec_dec_bits(dec, fine_quant[i]);
226       offset = EXTRACT16(celt_div(SHL16(q2,8)+QCONST16(.5,8),frac)-QCONST16(.5f,8));
227       oldEBands[i] += PSHR32(MULT16_16(DB_SCALING*6,offset),8);
228    }
229    for (i=0;i<m->nbEBands;i++)
230    {
231       eBands[i] = dB2Amp(oldEBands[i]);
232    }
233    /*printf ("\n");*/
234 }
235
236
237
238 void quant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, celt_word16_t *error, ec_enc *enc)
239 {
240    int C;
241    C = m->nbChannels;
242
243    if (C==1)
244    {
245       quant_coarse_energy_mono(m, eBands, oldEBands, budget, prob, error, enc);
246
247    } else {
248       int c;
249       for (c=0;c<C;c++)
250       {
251          int i;
252          VARDECL(celt_ener_t, E);
253          SAVE_STACK;
254          ALLOC(E, m->nbEBands, celt_ener_t);
255          for (i=0;i<m->nbEBands;i++)
256             E[i] = eBands[C*i+c];
257          quant_coarse_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, prob, error+c*m->nbEBands, enc);
258       }
259       RESTORE_STACK;
260    }
261 }
262
263 void quant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, ec_enc *enc)
264 {
265    int C;
266    C = m->nbChannels;
267
268    if (C==1)
269    {
270       quant_fine_energy_mono(m, eBands, oldEBands, error, fine_quant, enc);
271
272    } else {
273       int c;
274       VARDECL(celt_ener_t, E);
275       ALLOC(E, m->nbEBands, celt_ener_t);
276       for (c=0;c<C;c++)
277       {
278          int i;
279          SAVE_STACK;
280          quant_fine_energy_mono(m, E, oldEBands+c*m->nbEBands, error+c*m->nbEBands, fine_quant, enc);
281          for (i=0;i<m->nbEBands;i++)
282             eBands[C*i+c] = E[i];
283       }
284       RESTORE_STACK;
285    }
286 }
287
288
289 void unquant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, ec_dec *dec)
290 {
291    int C;   
292
293    C = m->nbChannels;
294    if (C==1)
295    {
296       unquant_coarse_energy_mono(m, eBands, oldEBands, budget, prob, dec);
297    }
298    else {
299       int c;
300       VARDECL(celt_ener_t, E);
301       SAVE_STACK;
302       ALLOC(E, m->nbEBands, celt_ener_t);
303       for (c=0;c<C;c++)
304       {
305          unquant_coarse_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, prob, dec);
306       }
307       RESTORE_STACK;
308    }
309 }
310
311 void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec)
312 {
313    int C;   
314
315    C = m->nbChannels;
316
317    if (C==1)
318    {
319       unquant_fine_energy_mono(m, eBands, oldEBands, fine_quant, dec);
320    }
321    else {
322       int c;
323       VARDECL(celt_ener_t, E);
324       SAVE_STACK;
325       ALLOC(E, m->nbEBands, celt_ener_t);
326       for (c=0;c<C;c++)
327       {
328          int i;
329          unquant_fine_energy_mono(m, E, oldEBands+c*m->nbEBands, fine_quant, dec);
330          for (i=0;i<m->nbEBands;i++)
331             eBands[C*i+c] = E[i];
332       }
333       RESTORE_STACK;
334    }
335 }