Enabling "plain folding" in case we don't even have enough bits for intra-frame
[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    float error[m->nbEBands];
105    /* The .7 is a heuristic */
106    float beta = .7*coef;
107    for (i=0;i<m->nbEBands;i++)
108    {
109       int qi;
110       float q;
111       float res;
112       float mean = (1-coef)*eMeans[i];
113       res = 6.;
114       qi = ec_laplace_decode(dec, 6000-i*200);
115       q = qi*res;
116       
117       oldEBands[i] = mean+coef*oldEBands[i]+prev+q;
118       
119       prev = mean+prev+(1-beta)*q;
120    }
121    for (i=0;i<m->nbEBands;i++)
122    {
123       int q2;
124       float offset;
125       q2 = ec_dec_uint(dec, frac[i]);
126       offset = ((q2+.5)/frac[i])-.5;
127       oldEBands[i] += 6.*offset;
128       //printf ("%f ", error[i] - offset);
129       eBands[i] = pow(10, .05*oldEBands[i])-.3;
130       if (eBands[i] < 0)
131          eBands[i] = 0;
132    }
133    //printf ("\n");
134 }
135
136
137
138 void quant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *enc)
139 {
140    int C;
141    
142    C = m->nbChannels;
143
144    if (C==1)
145       quant_energy_mono(m, eBands, oldEBands, enc);
146    else 
147 #if 1
148    {
149       int c;
150       for (c=0;c<C;c++)
151       {
152          int i;
153          float E[m->nbEBands];
154          for (i=0;i<m->nbEBands;i++)
155             E[i] = eBands[C*i+c];
156          quant_energy_mono(m, E, oldEBands+c*m->nbEBands, enc);
157          for (i=0;i<m->nbEBands;i++)
158             eBands[C*i+c] = E[i];
159       }
160    }
161 #else
162       if (C==2)
163    {
164       int i;
165       int NB = m->nbEBands;
166       float mid[NB];
167       float side[NB];
168       float left;
169       float right;
170       for (i=0;i<NB;i++)
171       {
172          //left = eBands[C*i];
173          //right = eBands[C*i+1];
174          mid[i] = sqrt(eBands[C*i]*eBands[C*i] + eBands[C*i+1]*eBands[C*i+1]);
175          side[i] = 20*log10((eBands[2*i]+.3)/(eBands[2*i+1]+.3));
176          //printf ("%f %f ", mid[i], side[i]);
177       }
178       //printf ("\n");
179       quant_energy_mono(m, mid, oldEBands, enc);
180       for (i=0;i<NB;i++)
181          side[i] = pow(10.f,floor(.5f+side[i])/10.f);
182          
183       //quant_energy_side(m, side, oldEBands+NB, enc);
184       for (i=0;i<NB;i++)
185       {
186          eBands[C*i] = mid[i]*sqrt(side[i]/(1.f+side[i]));
187          eBands[C*i+1] = mid[i]*sqrt(1.f/(1.f+side[i]));
188          //printf ("%f %f ", mid[i], side[i]);
189       }
190
191    } else {
192       celt_fatal("more than 2 channels not supported");
193    }
194 #endif
195 }
196
197
198
199 void unquant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_dec *dec)
200 {
201    int C;   
202    C = m->nbChannels;
203
204    if (C==1)
205       unquant_energy_mono(m, eBands, oldEBands, dec);
206    else {
207       int c;
208       for (c=0;c<C;c++)
209       {
210          int i;
211          float E[m->nbEBands];
212          unquant_energy_mono(m, E, oldEBands+c*m->nbEBands, dec);
213          for (i=0;i<m->nbEBands;i++)
214             eBands[C*i+c] = E[i];
215       }
216    }
217 }