comparison libtwamr/q_plsf_3.c @ 372:9cca139a20a8

libtwamr: integrate q_plsf_3.c
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 06 May 2024 04:00:14 +0000
parents
children
comparison
equal deleted inserted replaced
371:4a8cabac281e 372:9cca139a20a8
1 /*
2 *****************************************************************************
3 *
4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
5 * R99 Version 3.3.0
6 * REL-4 Version 4.1.0
7 *
8 ****************************************************************************
9 *
10 * File : q_plsf_3.c
11 * Purpose : Quantization of LSF parameters with 1st order MA
12 * prediction and split by 3 vector quantization
13 * (split-VQ)
14 *
15 *****************************************************************************
16 */
17
18 /*
19 *****************************************************************************
20 * MODULE INCLUDE FILE AND VERSION ID
21 *****************************************************************************
22 */
23 #include "namespace.h"
24 #include "q_plsf.h"
25
26 /*
27 *****************************************************************************
28 * INCLUDE FILES
29 *****************************************************************************
30 */
31 #include "typedef.h"
32 #include "basic_op.h"
33 #include "no_count.h"
34 #include "lsp_lsf.h"
35 #include "reorder.h"
36 #include "lsfwt.h"
37 #include "memops.h"
38 #include "q_plsf3_tab.h"
39
40 /*
41 *****************************************************************************
42 * LOCAL VARIABLES AND TABLES
43 *****************************************************************************
44 */
45 #define PAST_RQ_INIT_SIZE 8
46 /*
47 *****************************************************************************
48 * LOCAL PROGRAM CODE
49 *****************************************************************************
50 */
51 /* Quantization of a 4 dimensional subvector */
52
53 static Word16
54 Vq_subvec4( /* o: quantization index, Q0 */
55 Word16 * lsf_r1, /* i/o: 1st LSF residual vector, Q15 */
56 const Word16 * dico, /* i: quantization codebook, Q15 */
57 const Word16 * wf1, /* i: 1st LSF weighting factors, Q13 */
58 Word16 dico_size) /* i: size of quantization codebook, Q0 */
59 {
60 Word16 i, index = 0, temp;
61 const Word16 *p_dico;
62 Word32 dist_min, dist;
63
64 dist_min = MAX_32; move32 ();
65 p_dico = dico; move16 ();
66
67 for (i = 0; i < dico_size; i++)
68 {
69 temp = sub (lsf_r1[0], *p_dico++);
70 temp = mult (wf1[0], temp);
71 dist = L_mult (temp, temp);
72
73 temp = sub (lsf_r1[1], *p_dico++);
74 temp = mult (wf1[1], temp);
75 dist = L_mac (dist, temp, temp);
76
77 temp = sub (lsf_r1[2], *p_dico++);
78 temp = mult (wf1[2], temp);
79 dist = L_mac (dist, temp, temp);
80
81 temp = sub (lsf_r1[3], *p_dico++);
82 temp = mult (wf1[3], temp);
83 dist = L_mac (dist, temp, temp);
84
85 test ();
86 if (L_sub (dist, dist_min) < (Word32) 0)
87 {
88 dist_min = dist; move32 ();
89 index = i; move16 ();
90 }
91 }
92
93 /* Reading the selected vector */
94
95 p_dico = &dico[shl (index, 2)]; move16 ();
96 lsf_r1[0] = *p_dico++; move16 ();
97 lsf_r1[1] = *p_dico++; move16 ();
98 lsf_r1[2] = *p_dico++; move16 ();
99 lsf_r1[3] = *p_dico++; move16 ();
100
101 return index;
102 }
103
104 /* Quantization of a 3 dimensional subvector */
105
106 static Word16
107 Vq_subvec3( /* o: quantization index, Q0 */
108 Word16 * lsf_r1, /* i/o: 1st LSF residual vector, Q15 */
109 const Word16 * dico, /* i: quantization codebook, Q15 */
110 const Word16 * wf1, /* i: 1st LSF weighting factors, Q13 */
111 Word16 dico_size, /* i: size of quantization codebook, Q0 */
112 Flag use_half) /* i: use every second entry in codebook */
113 {
114 Word16 i, index = 0, temp;
115 const Word16 *p_dico;
116 Word32 dist_min, dist;
117
118 dist_min = MAX_32; move32 ();
119 p_dico = dico; move16 ();
120
121 test ();
122 if (use_half == 0) {
123 for (i = 0; i < dico_size; i++)
124 {
125 temp = sub(lsf_r1[0], *p_dico++);
126 temp = mult(wf1[0], temp);
127 dist = L_mult(temp, temp);
128
129 temp = sub(lsf_r1[1], *p_dico++);
130 temp = mult(wf1[1], temp);
131 dist = L_mac(dist, temp, temp);
132
133 temp = sub(lsf_r1[2], *p_dico++);
134 temp = mult(wf1[2], temp);
135 dist = L_mac(dist, temp, temp);
136
137 test ();
138 if (L_sub(dist, dist_min) < (Word32) 0) {
139 dist_min = dist; move32 ();
140 index = i; move16 ();
141 }
142 }
143 p_dico = &dico[add(index, add(index, index))]; move16 ();
144 }
145 else
146 {
147 for (i = 0; i < dico_size; i++)
148 {
149 temp = sub(lsf_r1[0], *p_dico++);
150 temp = mult(wf1[0], temp);
151 dist = L_mult(temp, temp);
152
153 temp = sub(lsf_r1[1], *p_dico++);
154 temp = mult(wf1[1], temp);
155 dist = L_mac(dist, temp, temp);
156
157 temp = sub(lsf_r1[2], *p_dico++);
158 temp = mult(wf1[2], temp);
159 dist = L_mac(dist, temp, temp);
160
161 test ();
162 if (L_sub(dist, dist_min) < (Word32) 0)
163 {
164 dist_min = dist; move32 ();
165 index = i; move16 ();
166 }
167 p_dico = p_dico + 3; add(0,0);
168 }
169 p_dico = &dico[shl(add(index, add(index, index)),1)]; move16 ();
170 }
171
172 /* Reading the selected vector */
173 lsf_r1[0] = *p_dico++; move16 ();
174 lsf_r1[1] = *p_dico++; move16 ();
175 lsf_r1[2] = *p_dico++; move16 ();
176
177 return index;
178 }
179
180 /*
181 *****************************************************************************
182 * PUBLIC PROGRAM CODE
183 *****************************************************************************
184 */
185
186 /***********************************************************************
187 *
188 * routine: Q_plsf_3()
189 *
190 * Quantization of LSF parameters with 1st order MA prediction and
191 * split by 3 vector quantization (split-VQ)
192 *
193 ***********************************************************************/
194 void Q_plsf_3(
195 Q_plsfState *st, /* i/o: state struct */
196 enum Mode mode, /* i : coder mode */
197 Word16 *lsp1, /* i : 1st LSP vector Q15 */
198 Word16 *lsp1_q, /* o : quantized 1st LSP vector Q15 */
199 Word16 *indice, /* o : quantization indices of 3 vectors Q0 */
200 Word16 *pred_init_i /* o : init index for MA prediction in DTX mode */
201 )
202 {
203 Word16 i, j;
204 Word16 lsf1[M], wf1[M], lsf_p[M], lsf_r1[M];
205 Word16 lsf1_q[M];
206
207 Word32 L_pred_init_err;
208 Word32 L_min_pred_init_err;
209 Word16 temp_r1[M];
210 Word16 temp_p[M];
211
212 /* convert LSFs to normalize frequency domain 0..16384 */
213
214 Lsp_lsf(lsp1, lsf1, M);
215
216 /* compute LSF weighting factors (Q13) */
217
218 Lsf_wt(lsf1, wf1);
219
220 /* Compute predicted LSF and prediction error */
221 if (test(), sub(mode, MRDTX) != 0)
222 {
223 for (i = 0; i < M; i++)
224 {
225 lsf_p[i] = add(mean_lsf3[i],
226 mult(st->past_rq[i],
227 pred_fac[i])); move16 ();
228 lsf_r1[i] = sub(lsf1[i], lsf_p[i]); move16 ();
229 }
230 }
231 else
232 {
233 /* DTX mode, search the init vector that yields */
234 /* lowest prediction resuidual energy */
235 *pred_init_i = 0; move16 ();
236 L_min_pred_init_err = 0x7fffffff; /* 2^31 - 1 */ move32 ();
237 for (j = 0; j < PAST_RQ_INIT_SIZE; j++)
238 {
239 L_pred_init_err = 0; move32 ();
240 for (i = 0; i < M; i++)
241 {
242 temp_p[i] = add(mean_lsf3[i], past_rq_init[j*M+i]);
243 temp_r1[i] = sub(lsf1[i],temp_p[i]);
244 L_pred_init_err = L_mac(L_pred_init_err, temp_r1[i], temp_r1[i]);
245 } /* next i */
246
247 test ();
248 if (L_sub(L_pred_init_err, L_min_pred_init_err) < (Word32) 0)
249 {
250 L_min_pred_init_err = L_pred_init_err; move32 ();
251 Copy(temp_r1, lsf_r1, M);
252 Copy(temp_p, lsf_p, M);
253
254 /* Set zerom */
255 Copy(&past_rq_init[j*M], st->past_rq, M);
256 *pred_init_i = j; move16 ();
257 } /* endif */
258 } /* next j */
259 } /* endif MRDTX */
260
261 /*---- Split-VQ of prediction error ----*/
262 if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0)
263 { /* MR475, MR515 */
264 test (); test ();
265
266 indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf3, &wf1[0], DICO31_SIZE, 0);
267 move16 ();
268 indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf3, &wf1[3], DICO32_SIZE/2, 1);
269 move16 ();
270 indice[2] = Vq_subvec4(&lsf_r1[6], mr515_3_lsf, &wf1[6], MR515_3_SIZE);
271 move16 ();
272 }
273 else if (sub (mode, MR795) == 0)
274 { /* MR795 */
275 test (); test (); test ();
276
277 indice[0] = Vq_subvec3(&lsf_r1[0], mr795_1_lsf, &wf1[0], MR795_1_SIZE, 0);
278 move16 ();
279 indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf3, &wf1[3], DICO32_SIZE, 0);
280 move16 ();
281 indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf3, &wf1[6], DICO33_SIZE);
282 move16 ();
283 }
284 else
285 { /* MR59, MR67, MR74, MR102 , MRDTX */
286 test (); test (); test ();
287
288 indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf3, &wf1[0], DICO31_SIZE, 0);
289 move16 ();
290 indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf3, &wf1[3], DICO32_SIZE, 0);
291 move16 ();
292 indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf3, &wf1[6], DICO33_SIZE);
293 move16 ();
294 }
295
296
297 /* Compute quantized LSFs and update the past quantized residual */
298
299 for (i = 0; i < M; i++)
300 {
301 lsf1_q[i] = add(lsf_r1[i], lsf_p[i]); move16 ();
302 st->past_rq[i] = lsf_r1[i]; move16 ();
303 }
304
305 /* verification that LSFs has mimimum distance of LSF_GAP Hz */
306
307 Reorder_lsf(lsf1_q, LSF_GAP, M);
308
309 /* convert LSFs to the cosine domain */
310
311 Lsf_lsp(lsf1_q, lsp1_q, M);
312 }