FreeCalypso > hg > gsm-codec-lib
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 } |