bcc35b47a2e5a2d01785a8eba4c75f03fa0d9299
[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+16)
133          qi = -1;
134       else
135          ec_laplace_encode_start(enc, &qi, prob[2*i], prob[2*i+1]);
136       q = qi*base_resolution;
137       error[i] = f - SHL16(qi,8);
138       
139       oldEBands[i] = mean+MULT16_16_Q15(coef,oldEBands[i])+prev+q;
140       if (oldEBands[i] < -QCONST16(12.f,8))
141          oldEBands[i] = -QCONST16(12.f,8);
142       prev = mean+prev+MULT16_16_Q15(Q15ONE-beta,q);
143    }
144 }
145
146 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)
147 {
148    int i;
149    /* Encode finer resolution */
150    for (i=0;i<m->nbEBands;i++)
151    {
152       int q2;
153       celt_int16_t frac = 1<<fine_quant[i];
154       celt_word16_t offset = (error[i]+QCONST16(.5f,8))*frac;
155       if (fine_quant[i] <= 0)
156          continue;
157 #ifdef FIXED_POINT
158       /* Has to be without rounding */
159       q2 = offset>>8;
160 #else
161       q2 = (int)floor(offset);
162 #endif
163       if (q2 > frac-1)
164          q2 = frac-1;
165       ec_enc_bits(enc, q2, fine_quant[i]);
166       offset = EXTRACT16(celt_div(SHL16(q2,8)+QCONST16(.5,8),frac)-QCONST16(.5f,8));
167       oldEBands[i] += PSHR32(MULT16_16(DB_SCALING*6,offset),8);
168       /*printf ("%f ", error[i] - offset);*/
169    }
170    for (i=0;i<m->nbEBands;i++)
171    {
172       eBands[i] = dB2Amp(oldEBands[i]);
173    }
174    /*printf ("%d\n", ec_enc_tell(enc, 0)-9);*/
175
176    /*printf ("\n");*/
177 }
178
179 static void unquant_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, unsigned budget, int *prob, ec_dec *dec)
180 {
181    int i;
182    unsigned bits;
183    celt_word16_t prev = 0;
184    celt_word16_t coef = m->ePredCoef;
185    /* The .7 is a heuristic */
186    celt_word16_t beta = MULT16_16_Q15(QCONST16(.8f,15),coef);
187    
188    bits = ec_dec_tell(dec, 0);
189    /* Decode at a fixed coarse resolution */
190    for (i=0;i<m->nbEBands;i++)
191    {
192       int qi;
193       celt_word16_t q;
194       celt_word16_t mean = MULT16_16_Q15(Q15ONE-coef,eMeans[i]);
195       /* If we didn't have enough bits to encode all the energy, just assume something safe.
196          We allow slightly busting the budget here */
197       if (ec_dec_tell(dec, 0) - bits > budget+16)
198          qi = -1;
199       else
200          qi = ec_laplace_decode_start(dec, prob[2*i], prob[2*i+1]);
201       q = qi*base_resolution;
202       
203       oldEBands[i] = mean+MULT16_16_Q15(coef,oldEBands[i])+prev+q;
204       if (oldEBands[i] < -QCONST16(12.f,8))
205          oldEBands[i] = -QCONST16(12.f,8);
206       
207       prev = mean+prev+MULT16_16_Q15(Q15ONE-beta,q);
208    }
209 }
210
211 static void unquant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec)
212 {
213    int i;
214    /* Decode finer resolution */
215    for (i=0;i<m->nbEBands;i++)
216    {
217       int q2;
218       celt_int16_t frac = 1<<fine_quant[i];
219       celt_word16_t offset;
220       if (fine_quant[i] <= 0)
221          continue;
222       q2 = ec_dec_bits(dec, fine_quant[i]);
223       offset = EXTRACT16(celt_div(SHL16(q2,8)+QCONST16(.5,8),frac)-QCONST16(.5f,8));
224       oldEBands[i] += PSHR32(MULT16_16(DB_SCALING*6,offset),8);
225    }
226    for (i=0;i<m->nbEBands;i++)
227    {
228       eBands[i] = dB2Amp(oldEBands[i]);
229    }
230    /*printf ("\n");*/
231 }
232
233
234
235 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)
236 {
237    int C;
238    C = m->nbChannels;
239
240    if (C==1)
241    {
242       quant_coarse_energy_mono(m, eBands, oldEBands, budget, prob, error, enc);
243
244    } else {
245       int c;
246       for (c=0;c<C;c++)
247       {
248          int i;
249          VARDECL(celt_ener_t, E);
250          SAVE_STACK;
251          ALLOC(E, m->nbEBands, celt_ener_t);
252          for (i=0;i<m->nbEBands;i++)
253             E[i] = eBands[C*i+c];
254          quant_coarse_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, prob, error+c*m->nbEBands, enc);
255       }
256       RESTORE_STACK;
257    }
258 }
259
260 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)
261 {
262    int C;
263    C = m->nbChannels;
264
265    if (C==1)
266    {
267       quant_fine_energy_mono(m, eBands, oldEBands, error, fine_quant, enc);
268
269    } else {
270       int c;
271       VARDECL(celt_ener_t, E);
272       ALLOC(E, m->nbEBands, celt_ener_t);
273       for (c=0;c<C;c++)
274       {
275          int i;
276          SAVE_STACK;
277          quant_fine_energy_mono(m, E, oldEBands+c*m->nbEBands, error+c*m->nbEBands, fine_quant, enc);
278          for (i=0;i<m->nbEBands;i++)
279             eBands[C*i+c] = E[i];
280       }
281       RESTORE_STACK;
282    }
283 }
284
285
286 void unquant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, ec_dec *dec)
287 {
288    int C;   
289
290    C = m->nbChannels;
291    if (C==1)
292    {
293       unquant_coarse_energy_mono(m, eBands, oldEBands, budget, prob, dec);
294    }
295    else {
296       int c;
297       VARDECL(celt_ener_t, E);
298       SAVE_STACK;
299       ALLOC(E, m->nbEBands, celt_ener_t);
300       for (c=0;c<C;c++)
301       {
302          unquant_coarse_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, prob, dec);
303       }
304       RESTORE_STACK;
305    }
306 }
307
308 void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec)
309 {
310    int C;   
311
312    C = m->nbChannels;
313
314    if (C==1)
315    {
316       unquant_fine_energy_mono(m, eBands, oldEBands, fine_quant, dec);
317    }
318    else {
319       int c;
320       VARDECL(celt_ener_t, E);
321       SAVE_STACK;
322       ALLOC(E, m->nbEBands, celt_ener_t);
323       for (c=0;c<C;c++)
324       {
325          int i;
326          unquant_fine_energy_mono(m, E, oldEBands+c*m->nbEBands, fine_quant, dec);
327          for (i=0;i<m->nbEBands;i++)
328             eBands[C*i+c] = E[i];
329       }
330       RESTORE_STACK;
331    }
332 }