Preparing for beta 3, cleaned up the mode/bit-rate code in speexdec,
[speexdsp.git] / libspeex / quant_lsp.c
1 /* Copyright (C) 2002 Jean-Marc Valin 
2    File: quant_lsp.c
3    LSP vector quantization
4
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions
7    are met:
8    
9    - Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11    
12    - Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15    
16    - Neither the name of the Xiph.org Foundation nor the names of its
17    contributors may be used to endorse or promote products derived from
18    this software without specific prior written permission.
19    
20    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include "quant_lsp.h"
34 #include <math.h>
35 #include <stdio.h>
36
37 extern int lsp_nb_vqid[64];
38 static float quant_weight[MAX_LSP_SIZE];
39
40 /* Note: x is modified*/
41 static int lsp_quant(float *x, float *cdbk, int nbVec, int nbDim)
42 {
43    int i,j;
44    float dist, tmp;
45    float best_dist=0;
46    int best_id=0;
47    float *ptr=cdbk;
48    for (i=0;i<nbVec;i++)
49    {
50       dist=0;
51       for (j=0;j<nbDim;j++)
52       {
53          tmp=(x[j]-*ptr++);
54          dist+=tmp*tmp;
55       }
56       if (dist<best_dist || i==0)
57       {
58          best_dist=dist;
59          best_id=i;
60       }
61    }
62
63    for (j=0;j<nbDim;j++)
64       x[j] -= cdbk[best_id*nbDim+j];
65     
66    return best_id;
67 }
68
69 /* Note: x is modified*/
70 static int lsp_weight_quant(float *x, float *weight, float *cdbk, int nbVec, int nbDim)
71 {
72    int i,j;
73    float dist, tmp;
74    float best_dist=0;
75    int best_id=0;
76    float *ptr=cdbk;
77    for (i=0;i<nbVec;i++)
78    {
79       dist=0;
80       for (j=0;j<nbDim;j++)
81       {
82          tmp=(x[j]-*ptr++);
83          dist+=weight[j]*tmp*tmp;
84       }
85       if (dist<best_dist || i==0)
86       {
87          best_dist=dist;
88          best_id=i;
89       }
90    }
91    
92    for (j=0;j<nbDim;j++)
93       x[j] -= cdbk[best_id*nbDim+j];
94    return best_id;
95 }
96
97
98 void lsp_quant_nb(float *lsp, float *qlsp, int order, SpeexBits *bits)
99 {
100    int i;
101    float tmp1, tmp2;
102    int id;
103
104    for (i=0;i<order;i++)
105       qlsp[i]=lsp[i];
106
107    quant_weight[0] = 1/(qlsp[1]-qlsp[0]);
108    quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]);
109    for (i=1;i<order-1;i++)
110    {
111 #if 1
112       tmp1 = 1/((.15+qlsp[i]-qlsp[i-1])*(.15+qlsp[i]-qlsp[i-1]));
113       tmp2 = 1/((.15+qlsp[i+1]-qlsp[i])*(.15+qlsp[i+1]-qlsp[i]));
114 #else
115       tmp1 = 1/(qlsp[i]-qlsp[i-1]);
116       tmp2 = 1/(qlsp[i+1]-qlsp[i]);
117 #endif
118       quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
119    }
120    id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
121    speex_bits_pack(bits, id, 6);
122
123    id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
124    speex_bits_pack(bits, id, 6);
125
126    id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5);
127    speex_bits_pack(bits, id, 6);
128
129    id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
130    speex_bits_pack(bits, id, 6);
131
132    id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5);
133    speex_bits_pack(bits, id, 6);
134
135    for (i=0;i<order;i++)
136       qlsp[i]=lsp[i]-qlsp[i];
137 }
138
139 void lsp_unquant_nb(float *lsp, int order, SpeexBits *bits)
140 {
141    int i, id;
142    for (i=0;i<order;i++)
143       lsp[i]=0;
144
145
146    id=speex_bits_unpack_unsigned(bits, 6);
147    for (i=0;i<10;i++)
148       lsp[i] += cdbk_nb[id*10+i];
149
150    id=speex_bits_unpack_unsigned(bits, 6);
151    for (i=0;i<5;i++)
152       lsp[i] += cdbk_nb_low1[id*5+i];
153
154    id=speex_bits_unpack_unsigned(bits, 6);
155    for (i=0;i<5;i++)
156       lsp[i] += cdbk_nb_low2[id*5+i];
157
158    id=speex_bits_unpack_unsigned(bits, 6);
159    for (i=0;i<5;i++)
160       lsp[i+5] += cdbk_nb_high1[id*5+i];
161    
162    id=speex_bits_unpack_unsigned(bits, 6);
163    for (i=0;i<5;i++)
164       lsp[i+5] += cdbk_nb_high2[id*5+i];
165 }
166
167
168 void lsp_quant_lbr(float *lsp, float *qlsp, int order, SpeexBits *bits)
169 {
170    int i;
171    float tmp1, tmp2;
172    int id;
173
174    for (i=0;i<order;i++)
175       qlsp[i]=lsp[i];
176
177    quant_weight[0] = 1/(qlsp[1]-qlsp[0]);
178    quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]);
179    for (i=1;i<order-1;i++)
180    {
181 #if 1
182       tmp1 = 1/((.15+qlsp[i]-qlsp[i-1])*(.15+qlsp[i]-qlsp[i-1]));
183       tmp2 = 1/((.15+qlsp[i+1]-qlsp[i])*(.15+qlsp[i+1]-qlsp[i]));
184 #else
185       tmp1 = 1/(qlsp[i]-qlsp[i-1]);
186       tmp2 = 1/(qlsp[i+1]-qlsp[i]);
187 #endif
188       quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
189    }
190    id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
191    speex_bits_pack(bits, id, 6);
192
193    id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
194    speex_bits_pack(bits, id, 6);
195
196    id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
197    speex_bits_pack(bits, id, 6);
198
199    for (i=0;i<order;i++)
200       qlsp[i]=lsp[i]-qlsp[i];
201 }
202
203 void lsp_unquant_lbr(float *lsp, int order, SpeexBits *bits)
204 {
205    int i, id;
206    for (i=0;i<order;i++)
207       lsp[i]=0;
208
209
210    id=speex_bits_unpack_unsigned(bits, 6);
211    for (i=0;i<10;i++)
212       lsp[i] += cdbk_nb[id*10+i];
213
214    id=speex_bits_unpack_unsigned(bits, 6);
215    for (i=0;i<5;i++)
216       lsp[i] += cdbk_nb_low1[id*5+i];
217
218    id=speex_bits_unpack_unsigned(bits, 6);
219    for (i=0;i<5;i++)
220       lsp[i+5] += cdbk_nb_high1[id*5+i];
221    
222 }
223
224
225 extern float high_lsp_cdbk[];
226 extern float high_lsp_cdbk2[];
227
228
229 void lsp_quant_high(float *lsp, float *qlsp, int order, SpeexBits *bits)
230 {
231    int i;
232    float tmp1, tmp2;
233    int id;
234    for (i=0;i<order;i++)
235       qlsp[i]=lsp[i];
236
237    quant_weight[0] = 1/(qlsp[1]-qlsp[0]);
238    quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]);
239    for (i=1;i<order-1;i++)
240    {
241       tmp1 = 1/(qlsp[i]-qlsp[i-1]);
242       tmp2 = 1/(qlsp[i+1]-qlsp[i]);
243       quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
244    }
245    id = lsp_quant(qlsp, high_lsp_cdbk, 64, order);
246    speex_bits_pack(bits, id, 6);
247
248    id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order);
249    speex_bits_pack(bits, id, 6);
250
251    for (i=0;i<order;i++)
252       qlsp[i]=lsp[i]-qlsp[i];
253 }
254
255 void lsp_unquant_high(float *lsp, int order, SpeexBits *bits)
256 {
257
258    int i, id;
259    for (i=0;i<order;i++)
260       lsp[i]=0;
261
262
263    id=speex_bits_unpack_unsigned(bits, 6);
264    for (i=0;i<order;i++)
265       lsp[i] += high_lsp_cdbk[id*order+i];
266
267
268    id=speex_bits_unpack_unsigned(bits, 6);
269    for (i=0;i<order;i++)
270       lsp[i] += high_lsp_cdbk2[id*order+i];
271 }