comparison libtwamr/c8_31pf.c @ 323:dfd5f159574b

libtwamr: integrate c8_31pf.c
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 18 Apr 2024 19:47:13 +0000
parents
children
comparison
equal deleted inserted replaced
322:fc82b113977f 323:dfd5f159574b
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 : c8_31pf.c
11 * Purpose : Searches a 31 bit algebraic codebook containing
12 * : 8 pulses in a frame of 40 samples.
13 * : in the same manner as GSM-EFR
14 *
15 ********************************************************************************
16 */
17 /*
18 ********************************************************************************
19 * MODULE INCLUDE FILE AND VERSION ID
20 ********************************************************************************
21 */
22 #include "namespace.h"
23 #include "c8_31pf.h"
24 /*
25 ********************************************************************************
26 * INCLUDE FILES
27 ********************************************************************************
28 */
29 #include "typedef.h"
30 #include "basic_op.h"
31 #include "no_count.h"
32 #include "cnst.h"
33 #include "inv_sqrt.h"
34 #include "cor_h.h"
35 #include "set_sign.h"
36 #include "s10_8pf.h"
37
38 /*
39 ********************************************************************************
40 * LOCAL VARIABLES AND TABLES
41 ********************************************************************************
42 */
43 #define NB_PULSE 8
44
45 /* define values/representation for output codevector and sign */
46 #define POS_CODE 8191
47 #define NEG_CODE 8191
48 #define POS_SIGN 32767
49 #define NEG_SIGN (Word16) (-32768L)
50
51 /*
52 ********************************************************************************
53 * LOCAL PROGRAM CODE
54 ********************************************************************************
55 */
56
57 /*************************************************************************
58 *
59 * FUNCTION: build_code()
60 *
61 * PURPOSE: Builds the codeword, the filtered codeword and a
62 * linear uncombined version of the index of the
63 * codevector, based on the signs and positions of 8 pulses.
64 *
65 *************************************************************************/
66
67 static void build_code (
68 Word16 codvec[], /* i : position of pulses */
69 Word16 sign[], /* i : sign of d[n] */
70 Word16 cod[], /* o : innovative code vector */
71 Word16 h[], /* i : impulse response of weighted synthesis filter*/
72 Word16 y[], /* o : filtered innovative code */
73 Word16 sign_indx[], /* o : signs of 4 pulses (signs only) */
74 Word16 pos_indx[] /* o : position index of 8 pulses(position only) */
75 )
76 {
77 Word16 i, j, k, track, sign_index, pos_index, _sign[NB_PULSE];
78 Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
79 Word32 s;
80
81 for (i = 0; i < L_CODE; i++)
82 {
83 cod[i] = 0; move16 ();
84 }
85 for (i = 0; i < NB_TRACK_MR102; i++)
86 {
87 pos_indx[i] = -1; move16 ();
88 sign_indx[i] = -1; move16 ();
89 }
90
91 for (k = 0; k < NB_PULSE; k++)
92 {
93 /* read pulse position */
94 i = codvec[k]; move16 ();
95 /* read sign */
96 j = sign[i]; move16 ();
97
98 pos_index = shr(i, 2); /* index = pos/4 */
99 track = i & 3; logic16 (); /* track = pos%4 */
100
101 test ();
102 if (j > 0)
103 {
104 cod[i] = add (cod[i], POS_CODE); move16 ();
105 _sign[k] = POS_SIGN; move16 ();
106 sign_index = 0; /* bit=0 -> positive pulse */ move16 ();
107 }
108 else
109 {
110 cod[i] = sub (cod[i], NEG_CODE); move16 ();
111 _sign[k] = NEG_SIGN; move16 ();
112 sign_index = 1; move16 (); /* bit=1 => negative pulse */
113 /* index = add (index, 8); 1 = negative old code */
114 }
115
116 test (); move16 ();
117 if (pos_indx[track] < 0)
118 { /* first set first NB_TRACK pulses */
119 pos_indx[track] = pos_index; move16 ();
120 sign_indx[track] = sign_index; move16 ();
121 }
122 else
123 { /* 2nd row of pulses , test if positions needs to be switched */
124 test (); logic16 (); logic16 ();
125 if (((sign_index ^ sign_indx[track]) & 1) == 0)
126 {
127 /* sign of 1st pulse == sign of 2nd pulse */
128
129 test ();
130 if (sub (pos_indx[track], pos_index) <= 0)
131 { /* no swap */
132 pos_indx[track + NB_TRACK_MR102] = pos_index; move16 ();
133 }
134 else
135 { /* swap*/
136 pos_indx[track + NB_TRACK_MR102] = pos_indx[track];
137 move16 ();
138
139 pos_indx[track] = pos_index; move16 ();
140 sign_indx[track] = sign_index; move16 ();
141 }
142 }
143 else
144 {
145 /* sign of 1st pulse != sign of 2nd pulse */
146
147 test ();
148 if (sub (pos_indx[track], pos_index) <= 0)
149 { /*swap*/
150 pos_indx[track + NB_TRACK_MR102] = pos_indx[track];
151 move16 ();
152
153 pos_indx[track] = pos_index; move16 ();
154 sign_indx[track] = sign_index; move16 ();
155 }
156 else
157 { /*no swap */
158 pos_indx[track + NB_TRACK_MR102] = pos_index; move16 ();
159 }
160 }
161 }
162 }
163
164 p0 = h - codvec[0]; move16 ();
165 p1 = h - codvec[1]; move16 ();
166 p2 = h - codvec[2]; move16 ();
167 p3 = h - codvec[3]; move16 ();
168 p4 = h - codvec[4]; move16 ();
169 p5 = h - codvec[5]; move16 ();
170 p6 = h - codvec[6]; move16 ();
171 p7 = h - codvec[7]; move16 ();
172
173 for (i = 0; i < L_CODE; i++)
174 {
175 s = 0; move32 ();
176 s = L_mac (s, *p0++, _sign[0]);
177 s = L_mac (s, *p1++, _sign[1]);
178 s = L_mac (s, *p2++, _sign[2]);
179 s = L_mac (s, *p3++, _sign[3]);
180 s = L_mac (s, *p4++, _sign[4]);
181 s = L_mac (s, *p5++, _sign[5]);
182 s = L_mac (s, *p6++, _sign[6]);
183 s = L_mac (s, *p7++, _sign[7]);
184 y[i] = round (s); move16 ();
185 }
186 }
187
188 /*************************************************************************
189 *
190 * FUNCTION: compress_code()
191 *
192 * PURPOSE: compression of three indeces [0..9] to one 10 bit index
193 * minimizing the phase shift of a bit error.
194 *
195 *************************************************************************/
196
197
198 static Word16 compress10 (
199 Word16 pos_indxA, /* i : signs of 4 pulses (signs only) */
200 Word16 pos_indxB, /* i : position index of 8 pulses (pos only) */
201 Word16 pos_indxC) /* i : position and sign of 8 pulses (compressed) */
202 {
203 Word16 indx, ia,ib,ic;
204
205 ia = shr(pos_indxA, 1);
206 ib = extract_l(L_shr(L_mult(shr(pos_indxB, 1), 5), 1));
207 ic = extract_l(L_shr(L_mult(shr(pos_indxC, 1), 25), 1));
208 indx = shl(add(ia, add(ib, ic)), 3);
209 ia = pos_indxA & 1; logic16 ();
210 ib = shl((pos_indxB & 1), 1); logic16 ();
211 ic = shl((pos_indxC & 1), 2); logic16 ();
212 indx = add(indx , add(ia, add(ib, ic)));
213
214 return indx;
215
216 }
217
218 /*************************************************************************
219 *
220 * FUNCTION: compress_code()
221 *
222 * PURPOSE: compression of the linear codewords to 4+three indeces
223 * one bit from each pulse is made robust to errors by
224 * minimizing the phase shift of a bit error.
225 * 4 signs (one for each track)
226 * i0,i4,i1 => one index (7+3) bits, 3 LSBs more robust
227 * i2,i6,i5 => one index (7+3) bits, 3 LSBs more robust
228 * i3,i7 => one index (5+2) bits, 2-3 LSbs more robust
229 *
230 *************************************************************************/
231
232
233 static void compress_code (
234 Word16 sign_indx[], /* i : signs of 4 pulses (signs only) */
235 Word16 pos_indx[], /* i : position index of 8 pulses (position only) */
236 Word16 indx[]) /* o : position and sign of 8 pulses (compressed) */
237 {
238 Word16 i, ia, ib, ic;
239
240 for (i = 0; i < NB_TRACK_MR102; i++)
241 {
242 indx[i] = sign_indx[i]; move16 ();
243 }
244
245 /* First index
246 indx[NB_TRACK] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */
247 move16 ();
248 indx[NB_TRACK_MR102] = compress10(pos_indx[0],pos_indx[4],pos_indx[1]);
249
250 /* Second index
251 indx[NB_TRACK+1] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */
252
253 move16 ();
254 indx[NB_TRACK_MR102+1]= compress10(pos_indx[2],pos_indx[6],pos_indx[5]);
255
256 /*
257 Third index
258 if ((ib/2)%2 == 1)
259 indx[NB_TRACK+2] = ((((4-ia/2) + (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2;
260 else
261 indx[NB_TRACK+2] = ((((ia/2) + (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2;
262 */
263
264 ib = shr(pos_indx[7], 1) & 1; logic16 ();
265 test ();
266 if (sub(ib, 1) == 0)
267 ia = sub(4, shr(pos_indx[3], 1));
268 else
269 ia = shr(pos_indx[3], 1);
270
271 ib = extract_l(L_shr(L_mult(shr(pos_indx[7], 1), 5), 1));
272 ib = add(shl(add(ia, ib), 5), 12);
273 ic = shl(mult(ib, 1311), 2);
274 ia = pos_indx[3] & 1; logic16 ();
275 ib = shl((pos_indx[7] & 1), 1); logic16 ();
276 indx[NB_TRACK_MR102+2] = add(ia, add(ib, ic));
277 }
278
279
280 /*
281 ********************************************************************************
282 * PUBLIC PROGRAM CODE
283 ********************************************************************************
284 */
285 /*************************************************************************
286 *
287 * FUNCTION: code_8i40_31bits()
288 *
289 * PURPOSE: Searches a 31 bit algebraic codebook containing 8 pulses
290 * in a frame of 40 samples.
291 *
292 * DESCRIPTION:
293 * The code contains 8 nonzero pulses: i0...i7.
294 * All pulses can have two possible amplitudes: +1 or -1.
295 * The 40 positions in a subframe are divided into 4 tracks of
296 * interleaved positions. Each track contains two pulses.
297 * The pulses can have the following possible positions:
298 *
299 * i0, i4 : 0, 4, 8, 12, 16, 20, 24, 28, 32, 36
300 * i1, i5 : 1, 5, 9, 13, 17, 21, 25, 29, 33, 37
301 * i2, i6 : 2, 6, 10, 14, 18, 22, 26, 30, 34, 38
302 * i3, i7 : 3, 7, 11, 15, 19, 23, 27, 31, 35, 39
303 *
304 * Each pair of pulses require 1 bit for their signs. The positions
305 * are encoded together 3,3 and 2 resulting in
306 * (7+3) + (7+3) + (5+2) bits for their
307 * positions. This results in a 31 (4 sign and 27 pos) bit codebook.
308 * The function determines the optimal pulse signs and positions, builds
309 * the codevector, and computes the filtered codevector.
310 *
311 *************************************************************************/
312
313 void code_8i40_31bits (
314 Word16 x[], /* i : target vector */
315 Word16 cn[], /* i : residual after long term prediction */
316 Word16 h[], /* i : impulse response of weighted synthesis
317 filter */
318 Word16 cod[], /* o : algebraic (fixed) codebook excitation */
319 Word16 y[], /* o : filtered fixed codebook excitation */
320 Word16 indx[] /* o : 7 Word16, index of 8 pulses (signs+positions) */
321 )
322 {
323 Word16 ipos[NB_PULSE], pos_max[NB_TRACK_MR102], codvec[NB_PULSE];
324 Word16 dn[L_CODE], sign[L_CODE];
325 Word16 rr[L_CODE][L_CODE];
326 Word16 linear_signs[NB_TRACK_MR102];
327 Word16 linear_codewords[NB_PULSE];
328
329 cor_h_x2 (h, x, dn, 2, NB_TRACK_MR102, STEP_MR102);
330 /* 2 = use GSMEFR scaling */
331
332 set_sign12k2 (dn, cn, sign, pos_max, NB_TRACK_MR102, ipos, STEP_MR102);
333 /* same setsign alg as GSM-EFR new constants though*/
334
335 cor_h (h, sign, rr);
336 search_10and8i40 (NB_PULSE, STEP_MR102, NB_TRACK_MR102,
337 dn, rr, ipos, pos_max, codvec);
338
339 build_code (codvec, sign, cod, h, y, linear_signs, linear_codewords);
340 compress_code (linear_signs, linear_codewords, indx);
341
342 return;
343 }