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