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