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