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