Checking in license stuff
[speexdsp.git] / libspeex / quant_lsp.c
1 /* Copyright (C) 2002 Jean-Marc Valin 
2    File: quant_lsp.c
3    LSP vector quantization
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9    
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14    
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20 #include "quant_lsp.h"
21 #include <math.h>
22 #include <stdio.h>
23
24 static float quant_weight[MAX_LSP_SIZE];
25
26 int lsp_quant(float *x, float *cdbk, int nbVec, int nbDim)
27 {
28    int i,j;
29    float dist, tmp;
30    float best_dist=0;
31    int best_id=0;
32    float *ptr=cdbk;
33    for (i=0;i<nbVec;i++)
34    {
35       dist=0;
36       for (j=0;j<nbDim;j++)
37       {
38          tmp=(x[j]-*ptr++);
39          dist+=tmp*tmp;
40       }
41       if (dist<best_dist || i==0)
42       {
43          best_dist=dist;
44          best_id=i;
45       }
46    }
47
48    for (j=0;j<nbDim;j++)
49       x[j] -= cdbk[best_id*nbDim+j];
50     
51    return best_id;
52 }
53
54 int lsp_weight_quant(float *x, float *weight, float *cdbk, int nbVec, int nbDim)
55 {
56    int i,j;
57    float dist, tmp;
58    float best_dist=0;
59    int best_id=0;
60    float *ptr=cdbk;
61    for (i=0;i<nbVec;i++)
62    {
63       dist=0;
64       for (j=0;j<nbDim;j++)
65       {
66          tmp=(x[j]-*ptr++);
67          dist+=weight[j]*tmp*tmp;
68       }
69       if (dist<best_dist || i==0)
70       {
71          best_dist=dist;
72          best_id=i;
73       }
74    }
75    
76    for (j=0;j<nbDim;j++)
77       x[j] -= cdbk[best_id*nbDim+j];
78    return best_id;
79 }
80
81
82 unsigned int lsp_quant_nb(float *lsp, int order)
83 {
84    int i;
85    float tmp1, tmp2;
86    unsigned int id;
87    quant_weight[0] = 1/(lsp[1]-lsp[0]);
88    quant_weight[order-1] = 1/(lsp[order-1]-lsp[order-2]);
89    for (i=1;i<order-1;i++)
90    {
91       tmp1 = 1/(lsp[i]-lsp[i-1]);
92       tmp2 = 1/(lsp[i+1]-lsp[i]);
93       quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
94    }
95    id = lsp_quant(lsp, cdbk_nb, NB_CDBK_SIZE, order);
96    
97    id *= NB_CDBK_SIZE_LOW1;
98    id += lsp_weight_quant(lsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
99    
100    id *= NB_CDBK_SIZE_LOW2;
101    id += lsp_weight_quant(lsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5);
102    
103    id *= NB_CDBK_SIZE_HIGH1;
104    id += lsp_weight_quant(lsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
105    
106    id *= NB_CDBK_SIZE_HIGH2;
107    id += lsp_weight_quant(lsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5);
108    
109    return id;
110 }
111
112 void lsp_unquant_nb(float *lsp, int order, unsigned int id)
113 {
114    int i, tmp;
115    for (i=0;i<order;i++)
116       lsp[i]=0;
117
118
119    tmp = id % NB_CDBK_SIZE_HIGH2;
120    for (i=0;i<5;i++)
121       lsp[i+5] += cdbk_nb_high2[tmp*5+i];
122    id /= NB_CDBK_SIZE_HIGH2;
123    
124    tmp = id % NB_CDBK_SIZE_HIGH1;
125    for (i=0;i<5;i++)
126       lsp[i+5] += cdbk_nb_high1[tmp*5+i];
127    id /= NB_CDBK_SIZE_HIGH1;
128    
129    tmp = id % NB_CDBK_SIZE_LOW2;
130    for (i=0;i<5;i++)
131       lsp[i] += cdbk_nb_low2[tmp*5+i];
132    id /= NB_CDBK_SIZE_LOW2;
133
134    tmp = id % NB_CDBK_SIZE_LOW1;
135    for (i=0;i<5;i++)
136       lsp[i] += cdbk_nb_low1[tmp*5+i];
137    id /= NB_CDBK_SIZE_LOW1;
138
139    tmp=id;
140    for (i=0;i<10;i++)
141       lsp[i] += cdbk_nb[tmp*10+i];
142    
143 }