comparison libtwamr/q_plsf_5.c @ 373:128ec87489b6

libtwamr: integrate q_plsf_5.c
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 06 May 2024 04:03:21 +0000
parents
children
comparison
equal deleted inserted replaced
372:9cca139a20a8 373:128ec87489b6
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_5.c
11 * Purpose : Quantization of 2 sets of LSF parameters using 1st
12 * order MA prediction and split by 5 matrix
13 * quantization (split-MQ)
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 "q_plsf5_tab.h"
38
39 /*
40 ********************************************************************************
41 * LOCAL PROGRAM CODE
42 ********************************************************************************
43 */
44 /* Quantization of a 4 dimensional subvector */
45
46 static Word16 Vq_subvec (/* o : quantization index, Q0 */
47 Word16 *lsf_r1, /* i : 1st LSF residual vector, Q15 */
48 Word16 *lsf_r2, /* i : 2nd LSF residual vector, Q15 */
49 const Word16 *dico, /* i : quantization codebook, Q15 */
50 Word16 *wf1, /* i : 1st LSF weighting factors Q13 */
51 Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */
52 Word16 dico_size /* i : size of quantization codebook, Q0 */
53 )
54 {
55 Word16 index = 0; /* initialization only needed to keep gcc silent */
56 Word16 i, temp;
57 const Word16 *p_dico;
58 Word32 dist_min, dist;
59
60 dist_min = MAX_32; move32 ();
61 p_dico = dico; move16 ();
62
63 for (i = 0; i < dico_size; i++)
64 {
65 temp = sub (lsf_r1[0], *p_dico++);
66 temp = mult (wf1[0], temp);
67 dist = L_mult (temp, temp);
68
69 temp = sub (lsf_r1[1], *p_dico++);
70 temp = mult (wf1[1], temp);
71 dist = L_mac (dist, temp, temp);
72
73 temp = sub (lsf_r2[0], *p_dico++);
74 temp = mult (wf2[0], temp);
75 dist = L_mac (dist, temp, temp);
76
77 temp = sub (lsf_r2[1], *p_dico++);
78 temp = mult (wf2[1], temp);
79 dist = L_mac (dist, temp, temp);
80
81 test ();
82 if (L_sub (dist, dist_min) < (Word32) 0)
83 {
84 dist_min = dist; move32 ();
85 index = i; move16 ();
86 }
87 }
88
89 /* Reading the selected vector */
90
91 p_dico = &dico[shl (index, 2)]; move16 ();
92 lsf_r1[0] = *p_dico++; move16 ();
93 lsf_r1[1] = *p_dico++; move16 ();
94 lsf_r2[0] = *p_dico++; move16 ();
95 lsf_r2[1] = *p_dico++; move16 ();
96
97 return index;
98 }
99
100 /* Quantization of a 4 dimensional subvector with a signed codebook */
101
102 static Word16 Vq_subvec_s ( /* o : quantization index Q0 */
103 Word16 *lsf_r1, /* i : 1st LSF residual vector Q15 */
104 Word16 *lsf_r2, /* i : and LSF residual vector Q15 */
105 const Word16 *dico, /* i : quantization codebook Q15 */
106 Word16 *wf1, /* i : 1st LSF weighting factors Q13 */
107 Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */
108 Word16 dico_size) /* i : size of quantization codebook Q0 */
109 {
110 Word16 index = 0; /* initialization only needed to keep gcc silent */
111 Word16 sign = 0; /* initialization only needed to keep gcc silent */
112 Word16 i, temp;
113 const Word16 *p_dico;
114 Word32 dist_min, dist;
115
116 dist_min = MAX_32; move32 ();
117 p_dico = dico; move16 ();
118
119 for (i = 0; i < dico_size; i++)
120 {
121 /* test positive */
122
123 temp = sub (lsf_r1[0], *p_dico++);
124 temp = mult (wf1[0], temp);
125 dist = L_mult (temp, temp);
126
127 temp = sub (lsf_r1[1], *p_dico++);
128 temp = mult (wf1[1], temp);
129 dist = L_mac (dist, temp, temp);
130
131 temp = sub (lsf_r2[0], *p_dico++);
132 temp = mult (wf2[0], temp);
133 dist = L_mac (dist, temp, temp);
134
135 temp = sub (lsf_r2[1], *p_dico++);
136 temp = mult (wf2[1], temp);
137 dist = L_mac (dist, temp, temp);
138
139 test ();
140 if (L_sub (dist, dist_min) < (Word32) 0)
141 {
142 dist_min = dist; move32 ();
143 index = i; move16 ();
144 sign = 0; move16 ();
145 }
146 /* test negative */
147
148 p_dico -= 4; move16 ();
149 temp = add (lsf_r1[0], *p_dico++);
150 temp = mult (wf1[0], temp);
151 dist = L_mult (temp, temp);
152
153 temp = add (lsf_r1[1], *p_dico++);
154 temp = mult (wf1[1], temp);
155 dist = L_mac (dist, temp, temp);
156
157 temp = add (lsf_r2[0], *p_dico++);
158 temp = mult (wf2[0], temp);
159 dist = L_mac (dist, temp, temp);
160
161 temp = add (lsf_r2[1], *p_dico++);
162 temp = mult (wf2[1], temp);
163 dist = L_mac (dist, temp, temp);
164
165 test ();
166 if (L_sub (dist, dist_min) < (Word32) 0)
167 {
168 dist_min = dist; move32 ();
169 index = i; move16 ();
170 sign = 1; move16 ();
171 }
172 }
173
174 /* Reading the selected vector */
175
176 p_dico = &dico[shl (index, 2)]; move16 ();
177 test ();
178 if (sign == 0)
179 {
180 lsf_r1[0] = *p_dico++; move16 ();
181 lsf_r1[1] = *p_dico++; move16 ();
182 lsf_r2[0] = *p_dico++; move16 ();
183 lsf_r2[1] = *p_dico++; move16 ();
184 }
185 else
186 {
187 lsf_r1[0] = negate (*p_dico++); move16 ();
188 lsf_r1[1] = negate (*p_dico++); move16 ();
189 lsf_r2[0] = negate (*p_dico++); move16 ();
190 lsf_r2[1] = negate (*p_dico++); move16 ();
191 }
192
193 index = shl (index, 1);
194 index = add (index, sign);
195
196 return index;
197 }
198
199 /*
200 ********************************************************************************
201 * PUBLIC PROGRAM CODE
202 ********************************************************************************
203 */
204
205 /*************************************************************************
206 * FUNCTION: Q_plsf_5()
207 *
208 * PURPOSE: Quantization of 2 sets of LSF parameters using 1st order MA
209 * prediction and split by 5 matrix quantization (split-MQ)
210 *
211 * DESCRIPTION:
212 *
213 * p[i] = pred_factor*past_rq[i]; i=0,...,m-1
214 * r1[i]= lsf1[i] - p[i]; i=0,...,m-1
215 * r2[i]= lsf2[i] - p[i]; i=0,...,m-1
216 * where:
217 * lsf1[i] 1st mean-removed LSF vector.
218 * lsf2[i] 2nd mean-removed LSF vector.
219 * r1[i] 1st residual prediction vector.
220 * r2[i] 2nd residual prediction vector.
221 * past_r2q[i] Past quantized residual (2nd vector).
222 *
223 * The residual vectors r1[i] and r2[i] are jointly quantized using
224 * split-MQ with 5 codebooks. Each 4th dimension submatrix contains 2
225 * elements from each residual vector. The 5 submatrices are as follows:
226 * {r1[0], r1[1], r2[0], r2[1]}; {r1[2], r1[3], r2[2], r2[3]};
227 * {r1[4], r1[5], r2[4], r2[5]}; {r1[6], r1[7], r2[6], r2[7]};
228 * {r1[8], r1[9], r2[8], r2[9]};
229 *
230 *************************************************************************/
231 void Q_plsf_5 (
232 Q_plsfState *st,
233 Word16 *lsp1, /* i : 1st LSP vector, Q15 */
234 Word16 *lsp2, /* i : 2nd LSP vector, Q15 */
235 Word16 *lsp1_q, /* o : quantized 1st LSP vector, Q15 */
236 Word16 *lsp2_q, /* o : quantized 2nd LSP vector, Q15 */
237 Word16 *indice /* o : quantization indices of 5 matrices, Q0 */
238 )
239 {
240 Word16 i;
241 Word16 lsf1[M], lsf2[M], wf1[M], wf2[M], lsf_p[M], lsf_r1[M], lsf_r2[M];
242 Word16 lsf1_q[M], lsf2_q[M];
243
244 /* convert LSFs to normalize frequency domain 0..16384 */
245
246 Lsp_lsf (lsp1, lsf1, M);
247 Lsp_lsf (lsp2, lsf2, M);
248
249 /* Compute LSF weighting factors (Q13) */
250
251 Lsf_wt (lsf1, wf1);
252 Lsf_wt (lsf2, wf2);
253
254 /* Compute predicted LSF and prediction error */
255
256 for (i = 0; i < M; i++)
257 {
258 lsf_p[i] = add (mean_lsf[i], mult (st->past_rq[i], LSP_PRED_FAC_MR122));
259 move16 ();
260 lsf_r1[i] = sub (lsf1[i], lsf_p[i]); move16 ();
261 lsf_r2[i] = sub (lsf2[i], lsf_p[i]); move16 ();
262 }
263
264 /*---- Split-MQ of prediction error ----*/
265
266 indice[0] = Vq_subvec (&lsf_r1[0], &lsf_r2[0], dico1_lsf,
267 &wf1[0], &wf2[0], DICO1_SIZE);
268 move16 ();
269
270 indice[1] = Vq_subvec (&lsf_r1[2], &lsf_r2[2], dico2_lsf,
271 &wf1[2], &wf2[2], DICO2_SIZE);
272 move16 ();
273
274 indice[2] = Vq_subvec_s (&lsf_r1[4], &lsf_r2[4], dico3_lsf,
275 &wf1[4], &wf2[4], DICO3_SIZE);
276 move16 ();
277
278 indice[3] = Vq_subvec (&lsf_r1[6], &lsf_r2[6], dico4_lsf,
279 &wf1[6], &wf2[6], DICO4_SIZE);
280 move16 ();
281
282 indice[4] = Vq_subvec (&lsf_r1[8], &lsf_r2[8], dico5_lsf,
283 &wf1[8], &wf2[8], DICO5_SIZE);
284 move16 ();
285
286 /* Compute quantized LSFs and update the past quantized residual */
287 for (i = 0; i < M; i++)
288 {
289 lsf1_q[i] = add (lsf_r1[i], lsf_p[i]); move16 ();
290 lsf2_q[i] = add (lsf_r2[i], lsf_p[i]); move16 ();
291 st->past_rq[i] = lsf_r2[i]; move16 ();
292 }
293
294 /* verification that LSFs has minimum distance of LSF_GAP */
295
296 Reorder_lsf (lsf1_q, LSF_GAP, M);
297 Reorder_lsf (lsf2_q, LSF_GAP, M);
298
299 /* convert LSFs to the cosine domain */
300
301 Lsf_lsp (lsf1_q, lsp1_q, M);
302 Lsf_lsp (lsf2_q, lsp2_q, M);
303 }