Add support for intra-coding of the coarse energy.
[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    if (dB>24659)
56       dB=24659;
57    amp = PSHR32(celt_exp2(MULT16_16_Q14(21771,dB)),2)-QCONST16(.3f, 14);
58    if (amp < 0)
59       amp = 0;
60    return PSHR32(amp,2);
61 }
62
63 #define DBofTWO 24661
64 static inline celt_word16_t amp2dB(celt_ener_t amp)
65 {
66    /* equivalent to return 6.0207*log2(.3+amp) */
67    return ROUND16(MULT16_16(24661,celt_log2(ADD32(QCONST32(.3f,14),SHL32(amp,2)))),12);
68    /* return DB_SCALING*20*log10(.3+ENER_SCALING_1*amp); */
69 }
70 #else
71 static inline celt_ener_t dB2Amp(celt_ener_t dB)
72 {
73    celt_ener_t amp;
74    /*amp = pow(10, .05*dB)-.3;*/
75    amp = exp(0.115129f*dB)-.3f;
76    if (amp < 0)
77       amp = 0;
78    return amp;
79 }
80 static inline celt_word16_t amp2dB(celt_ener_t amp)
81 {
82    /*return 20*log10(.3+amp);*/
83    return 8.68589f*log(.3f+amp);
84 }
85 #endif
86
87 static const celt_word16_t base_resolution = QCONST16(6.f,8);
88 static const celt_word16_t base_resolution_1 = QCONST16(0.1666667f,15);
89
90 int *quant_prob_alloc(const CELTMode *m)
91 {
92    int i;
93    int *prob;
94    prob = celt_alloc(4*m->nbEBands*sizeof(int));
95    for (i=0;i<m->nbEBands;i++)
96    {
97       prob[2*i] = 6000-i*200;
98       prob[2*i+1] = ec_laplace_get_start_freq(prob[2*i]);
99    }
100    for (i=0;i<m->nbEBands;i++)
101    {
102       prob[2*m->nbEBands+2*i] = 9000-i*240;
103       prob[2*m->nbEBands+2*i+1] = ec_laplace_get_start_freq(prob[2*m->nbEBands+2*i]);
104    }
105    return prob;
106 }
107
108 void quant_prob_free(int *freq)
109 {
110    celt_free(freq);
111 }
112
113 static void quant_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, unsigned budget, int intra, int *prob, celt_word16_t *error, ec_enc *enc)
114 {
115    int i;
116    unsigned bits;
117    celt_word16_t prev = 0;
118    celt_word16_t coef = m->ePredCoef;
119    celt_word16_t beta;
120    
121    if (intra)
122    {
123       coef = 0;
124       prob += 2*m->nbEBands;
125    }
126    /* The .8 is a heuristic */
127    beta = MULT16_16_Q15(QCONST16(.8f,15),coef);
128    
129    bits = ec_enc_tell(enc, 0);
130    /* Encode at a fixed coarse resolution */
131    for (i=0;i<m->nbEBands;i++)
132    {
133       int qi;
134       celt_word16_t q;   /* dB */
135       celt_word16_t x;   /* dB */
136       celt_word16_t f;   /* Q8 */
137       celt_word16_t mean = MULT16_16_Q15(Q15ONE-coef,eMeans[i]);
138       x = amp2dB(eBands[i]);
139 #ifdef FIXED_POINT
140       f = MULT16_16_Q15(x-mean-MULT16_16_Q15(coef,oldEBands[i])-prev,base_resolution_1);
141       /* Rounding to nearest integer here is really important! */
142       qi = (f+128)>>8;
143 #else
144       f = (x-mean-coef*oldEBands[i]-prev)*base_resolution_1;
145       /* Rounding to nearest integer here is really important! */
146       qi = (int)floor(.5+f);
147 #endif
148       /* If we don't have enough bits to encode all the energy, just assume something safe.
149          We allow slightly busting the budget here */
150       if (ec_enc_tell(enc, 0) - bits > budget)
151       {
152          qi = -1;
153          error[i] = 128;
154       } else {
155          ec_laplace_encode_start(enc, &qi, prob[2*i], prob[2*i+1]);
156          error[i] = f - SHL16(qi,8);
157       }
158       q = qi*base_resolution;
159       
160       oldEBands[i] = mean+MULT16_16_Q15(coef,oldEBands[i])+prev+q;
161       if (oldEBands[i] < -QCONST16(12.f,8))
162          oldEBands[i] = -QCONST16(12.f,8);
163       prev = mean+prev+MULT16_16_Q15(Q15ONE-beta,q);
164    }
165 }
166
167 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)
168 {
169    int i;
170    /* Encode finer resolution */
171    for (i=0;i<m->nbEBands;i++)
172    {
173       int q2;
174       celt_int16_t frac = 1<<fine_quant[i];
175       celt_word16_t offset = (error[i]+QCONST16(.5f,8))*frac;
176       if (fine_quant[i] <= 0)
177          continue;
178 #ifdef FIXED_POINT
179       /* Has to be without rounding */
180       q2 = offset>>8;
181 #else
182       q2 = (int)floor(offset);
183 #endif
184       if (q2 > frac-1)
185          q2 = frac-1;
186       ec_enc_bits(enc, q2, fine_quant[i]);
187 #ifdef FIXED_POINT
188       offset = SUB16(SHR16(SHL16(q2,8)+QCONST16(.5,8),fine_quant[i]),QCONST16(.5f,8));
189 #else
190       offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
191 #endif
192       oldEBands[i] += PSHR32(MULT16_16(DB_SCALING*6,offset),8);
193       /*printf ("%f ", error[i] - offset);*/
194    }
195    for (i=0;i<m->nbEBands;i++)
196    {
197       eBands[i] = dB2Amp(oldEBands[i]);
198    }
199    /*printf ("%d\n", ec_enc_tell(enc, 0)-9);*/
200
201    /*printf ("\n");*/
202 }
203
204 static void unquant_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, unsigned budget, int intra, int *prob, ec_dec *dec)
205 {
206    int i;
207    unsigned bits;
208    celt_word16_t prev = 0;
209    celt_word16_t coef = m->ePredCoef;
210    celt_word16_t beta;
211    
212    if (intra)
213    {
214       coef = 0;
215       prob += 2*m->nbEBands;
216    }
217    /* The .8 is a heuristic */
218    beta = MULT16_16_Q15(QCONST16(.8f,15),coef);
219    
220    bits = ec_dec_tell(dec, 0);
221    /* Decode at a fixed coarse resolution */
222    for (i=0;i<m->nbEBands;i++)
223    {
224       int qi;
225       celt_word16_t q;
226       celt_word16_t mean = MULT16_16_Q15(Q15ONE-coef,eMeans[i]);
227       /* If we didn't have enough bits to encode all the energy, just assume something safe.
228          We allow slightly busting the budget here */
229       if (ec_dec_tell(dec, 0) - bits > budget)
230          qi = -1;
231       else
232          qi = ec_laplace_decode_start(dec, prob[2*i], prob[2*i+1]);
233       q = qi*base_resolution;
234       
235       oldEBands[i] = mean+MULT16_16_Q15(coef,oldEBands[i])+prev+q;
236       if (oldEBands[i] < -QCONST16(12.f,8))
237          oldEBands[i] = -QCONST16(12.f,8);
238       
239       prev = mean+prev+MULT16_16_Q15(Q15ONE-beta,q);
240    }
241 }
242
243 static void unquant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec)
244 {
245    int i;
246    /* Decode finer resolution */
247    for (i=0;i<m->nbEBands;i++)
248    {
249       int q2;
250       celt_word16_t offset;
251       if (fine_quant[i] <= 0)
252          continue;
253       q2 = ec_dec_bits(dec, fine_quant[i]);
254 #ifdef FIXED_POINT
255       offset = SUB16(SHR16(SHL16(q2,8)+QCONST16(.5,8),fine_quant[i]),QCONST16(.5f,8));
256 #else
257       offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
258 #endif
259       oldEBands[i] += PSHR32(MULT16_16(DB_SCALING*6,offset),8);
260    }
261    for (i=0;i<m->nbEBands;i++)
262    {
263       eBands[i] = dB2Amp(oldEBands[i]);
264    }
265    /*printf ("\n");*/
266 }
267
268
269
270 void quant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int intra, int *prob, celt_word16_t *error, ec_enc *enc)
271 {
272    int C;
273    C = m->nbChannels;
274
275    if (C==1)
276    {
277       quant_coarse_energy_mono(m, eBands, oldEBands, budget, intra, prob, error, enc);
278    } else {
279       int c;
280       for (c=0;c<C;c++)
281       {
282          int i;
283          VARDECL(celt_ener_t, E);
284          SAVE_STACK;
285          ALLOC(E, m->nbEBands, celt_ener_t);
286          for (i=0;i<m->nbEBands;i++)
287             E[i] = eBands[C*i+c];
288          quant_coarse_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, intra, prob, error+c*m->nbEBands, enc);
289          RESTORE_STACK;
290       }
291    }
292 }
293
294 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)
295 {
296    int C;
297    C = m->nbChannels;
298
299    if (C==1)
300    {
301       quant_fine_energy_mono(m, eBands, oldEBands, error, fine_quant, enc);
302
303    } else {
304       int c;
305       VARDECL(celt_ener_t, E);
306       ALLOC(E, m->nbEBands, celt_ener_t);
307       for (c=0;c<C;c++)
308       {
309          int i;
310          SAVE_STACK;
311          quant_fine_energy_mono(m, E, oldEBands+c*m->nbEBands, error+c*m->nbEBands, fine_quant, enc);
312          for (i=0;i<m->nbEBands;i++)
313             eBands[C*i+c] = E[i];
314          RESTORE_STACK;
315       }
316    }
317 }
318
319
320 void unquant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int intra, int *prob, ec_dec *dec)
321 {
322    int C;   
323
324    C = m->nbChannels;
325    if (C==1)
326    {
327       unquant_coarse_energy_mono(m, eBands, oldEBands, budget, intra, prob, dec);
328    }
329    else {
330       int c;
331       VARDECL(celt_ener_t, E);
332       SAVE_STACK;
333       ALLOC(E, m->nbEBands, celt_ener_t);
334       for (c=0;c<C;c++)
335       {
336          unquant_coarse_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, intra, prob, dec);
337       }
338       RESTORE_STACK;
339    }
340 }
341
342 void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec)
343 {
344    int C;   
345
346    C = m->nbChannels;
347
348    if (C==1)
349    {
350       unquant_fine_energy_mono(m, eBands, oldEBands, fine_quant, dec);
351    }
352    else {
353       int c;
354       VARDECL(celt_ener_t, E);
355       SAVE_STACK;
356       ALLOC(E, m->nbEBands, celt_ener_t);
357       for (c=0;c<C;c++)
358       {
359          int i;
360          unquant_fine_energy_mono(m, E, oldEBands+c*m->nbEBands, fine_quant, dec);
361          for (i=0;i<m->nbEBands;i++)
362             eBands[C*i+c] = E[i];
363       }
364       RESTORE_STACK;
365    }
366 }