comparison src/q_plsf_5.c @ 0:56410792419a

src: original EFR source from ETSI
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 03 Apr 2024 05:31:37 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:56410792419a
1 /*************************************************************************
2 * FUNCTION: Q_plsf_5()
3 *
4 * PURPOSE: Quantization of 2 sets of LSF parameters using 1st order MA
5 * prediction and split by 5 matrix quantization (split-MQ)
6 *
7 * DESCRIPTION:
8 *
9 * p[i] = pred_factor*past_r2q[i]; i=0,...,m-1
10 * r1[i]= lsf1[i] - p[i]; i=0,...,m-1
11 * r2[i]= lsf2[i] - p[i]; i=0,...,m-1
12 * where:
13 * lsf1[i] 1st mean-removed LSF vector.
14 * lsf2[i] 2nd mean-removed LSF vector.
15 * r1[i] 1st residual prediction vector.
16 * r2[i] 2nd residual prediction vector.
17 * past_r2q[i] Past quantized residual (2nd vector).
18 *
19 * The residual vectors r1[i] and r2[i] are jointly quantized using
20 * split-MQ with 5 codebooks. Each 4th dimension submatrix contains 2
21 * elements from each residual vector. The 5 submatrices are as follows:
22 * {r1[0], r1[1], r2[0], r2[1]}; {r1[2], r1[3], r2[2], r2[3]};
23 * {r1[4], r1[5], r2[4], r2[5]}; {r1[6], r1[7], r2[6], r2[7]};
24 * {r1[8], r1[9], r2[8], r2[9]};
25 *
26 *************************************************************************/
27
28 #include "typedef.h"
29 #include "basic_op.h"
30 #include "count.h"
31 #include "sig_proc.h"
32
33 #include "cnst.h"
34 #include "dtx.h"
35
36 /* Locals functions */
37
38 void Lsf_wt (
39 Word16 *lsf, /* input : LSF vector */
40 Word16 *wf2 /* output: square of weighting factors */
41 );
42
43 Word16 Vq_subvec ( /* output: return quantization index */
44 Word16 *lsf_r1, /* input : 1st LSF residual vector */
45 Word16 *lsf_r2, /* input : and LSF residual vector */
46 const Word16 *dico,/* input : quantization codebook */
47 Word16 *wf1, /* input : 1st LSF weighting factors */
48 Word16 *wf2, /* input : 2nd LSF weighting factors */
49 Word16 dico_size /* input : size of quantization codebook */
50 );
51 Word16 Vq_subvec_s ( /* output: return quantization index */
52 Word16 *lsf_r1, /* input : 1st LSF residual vector */
53 Word16 *lsf_r2, /* input : and LSF residual vector */
54 const Word16 *dico,/* input : quantization codebook */
55 Word16 *wf1, /* input : 1st LSF weighting factors */
56 Word16 *wf2, /* input : 2nd LSF weighting factors */
57 Word16 dico_size /* input : size of quantization codebook */
58 );
59 /* M ->order of linear prediction filter */
60 /* LSF_GAP -> Minimum distance between LSF after quantization */
61 /* 50 Hz = 205 */
62 /* PRED_FAC -> Predcition factor */
63
64 #define M 10
65 #define LSF_GAP 205
66 #define PRED_FAC 21299
67
68 #include "q_plsf_5.tab" /* Codebooks of LSF prediction residual */
69
70 /* Past quantized prediction error */
71
72 Word16 past_r2_q[M];
73
74 extern Word16 lsf_old_tx[DTX_HANGOVER][M];
75
76 void Q_plsf_5 (
77 Word16 *lsp1, /* input : 1st LSP vector */
78 Word16 *lsp2, /* input : 2nd LSP vector */
79 Word16 *lsp1_q, /* output: quantized 1st LSP vector */
80 Word16 *lsp2_q, /* output: quantized 2nd LSP vector */
81 Word16 *indice, /* output: quantization indices of 5 matrices */
82 Word16 txdtx_ctrl /* input : tx dtx control word */
83 )
84 {
85 Word16 i;
86 Word16 lsf1[M], lsf2[M], wf1[M], wf2[M], lsf_p[M], lsf_r1[M], lsf_r2[M];
87 Word16 lsf1_q[M], lsf2_q[M];
88 Word16 lsf_aver[M];
89 static Word16 lsf_p_CN[M];
90
91 /* convert LSFs to normalize frequency domain 0..16384 */
92
93 Lsp_lsf (lsp1, lsf1, M);
94 Lsp_lsf (lsp2, lsf2, M);
95
96 /* Update LSF CN quantizer "memory" */
97
98 logic16 (); logic16 (); test (); test ();
99 if ((txdtx_ctrl & TX_SP_FLAG) == 0
100 && (txdtx_ctrl & TX_PREV_HANGOVER_ACTIVE) != 0)
101 {
102 update_lsf_p_CN (lsf_old_tx, lsf_p_CN);
103 }
104 logic16 (); test ();
105 if ((txdtx_ctrl & TX_SID_UPDATE) != 0)
106 {
107 /* New SID frame is to be sent:
108 Compute average of the current LSFs and the LSFs in the history */
109
110 aver_lsf_history (lsf_old_tx, lsf1, lsf2, lsf_aver);
111 }
112 /* Update LSF history with unquantized LSFs when no speech activity
113 is present */
114
115 logic16 (); test ();
116 if ((txdtx_ctrl & TX_SP_FLAG) == 0)
117 {
118 update_lsf_history (lsf1, lsf2, lsf_old_tx);
119 }
120 logic16 (); test ();
121 if ((txdtx_ctrl & TX_SID_UPDATE) != 0)
122 {
123 /* Compute LSF weighting factors for lsf2, using averaged LSFs */
124 /* Set LSF weighting factors for lsf1 to zero */
125 /* Replace lsf1 and lsf2 by the averaged LSFs */
126
127 Lsf_wt (lsf_aver, wf2);
128 for (i = 0; i < M; i++)
129 {
130 wf1[i] = 0; move16 ();
131 lsf1[i] = lsf_aver[i]; move16 ();
132 lsf2[i] = lsf_aver[i]; move16 ();
133 }
134 }
135 else
136 {
137 /* Compute LSF weighting factors */
138
139 Lsf_wt (lsf1, wf1);
140 Lsf_wt (lsf2, wf2);
141 }
142
143 /* Compute predicted LSF and prediction error */
144
145 logic16 (); test ();
146 if ((txdtx_ctrl & TX_SP_FLAG) != 0)
147 {
148 for (i = 0; i < M; i++)
149 {
150 lsf_p[i] = add (mean_lsf[i], mult (past_r2_q[i], PRED_FAC));
151 move16 ();
152 lsf_r1[i] = sub (lsf1[i], lsf_p[i]); move16 ();
153 lsf_r2[i] = sub (lsf2[i], lsf_p[i]); move16 ();
154 }
155 }
156 else
157 {
158 for (i = 0; i < M; i++)
159 {
160 lsf_r1[i] = sub (lsf1[i], lsf_p_CN[i]); move16 ();
161 lsf_r2[i] = sub (lsf2[i], lsf_p_CN[i]); move16 ();
162 }
163 }
164
165 /*---- Split-VQ of prediction error ----*/
166
167 indice[0] = Vq_subvec (&lsf_r1[0], &lsf_r2[0], dico1_lsf,
168 &wf1[0], &wf2[0], DICO1_SIZE);
169 move16 ();
170
171 indice[1] = Vq_subvec (&lsf_r1[2], &lsf_r2[2], dico2_lsf,
172 &wf1[2], &wf2[2], DICO2_SIZE);
173 move16 ();
174
175 indice[2] = Vq_subvec_s (&lsf_r1[4], &lsf_r2[4], dico3_lsf,
176 &wf1[4], &wf2[4], DICO3_SIZE);
177 move16 ();
178
179 indice[3] = Vq_subvec (&lsf_r1[6], &lsf_r2[6], dico4_lsf,
180 &wf1[6], &wf2[6], DICO4_SIZE);
181 move16 ();
182
183 indice[4] = Vq_subvec (&lsf_r1[8], &lsf_r2[8], dico5_lsf,
184 &wf1[8], &wf2[8], DICO5_SIZE);
185 move16 ();
186
187 /* Compute quantized LSFs and update the past quantized residual */
188 /* In case of no speech activity, skip computing the quantized LSFs,
189 and set past_r2_q to zero (initial value) */
190
191 logic16 (); test ();
192 if ((txdtx_ctrl & TX_SP_FLAG) != 0)
193 {
194 for (i = 0; i < M; i++)
195 {
196 lsf1_q[i] = add (lsf_r1[i], lsf_p[i]); move16 ();
197 lsf2_q[i] = add (lsf_r2[i], lsf_p[i]); move16 ();
198 past_r2_q[i] = lsf_r2[i]; move16 ();
199 }
200
201 /* verification that LSFs has minimum distance of LSF_GAP */
202
203 Reorder_lsf (lsf1_q, LSF_GAP, M);
204 Reorder_lsf (lsf2_q, LSF_GAP, M);
205
206 /* Update LSF history with quantized LSFs
207 when hangover period is active */
208
209 logic16 (); test ();
210 if ((txdtx_ctrl & TX_HANGOVER_ACTIVE) != 0)
211 {
212 update_lsf_history (lsf1_q, lsf2_q, lsf_old_tx);
213 }
214 /* convert LSFs to the cosine domain */
215
216 Lsf_lsp (lsf1_q, lsp1_q, M);
217 Lsf_lsp (lsf2_q, lsp2_q, M);
218 }
219 else
220 {
221 for (i = 0; i < M; i++)
222 {
223 past_r2_q[i] = 0; move16 ();
224 }
225 }
226
227 return;
228 }
229
230 /* Quantization of a 4 dimensional subvector */
231
232 Word16 Vq_subvec ( /* output: return quantization index */
233 Word16 *lsf_r1, /* input : 1st LSF residual vector */
234 Word16 *lsf_r2, /* input : and LSF residual vector */
235 const Word16 *dico, /* input : quantization codebook */
236 Word16 *wf1, /* input : 1st LSF weighting factors */
237 Word16 *wf2, /* input : 2nd LSF weighting factors */
238 Word16 dico_size /* input : size of quantization codebook */
239 )
240 {
241 Word16 i, index, temp;
242 const Word16 *p_dico;
243 Word32 dist_min, dist;
244
245 dist_min = MAX_32; move32 ();
246 p_dico = dico; move16 ();
247
248 for (i = 0; i < dico_size; i++)
249 {
250 temp = sub (lsf_r1[0], *p_dico++);
251 temp = mult (wf1[0], temp);
252 dist = L_mult (temp, temp);
253
254 temp = sub (lsf_r1[1], *p_dico++);
255 temp = mult (wf1[1], temp);
256 dist = L_mac (dist, temp, temp);
257
258 temp = sub (lsf_r2[0], *p_dico++);
259 temp = mult (wf2[0], temp);
260 dist = L_mac (dist, temp, temp);
261
262 temp = sub (lsf_r2[1], *p_dico++);
263 temp = mult (wf2[1], temp);
264 dist = L_mac (dist, temp, temp);
265
266 test ();
267 if (L_sub (dist, dist_min) < (Word32) 0)
268 {
269 dist_min = dist; move32 ();
270 index = i; move16 ();
271 }
272 }
273
274 /* Reading the selected vector */
275
276 p_dico = &dico[shl (index, 2)]; move16 ();
277 lsf_r1[0] = *p_dico++; move16 ();
278 lsf_r1[1] = *p_dico++; move16 ();
279 lsf_r2[0] = *p_dico++; move16 ();
280 lsf_r2[1] = *p_dico++; move16 ();
281
282 return index;
283
284 }
285
286 /* Quantization of a 4 dimensional subvector with a signed codebook */
287
288 Word16 Vq_subvec_s ( /* output: return quantization index */
289 Word16 *lsf_r1, /* input : 1st LSF residual vector */
290 Word16 *lsf_r2, /* input : and LSF residual vector */
291 const Word16 *dico, /* input : quantization codebook */
292 Word16 *wf1, /* input : 1st LSF weighting factors */
293 Word16 *wf2, /* input : 2nd LSF weighting factors */
294 Word16 dico_size) /* input : size of quantization codebook */
295 {
296 Word16 i, index, sign, temp;
297 const Word16 *p_dico;
298 Word32 dist_min, dist;
299
300 dist_min = MAX_32; move32 ();
301 p_dico = dico; move16 ();
302
303 for (i = 0; i < dico_size; i++)
304 {
305 /* test positive */
306
307 temp = sub (lsf_r1[0], *p_dico++);
308 temp = mult (wf1[0], temp);
309 dist = L_mult (temp, temp);
310
311 temp = sub (lsf_r1[1], *p_dico++);
312 temp = mult (wf1[1], temp);
313 dist = L_mac (dist, temp, temp);
314
315 temp = sub (lsf_r2[0], *p_dico++);
316 temp = mult (wf2[0], temp);
317 dist = L_mac (dist, temp, temp);
318
319 temp = sub (lsf_r2[1], *p_dico++);
320 temp = mult (wf2[1], temp);
321 dist = L_mac (dist, temp, temp);
322
323 test ();
324 if (L_sub (dist, dist_min) < (Word32) 0)
325 {
326 dist_min = dist; move32 ();
327 index = i; move16 ();
328 sign = 0; move16 ();
329 }
330 /* test negative */
331
332 p_dico -= 4; move16 ();
333 temp = add (lsf_r1[0], *p_dico++);
334 temp = mult (wf1[0], temp);
335 dist = L_mult (temp, temp);
336
337 temp = add (lsf_r1[1], *p_dico++);
338 temp = mult (wf1[1], temp);
339 dist = L_mac (dist, temp, temp);
340
341 temp = add (lsf_r2[0], *p_dico++);
342 temp = mult (wf2[0], temp);
343 dist = L_mac (dist, temp, temp);
344
345 temp = add (lsf_r2[1], *p_dico++);
346 temp = mult (wf2[1], temp);
347 dist = L_mac (dist, temp, temp);
348
349 test ();
350 if (L_sub (dist, dist_min) < (Word32) 0)
351 {
352 dist_min = dist; move32 ();
353 index = i; move16 ();
354 sign = 1; move16 ();
355 }
356 }
357
358 /* Reading the selected vector */
359
360 p_dico = &dico[shl (index, 2)]; move16 ();
361 test ();
362 if (sign == 0)
363 {
364 lsf_r1[0] = *p_dico++; move16 ();
365 lsf_r1[1] = *p_dico++; move16 ();
366 lsf_r2[0] = *p_dico++; move16 ();
367 lsf_r2[1] = *p_dico++; move16 ();
368 }
369 else
370 {
371 lsf_r1[0] = negate (*p_dico++); move16 ();
372 lsf_r1[1] = negate (*p_dico++); move16 ();
373 lsf_r2[0] = negate (*p_dico++); move16 ();
374 lsf_r2[1] = negate (*p_dico++); move16 ();
375 }
376
377 index = shl (index, 1);
378 index = add (index, sign);
379
380 return index;
381
382 }
383
384 /****************************************************
385 * FUNCTION Lsf_wt *
386 * *
387 ****************************************************
388 * Compute LSF weighting factors *
389 * *
390 * d[i] = lsf[i+1] - lsf[i-1] *
391 * *
392 * The weighting factors are approximated by two line segment. *
393 * *
394 * First segment passes by the following 2 points: *
395 * *
396 * d[i] = 0Hz wf[i] = 3.347 *
397 * d[i] = 450Hz wf[i] = 1.8 *
398 * *
399 * Second segment passes by the following 2 points: *
400 * *
401 * d[i] = 450Hz wf[i] = 1.8 *
402 * d[i] = 1500Hz wf[i] = 1.0 *
403 * *
404 * if( d[i] < 450Hz ) *
405 * wf[i] = 3.347 - ( (3.347-1.8) / (450-0)) * d[i] *
406 * else *
407 * wf[i] = 1.8 - ( (1.8-1.0) / (1500-450)) * (d[i] - 450) *
408 * *
409 * *
410 * if( d[i] < 1843) *
411 * wf[i] = 3427 - (28160*d[i])>>15 *
412 * else *
413 * wf[i] = 1843 - (6242*(d[i]-1843))>>15 *
414 * *
415 *--------------------------------------------------------------------------*/
416
417 void Lsf_wt (
418 Word16 *lsf, /* input : LSF vector */
419 Word16 *wf) /* output: square of weighting factors */
420 {
421 Word16 temp;
422 Word16 i;
423 /* wf[0] = lsf[1] - 0 */
424 wf[0] = lsf[1]; move16 ();
425 for (i = 1; i < 9; i++)
426 {
427 wf[i] = sub (lsf[i + 1], lsf[i - 1]); move16 ();
428 }
429 /* wf[9] = 0.5 - lsf[8] */
430 wf[9] = sub (16384, lsf[8]);move16 ();
431
432 for (i = 0; i < 10; i++)
433 {
434 temp = sub (wf[i], 1843);
435 test ();
436 if (temp < 0)
437 {
438 wf[i] = sub (3427, mult (wf[i], 28160)); move16 ();
439 }
440 else
441 {
442 wf[i] = sub (1843, mult (temp, 6242)); move16 ();
443 }
444
445 wf[i] = shl (wf[i], 3); move16 ();
446 }
447 return;
448 }