Re-ordered the parameters in the stream: [energy, pitch index, pitch gains]
[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] = {8, 6, 5, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
41
42 static void quant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *enc)
43 {
44    int i;
45    float prev = 0;
46    float coef = m->ePredCoef;
47    float error[m->nbEBands];
48    /* The .7 is a heuristic */
49    float beta = .7*coef;
50    for (i=0;i<m->nbEBands;i++)
51    {
52       int qi;
53       float q;
54       float res;
55       float x;
56       float f;
57       float mean = (1-coef)*eMeans[i];
58       x = 20*log10(.3+eBands[i]);
59       res = 6.;
60       //res = 1;
61       f = (x-mean-coef*oldEBands[i]-prev)/res;
62       qi = (int)floor(.5+f);
63       //if (i> 4 && qi<-2)
64       //   qi = -2;
65       //ec_laplace_encode(enc, qi, i==0?11192:6192);
66       //ec_laplace_encode(enc, qi, 8500-i*200);
67       ec_laplace_encode(enc, qi, 6000-i*200);
68       q = qi*res;
69       error[i] = f - qi;
70       
71       //printf("%d ", qi);
72       //printf("%f %f ", pred+prev+q, x);
73       //printf("%f ", x-pred);
74       
75       oldEBands[i] = mean+coef*oldEBands[i]+prev+q;
76       
77       prev = mean+prev+(1-beta)*q;
78    }
79    for (i=0;i<m->nbEBands;i++)
80    {
81       int q2;
82       float offset = (error[i]+.5)*frac[i];
83       q2 = (int)floor(offset);
84       if (q2 > frac[i]-1)
85          q2 = frac[i]-1;
86       ec_enc_uint(enc, q2, frac[i]);
87       offset = ((q2+.5)/frac[i])-.5;
88       oldEBands[i] += 6.*offset;
89       //printf ("%f ", error[i] - offset);
90       eBands[i] = pow(10, .05*oldEBands[i])-.3;
91       if (eBands[i] < 0)
92          eBands[i] = 0;
93    }
94    //printf ("%d\n", ec_enc_tell(enc, 0)-9);
95
96    //printf ("\n");
97 }
98
99 static void unquant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, ec_dec *dec)
100 {
101    int i;
102    float prev = 0;
103    float coef = m->ePredCoef;
104    /* The .7 is a heuristic */
105    float beta = .7*coef;
106    for (i=0;i<m->nbEBands;i++)
107    {
108       int qi;
109       float q;
110       float res;
111       float mean = (1-coef)*eMeans[i];
112       res = 6.;
113       qi = ec_laplace_decode(dec, 6000-i*200);
114       q = qi*res;
115       
116       oldEBands[i] = mean+coef*oldEBands[i]+prev+q;
117       
118       prev = mean+prev+(1-beta)*q;
119    }
120    for (i=0;i<m->nbEBands;i++)
121    {
122       int q2;
123       float offset;
124       q2 = ec_dec_uint(dec, frac[i]);
125       offset = ((q2+.5)/frac[i])-.5;
126       oldEBands[i] += 6.*offset;
127       //printf ("%f ", error[i] - offset);
128       eBands[i] = pow(10, .05*oldEBands[i])-.3;
129       if (eBands[i] < 0)
130          eBands[i] = 0;
131    }
132    //printf ("\n");
133 }
134
135
136
137 void quant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *enc)
138 {
139    int C;
140    
141    C = m->nbChannels;
142
143    if (C==1)
144       quant_energy_mono(m, eBands, oldEBands, enc);
145    else 
146 #if 1
147    {
148       int c;
149       for (c=0;c<C;c++)
150       {
151          int i;
152          float E[m->nbEBands];
153          for (i=0;i<m->nbEBands;i++)
154             E[i] = eBands[C*i+c];
155          quant_energy_mono(m, E, oldEBands+c*m->nbEBands, enc);
156          for (i=0;i<m->nbEBands;i++)
157             eBands[C*i+c] = E[i];
158       }
159    }
160 #else
161       if (C==2)
162    {
163       int i;
164       int NB = m->nbEBands;
165       float mid[NB];
166       float side[NB];
167       float left;
168       float right;
169       for (i=0;i<NB;i++)
170       {
171          //left = eBands[C*i];
172          //right = eBands[C*i+1];
173          mid[i] = sqrt(eBands[C*i]*eBands[C*i] + eBands[C*i+1]*eBands[C*i+1]);
174          side[i] = 20*log10((eBands[2*i]+.3)/(eBands[2*i+1]+.3));
175          //printf ("%f %f ", mid[i], side[i]);
176       }
177       //printf ("\n");
178       quant_energy_mono(m, mid, oldEBands, enc);
179       for (i=0;i<NB;i++)
180          side[i] = pow(10.f,floor(.5f+side[i])/10.f);
181          
182       //quant_energy_side(m, side, oldEBands+NB, enc);
183       for (i=0;i<NB;i++)
184       {
185          eBands[C*i] = mid[i]*sqrt(side[i]/(1.f+side[i]));
186          eBands[C*i+1] = mid[i]*sqrt(1.f/(1.f+side[i]));
187          //printf ("%f %f ", mid[i], side[i]);
188       }
189
190    } else {
191       celt_fatal("more than 2 channels not supported");
192    }
193 #endif
194 }
195
196
197
198 void unquant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_dec *dec)
199 {
200    int C;   
201    C = m->nbChannels;
202
203    if (C==1)
204       unquant_energy_mono(m, eBands, oldEBands, dec);
205    else {
206       int c;
207       for (c=0;c<C;c++)
208       {
209          int i;
210          float E[m->nbEBands];
211          unquant_energy_mono(m, E, oldEBands+c*m->nbEBands, dec);
212          for (i=0;i<m->nbEBands;i++)
213             eBands[C*i+c] = E[i];
214       }
215    }
216 }