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