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