6d3a802b440cb7ce741007d56b9cf635c3f370fa
[opus.git] / libcelt / quant_bands.c
1 /* (C) 2007 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
42 #ifdef FIXED_POINT
43 const float 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};
44 #else
45 const float 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};
46 #endif
47
48 /*const int frac[24] = {4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};*/
49 const int frac[24] = {8, 6, 5, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
50
51 #ifdef FIXED_POINT
52 #define Q8 256.f
53 #define Q8_1 (1.f/256.f)
54 #else
55 #define Q8 1.f
56 #define Q8_1 1.f
57 #endif
58 static void quant_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, ec_enc *enc)
59 {
60    int i;
61    int bits;
62    celt_word16_t prev = 0;
63    float coef = m->ePredCoef;
64    VARDECL(celt_word16_t *error);
65    /* The .7 is a heuristic */
66    float beta = .7*coef;
67    
68    ALLOC(error, m->nbEBands, celt_word16_t);
69    bits = ec_enc_tell(enc, 0);
70    for (i=0;i<m->nbEBands;i++)
71    {
72       int qi;
73       celt_word16_t q;   /* dB */
74       celt_word16_t res; /* dB */
75       celt_word16_t x;   /* dB */
76       celt_word16_t f;   /* Q8 */
77       celt_word16_t mean = (1-coef)*eMeans[i];
78       x = DB_SCALING*20*log10(.3+ENER_SCALING_1*eBands[i]);
79       res = DB_SCALING*6;
80       f = QCONST16(1.f,8)*(x-mean-coef*oldEBands[i]-prev*1.f)/res;
81 #ifdef FIXED_POINT
82       /* Rounding to nearest integer here is really important! */
83       qi = (f+128)>>8;
84 #else
85       qi = (int)floor(.5+f);
86 #endif
87       /*ec_laplace_encode(enc, qi, i==0?11192:6192);*/
88       /*ec_laplace_encode(enc, qi, 8500-i*200);*/
89       /* If we don't have enough bits to encode all the energy, just assume something safe. */
90       if (ec_enc_tell(enc, 0) - bits > budget)
91          qi = -1;
92       else
93          ec_laplace_encode(enc, qi, 6000-i*200);
94       q = qi*res;
95       error[i] = f - SHL16(qi,8);
96       
97       /*printf("%d ", qi);*/
98       /*printf("%f %f ", pred+prev+q, x);*/
99       /*printf("%f ", x-pred);*/
100       
101       oldEBands[i] = mean+coef*oldEBands[i]+prev+q;
102       
103       prev = mean+prev+(1-beta)*q;
104    }
105    /*bits = ec_enc_tell(enc, 0) - bits;*/
106    /*printf ("%d\n", bits);*/
107    for (i=0;i<m->nbEBands;i++)
108    {
109       int q2;
110       float offset = Q8_1*(error[i]+QCONST16(.5f,8))*frac[i];
111       /* FIXME: Instead of giving up without warning, we should degrade everything gracefully */
112       if (ec_enc_tell(enc, 0) - bits +EC_ILOG(frac[i])> budget)
113          break;
114       q2 = (int)floor(offset);
115       if (q2 > frac[i]-1)
116          q2 = frac[i]-1;
117       ec_enc_uint(enc, q2, frac[i]);
118       offset = ((q2+.5)/frac[i])-.5;
119       oldEBands[i] += DB_SCALING*6.*offset;
120       /*printf ("%f ", error[i] - offset);*/
121    }
122    for (i=0;i<m->nbEBands;i++)
123    {
124       eBands[i] = ENER_SCALING*(pow(10, .05*DB_SCALING_1*oldEBands[i])-.3);
125       if (eBands[i] < 0)
126          eBands[i] = 0;
127    }
128    /*printf ("%d\n", ec_enc_tell(enc, 0)-9);*/
129
130    /*printf ("\n");*/
131 }
132
133 static void unquant_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, ec_dec *dec)
134 {
135    int i;
136    int bits;
137    float prev = 0;
138    float coef = m->ePredCoef;
139    /* The .7 is a heuristic */
140    float beta = .7*coef;
141    bits = ec_dec_tell(dec, 0);
142    for (i=0;i<m->nbEBands;i++)
143    {
144       int qi;
145       float q;
146       float res;
147       float mean = (1-coef)*eMeans[i];
148       res = 6.;
149       /* If we didn't have enough bits to encode all the energy, just assume something safe. */
150       if (ec_dec_tell(dec, 0) - bits > budget)
151          qi = -1;
152       else
153          qi = ec_laplace_decode(dec, 6000-i*200);
154       q = qi*res;
155       
156       oldEBands[i] = DB_SCALING*(DB_SCALING_1*mean+coef*DB_SCALING_1*oldEBands[i]+prev+q);
157       
158       prev = DB_SCALING_1*mean+prev+(1-beta)*q;
159    }
160    for (i=0;i<m->nbEBands;i++)
161    {
162       int q2;
163       float offset;
164       if (ec_dec_tell(dec, 0) - bits +EC_ILOG(frac[i])> budget)
165          break;
166       q2 = ec_dec_uint(dec, frac[i]);
167       offset = ((q2+.5)/frac[i])-.5;
168       oldEBands[i] += DB_SCALING*6.*offset;
169    }
170    for (i=0;i<m->nbEBands;i++)
171    {
172       /*printf ("%f ", error[i] - offset);*/
173       eBands[i] = ENER_SCALING*(pow(10, .05*DB_SCALING_1*oldEBands[i])-.3);
174       if (eBands[i] < 0)
175          eBands[i] = 0;
176    }
177    /*printf ("\n");*/
178 }
179
180
181
182 void quant_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, ec_enc *enc)
183 {
184    int C;
185    
186    C = m->nbChannels;
187
188    if (C==1)
189       quant_energy_mono(m, eBands, oldEBands, budget, enc);
190    else 
191 #if 1
192    {
193       int c;
194       VARDECL(celt_ener_t *E);
195       ALLOC(E, m->nbEBands, celt_ener_t);
196       for (c=0;c<C;c++)
197       {
198          int i;
199          for (i=0;i<m->nbEBands;i++)
200             E[i] = eBands[C*i+c];
201          quant_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, enc);
202          for (i=0;i<m->nbEBands;i++)
203             eBands[C*i+c] = E[i];
204       }
205    }
206 #else
207       if (C==2)
208    {
209       int i;
210       int NB = m->nbEBands;
211       float mid[NB];
212       float side[NB];
213       float left;
214       float right;
215       for (i=0;i<NB;i++)
216       {
217          //left = eBands[C*i];
218          //right = eBands[C*i+1];
219          mid[i] = ENER_SCALING_1*sqrt(eBands[C*i]*eBands[C*i] + eBands[C*i+1]*eBands[C*i+1]);
220          side[i] = 20*log10((ENER_SCALING_1*eBands[2*i]+.3)/(ENER_SCALING_1*eBands[2*i+1]+.3));
221          //printf ("%f %f ", mid[i], side[i]);
222       }
223       //printf ("\n");
224       quant_energy_mono(m, mid, oldEBands, enc);
225       for (i=0;i<NB;i++)
226          side[i] = pow(10.f,floor(.5f+side[i])/10.f);
227          
228       //quant_energy_side(m, side, oldEBands+NB, enc);
229       for (i=0;i<NB;i++)
230       {
231          eBands[C*i] = ENER_SCALING*mid[i]*sqrt(side[i]/(1.f+side[i]));
232          eBands[C*i+1] = ENER_SCALING*mid[i]*sqrt(1.f/(1.f+side[i]));
233          //printf ("%f %f ", mid[i], side[i]);
234       }
235
236    } else {
237       celt_fatal("more than 2 channels not supported");
238    }
239 #endif
240 }
241
242
243
244 void unquant_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, ec_dec *dec)
245 {
246    int C;   
247    C = m->nbChannels;
248
249    if (C==1)
250       unquant_energy_mono(m, eBands, oldEBands, budget, dec);
251    else {
252       int c;
253       VARDECL(celt_ener_t *E);
254       ALLOC(E, m->nbEBands, celt_ener_t);
255       for (c=0;c<C;c++)
256       {
257          int i;
258          unquant_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, dec);
259          for (i=0;i<m->nbEBands;i++)
260             eBands[C*i+c] = E[i];
261       }
262    }
263 }