comparison libtwamr/c2_11pf.c @ 319:9bca350be398

libtwamr: integrate c2_11pf.c
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 18 Apr 2024 19:23:20 +0000
parents
children
comparison
equal deleted inserted replaced
318:6fd6c5fc1aa4 319:9bca350be398
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 : c2_11pf.c
11 * Purpose : Searches a 11 bit algebraic codebook containing 2 pulses
12 * in a frame of 40 samples.
13 *
14 *****************************************************************************
15 */
16
17 /*
18 *****************************************************************************
19 * MODULE INCLUDE FILE AND VERSION ID
20 *****************************************************************************
21 */
22 #include "namespace.h"
23 #include "c2_11pf.h"
24
25 /*
26 *****************************************************************************
27 * INCLUDE FILES
28 *****************************************************************************
29 */
30 #include "typedef.h"
31 #include "basic_op.h"
32 #include "no_count.h"
33 #include "inv_sqrt.h"
34 #include "cnst.h"
35 #include "cor_h.h"
36 #include "set_sign.h"
37
38 /*
39 *****************************************************************************
40 * LOCAL VARIABLES AND TABLES
41 *****************************************************************************
42 */
43 #define NB_PULSE 2
44
45 #include "c2_11pf.tab"
46
47 /*
48 *****************************************************************************
49 * DECLARATION OF PROTOTYPES
50 *****************************************************************************
51 */
52 static void search_2i40(
53 Word16 dn[], /* i : correlation between target and h[] */
54 Word16 rr[][L_CODE],/* i : matrix of autocorrelation */
55 Word16 codvec[] /* o : algebraic codebook vector */
56 );
57
58 static Word16 build_code(
59 Word16 codvec[], /* i : algebraic codebook vector */
60 Word16 dn_sign[], /* i : sign of dn[] */
61 Word16 cod[], /* o : algebraic (fixed) codebook excitation */
62 Word16 h[], /* i : impulse response of weighted synthesis filter */
63 Word16 y[], /* o : filtered fixed codebook excitation */
64 Word16 sign[] /* o : sign of 2 pulses */
65 );
66
67 /*
68 *****************************************************************************
69 * PUBLIC PROGRAM CODE
70 *****************************************************************************
71 */
72 /*************************************************************************
73 *
74 * FUNCTION: code_2i40_11bits()
75 *
76 * PURPOSE: Searches a 11 bit algebraic codebook containing 2 pulses
77 * in a frame of 40 samples.
78 *
79 * DESCRIPTION:
80 * The code length is 40, containing 2 nonzero pulses: i0...i1.
81 * All pulses can have two possible amplitudes: +1 or -1.
82 * Pulse i0 can have 2x8=16 possible positions, pulse i1 can have
83 * 4x8=32 positions.
84 *
85 * i0 : 1, 6, 11, 16, 21, 26, 31, 36.
86 * 3, 8, 13, 18, 23, 28, 33, 38.
87 * i1 : 0, 5, 10, 15, 20, 25, 30, 35.
88 * 1, 6, 11, 16, 21, 26, 31, 36.
89 * 2, 7, 12, 17, 22, 27, 32, 37.
90 * 4, 9, 14, 19, 24, 29, 34, 39.
91 *
92 *************************************************************************/
93 Word16 code_2i40_11bits(
94 Word16 x[], /* i : target vector */
95 Word16 h[], /* i : impulse response of weighted synthesis filter */
96 /* h[-L_subfr..-1] must be set to zero. */
97 Word16 T0, /* i : Pitch lag */
98 Word16 pitch_sharp, /* i : Last quantized pitch gain */
99 Word16 code[], /* o : Innovative codebook */
100 Word16 y[], /* o : filtered fixed codebook excitation */
101 Word16 * sign /* o : Signs of 2 pulses */
102 )
103 {
104 Word16 codvec[NB_PULSE];
105 Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE];
106 Word16 rr[L_CODE][L_CODE];
107 Word16 i, index, sharp;
108
109 sharp = shl(pitch_sharp, 1);
110 test ();
111 if (sub(T0, L_CODE) < 0)
112 {
113 for (i = T0; i < L_CODE; i++) {
114 h[i] = add(h[i], mult(h[i - T0], sharp)); move16 ();
115 }
116 }
117
118 cor_h_x(h, x, dn, 1);
119 set_sign(dn, dn_sign, dn2, 8); /* dn2[] not used in this codebook search */
120 cor_h(h, dn_sign, rr);
121 search_2i40(dn, rr, codvec);
122 move16 (); /* function result */
123 index = build_code(codvec, dn_sign, code, h, y, sign);
124
125 /*-----------------------------------------------------------------*
126 * Compute innovation vector gain. *
127 * Include fixed-gain pitch contribution into code[]. *
128 *-----------------------------------------------------------------*/
129
130 test ();
131 if (sub(T0, L_CODE) < 0)
132 {
133 for (i = T0; i < L_CODE; i++)
134 {
135 code[i] = add(code[i], mult(code[i - T0], sharp)); move16 ();
136 }
137 }
138 return index;
139 }
140
141 /*
142 *****************************************************************************
143 * PRIVATE PROGRAM CODE
144 *****************************************************************************
145 */
146 /*************************************************************************
147 *
148 * FUNCTION search_2i40()
149 *
150 * PURPOSE: Search the best codevector; determine positions of the 2 pulses
151 * in the 40-sample frame.
152 *
153 *************************************************************************/
154
155 #define _1_2 (Word16)(32768L/2)
156 #define _1_4 (Word16)(32768L/4)
157 #define _1_8 (Word16)(32768L/8)
158 #define _1_16 (Word16)(32768L/16)
159
160 static void search_2i40(
161 Word16 dn[], /* i : correlation between target and h[] */
162 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
163 Word16 codvec[] /* o : algebraic codebook vector */
164 )
165 {
166 Word16 i0, i1;
167 Word16 ix = 0; /* initialization only needed to keep gcc silent */
168 Word16 track1, track2, ipos[NB_PULSE];
169 Word16 psk, ps0, ps1, sq, sq1;
170 Word16 alpk, alp, alp_16;
171 Word32 s, alp0, alp1;
172 Word16 i;
173
174 psk = -1; move16 ();
175 alpk = 1; move16 ();
176 for (i = 0; i < NB_PULSE; i++)
177 {
178 codvec[i] = i; move16 ();
179 }
180
181 /*------------------------------------------------------------------*
182 * main loop: try 2x4 tracks. *
183 *------------------------------------------------------------------*/
184
185 for (track1 = 0; track1 < 2; track1++)
186 {
187 for (track2 = 0; track2 < 4; track2++)
188 {
189 /* fix starting position */
190 ipos[0] = startPos1[track1]; move16 ();
191 ipos[1] = startPos2[track2]; move16 ();
192
193 /*----------------------------------------------------------------*
194 * i0 loop: try 8 positions. *
195 *----------------------------------------------------------------*/
196 move16 (); /* account for ptr. init. (rr[io]) */
197 for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)
198 {
199 ps0 = dn[i0]; move16 ();
200 alp0 = L_mult(rr[i0][i0], _1_4);
201
202 /*-------------------------------------------------------------*
203 * i1 loop: 8 positions. *
204 *-------------------------------------------------------------*/
205
206 sq = -1; move16 ();
207 alp = 1; move16 ();
208 ix = ipos[1]; move16 ();
209
210 /*---------------------------------------------------------------*
211 * These index have low complexity address computation because *
212 * they are, in fact, pointers with fixed increment. For example,*
213 * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" *
214 * and incremented by "STEP". *
215 *---------------------------------------------------------------*/
216
217 move16 (); /* account for ptr. init. (rr[i1]) */
218 move16 (); /* account for ptr. init. (dn[i1]) */
219 move16 (); /* account for ptr. init. (rr[io]) */
220 for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) {
221 ps1 = add(ps0, dn[i1]); /* idx increment = STEP */
222
223 /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
224
225 alp1 = L_mac(alp0, rr[i1][i1], _1_4); /* idx incr = STEP */
226 alp1 = L_mac(alp1, rr[i0][i1], _1_2); /* idx incr = STEP */
227
228 sq1 = mult(ps1, ps1);
229
230 alp_16 = round(alp1);
231
232 s = L_msu(L_mult(alp, sq1), sq, alp_16);
233
234 test ();
235 if (s > 0)
236 {
237 sq = sq1; move16 ();
238 alp = alp_16; move16 ();
239 ix = i1; move16 ();
240 }
241 }
242
243 /*---------------------------------------------------------------*
244 * memorise codevector if this one is better than the last one. *
245 *---------------------------------------------------------------*/
246
247 s = L_msu(L_mult(alpk, sq), psk, alp);
248
249 test ();
250 if (s > 0)
251 {
252 psk = sq; move16 ();
253 alpk = alp; move16 ();
254 codvec[0] = i0; move16 ();
255 codvec[1] = ix; move16 ();
256 }
257 }
258 }
259 }
260 return;
261 }
262
263 /*************************************************************************
264 *
265 * FUNCTION: build_code()
266 *
267 * PURPOSE: Builds the codeword, the filtered codeword and index of the
268 * codevector, based on the signs and positions of 2 pulses.
269 *
270 *************************************************************************/
271
272 static Word16 build_code(
273 Word16 codvec[], /* i : position of pulses */
274 Word16 dn_sign[], /* i : sign of pulses */
275 Word16 cod[], /* o : innovative code vector */
276 Word16 h[], /* i : impulse response of weighted synthesis filter */
277 Word16 y[], /* o : filtered innovative code */
278 Word16 sign[] /* o : sign of 2 pulses */
279 )
280 {
281 Word16 i, j, k, track, index, _sign[NB_PULSE], indx, rsign;
282 Word16 *p0, *p1;
283 Word32 s;
284
285 for (i = 0; i < L_CODE; i++)
286 {
287 cod[i] = 0; move16 ();
288 }
289
290 indx = 0; move16 ();
291 rsign = 0; move16 ();
292 for (k = 0; k < NB_PULSE; k++)
293 {
294 i = codvec[k]; /* read pulse position */ move16 ();
295 j = dn_sign[i]; /* read sign */ move16 ();
296
297 index = mult(i, 6554); /* index = pos/5 */
298 /* track = pos%5 */
299 track = sub(i, extract_l(L_shr(L_mult(index, 5), 1)));
300
301 test (); test (); test (); test ();
302 if (sub(track, 0) == 0)
303 {
304 track = 1; move16 ();
305 index = shl(index, 6);
306 }
307 else if (sub(track, 1) == 0)
308 {
309 test ();
310 if (sub(k, 0) == 0)
311 {
312 track = 0; move16 ();
313 index = shl(index, 1);
314 }
315 else
316 {
317 track = 1; move16 ();
318 index = add(shl(index, 6), 16);
319 }
320 }
321 else if (sub(track, 2) == 0)
322 {
323 track = 1; move16 ();
324 index = add(shl(index, 6), 32);
325 }
326 else if (sub(track, 3) == 0)
327 {
328 track = 0; move16 ();
329 index = add(shl(index, 1), 1);
330 }
331 else if (sub(track, 4) == 0)
332 {
333 track = 1; move16 ();
334 index = add(shl(index, 6), 48);
335 }
336
337 test ();
338 if (j > 0)
339 {
340 cod[i] = 8191; move16 ();
341 _sign[k] = 32767; move16 ();
342 rsign = add(rsign, shl(1, track));
343 }
344 else
345 {
346 cod[i] = -8192; move16 ();
347 _sign[k] = (Word16) - 32768L; move16 ();
348 }
349
350 indx = add(indx, index);
351 }
352 *sign = rsign; move16 ();
353
354 p0 = h - codvec[0]; move16 ();
355 p1 = h - codvec[1]; move16 ();
356
357 for (i = 0; i < L_CODE; i++)
358 {
359 s = 0; move32 ();
360 s = L_mac(s, *p0++, _sign[0]);
361 s = L_mac(s, *p1++, _sign[1]);
362 y[i] = round(s); move16 ();
363 }
364
365 return indx;
366 }