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