Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : #include "rom_com.h" /* Common constants */
8 : #include "prot_fx.h" /* Function prototypes */
9 : #include "prot_fx_enc.h" /* Function prototypes */
10 :
11 : /*-------------------------------------------------------------------*
12 : * Local Constants
13 : *-------------------------------------------------------------------*/
14 :
15 : #define STEP 2
16 : #define MSIZE 1024
17 :
18 : /*----------------------------------------------------------------------------------
19 : * Function acelp_2t32()
20 : *
21 : * 12 bits algebraic codebook.
22 : * 2 tracks x 32 positions per track = 64 samples.
23 : *
24 : * 12 bits --> 2 pulses in a frame of 64 samples.
25 : *
26 : * All pulses can have two (2) possible amplitudes: +1 or -1.
27 : * Each pulse can have 32 possible positions.
28 : *----------------------------------------------------------------------------------*/
29 :
30 0 : void acelp_2t32_fx(
31 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
32 : const Word16 dn[], /* i : corr. between target and h[]. Qx*/
33 : const Word16 h[], /* i : impulse response of weighted synthesis filter Q12*/
34 : Word16 code[], /* o : algebraic (fixed) codebook excitation Q9*/
35 : Word16 y[] /* o : filtered fixed codebook excitation Q9*/
36 : )
37 : {
38 : Word16 i, j, k, i0, i1, ix, iy, pos, pos2, sign0, sign1, index;
39 : Word16 ps1, ps2, alpk, alp1, alp2;
40 : Word16 sq, psk;
41 : Word16 pol[L_SUBFR], dn_p[L_SUBFR];
42 : Word16 ii, jj;
43 : Word16 *p0, *p1, *p2;
44 : const Word16 *ptr_h1, *ptr_h2, *ptr_hf;
45 :
46 : Word32 s, L_cor;
47 : Word32 L_tmp;
48 : Word16 rrixix[NB_TRACK_FCB_2T][NB_POS_FCB_2T];
49 : Word16 rrixiy[MSIZE];
50 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
51 0 : Flag Overflow = 0;
52 0 : move32();
53 : #endif
54 : /*----------------------------------------------------------------*
55 : * Compute rrixix[][] needed for the codebook search.
56 : *----------------------------------------------------------------*/
57 :
58 : /* Init pointers to last position of rrixix[] */
59 0 : p0 = &rrixix[0][NB_POS_FCB_2T - 1];
60 0 : p1 = &rrixix[1][NB_POS_FCB_2T - 1];
61 :
62 0 : ptr_h1 = h;
63 0 : L_cor = L_deposit_h( 1 );
64 0 : FOR( i = 0; i < NB_POS_FCB_2T; i++ )
65 : {
66 0 : L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow );
67 0 : ptr_h1++;
68 0 : *p1-- = extract_h( L_cor );
69 0 : move16(); /*Q9 Q7*/
70 0 : L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow );
71 0 : ptr_h1++;
72 0 : *p0-- = extract_h( L_cor );
73 0 : move16(); /*Q9 Q7*/
74 : }
75 :
76 0 : p0 = rrixix[0];
77 0 : p1 = rrixix[1];
78 :
79 0 : FOR( i = 0; i < NB_POS_FCB_2T; i++ )
80 : {
81 0 : *p0 = shr( *p0, 1 );
82 0 : move16();
83 0 : p0++;
84 0 : *p1 = shr( *p1, 1 );
85 0 : move16();
86 0 : p1++;
87 : }
88 :
89 : /*------------------------------------------------------------*
90 : * Compute rrixiy[][] needed for the codebook search.
91 : *------------------------------------------------------------*/
92 :
93 0 : pos = MSIZE - 1;
94 0 : move16();
95 0 : pos2 = MSIZE - 2;
96 0 : move16();
97 0 : ptr_hf = h + 1;
98 :
99 0 : FOR( k = 0; k < NB_POS_FCB_2T; k++ )
100 : {
101 : /* Init pointers to last position of diagonals */
102 0 : p1 = &rrixiy[pos];
103 0 : p0 = &rrixiy[pos2];
104 :
105 0 : ptr_h1 = h;
106 0 : ptr_h2 = ptr_hf;
107 :
108 0 : L_cor = L_mult( *ptr_h1++, *ptr_h2++ ); // Q(12+12+1)
109 0 : FOR( i = k; i < NB_POS_FCB_2T - 1; i++ )
110 : {
111 0 : *p1 = round_fx_o( L_cor, &Overflow ); // Q(25-16)
112 0 : L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow );
113 0 : *p0 = round_fx_o( L_cor, &Overflow ); // Q(9)
114 0 : L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow );
115 0 : move16();
116 0 : move16();
117 0 : p1 -= ( NB_POS_FCB_2T + 1 );
118 0 : p0 -= ( NB_POS_FCB_2T + 1 );
119 : }
120 :
121 0 : *p1 = round_fx_o( L_cor, &Overflow ); // Q9
122 0 : pos -= NB_POS_FCB_2T;
123 0 : move16();
124 0 : pos2--;
125 0 : ptr_hf += STEP;
126 : }
127 :
128 : /*----------------------------------------------------------------*
129 : * computing reference vector and pre-selection of polarities
130 : *----------------------------------------------------------------*/
131 :
132 0 : L_tmp = L_deposit_h( dn[0] );
133 0 : FOR( i = 0; i < L_SUBFR; i++ )
134 : {
135 : /* FIR high-pass filtering */
136 0 : IF( i == 0 )
137 : {
138 0 : L_tmp = L_msu( L_tmp, dn[1], 11469 /*.3f Q15*/ );
139 : }
140 0 : ELSE IF( EQ_16( i, L_SUBFR - 1 ) )
141 : {
142 0 : L_tmp = L_deposit_h( dn[i] );
143 0 : L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ );
144 : }
145 : ELSE
146 : {
147 0 : L_tmp = L_deposit_h( dn[i] );
148 0 : L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ );
149 0 : L_tmp = L_msu( L_tmp, dn[i + 1], 11469 /*.3f Q15*/ );
150 : }
151 :
152 : /* pre-selection of polarities */
153 0 : IF( L_tmp >= 0 )
154 : {
155 0 : pol[i] = 1;
156 0 : move16();
157 0 : dn_p[i] = dn[i];
158 0 : move16();
159 : }
160 : ELSE
161 : {
162 0 : pol[i] = -1;
163 0 : move16();
164 0 : dn_p[i] = negate( dn[i] );
165 0 : move16();
166 : }
167 : }
168 :
169 : /*----------------------------------------------------------------*
170 : * compute denominator ( multiplied by polarity )
171 : *----------------------------------------------------------------*/
172 :
173 0 : k = 0;
174 0 : ii = 0;
175 0 : move16();
176 0 : move16();
177 0 : FOR( i = 0; i < NB_POS_FCB_2T; i++ )
178 : {
179 0 : jj = 1;
180 0 : move16();
181 0 : FOR( j = 0; j < NB_POS_FCB_2T; j++ )
182 : {
183 0 : test();
184 0 : if ( EQ_16( s_and( pol[ii], pol[jj] ), 1 ) && EQ_16( s_or( pol[ii], pol[jj] ), -1 ) )
185 : {
186 0 : rrixiy[k + j] = negate( rrixiy[k + j] );
187 0 : move16();
188 : }
189 0 : jj = add( jj, 2 );
190 : }
191 0 : ii = add( ii, 2 );
192 0 : k = add( k, NB_POS_FCB_2T );
193 : }
194 :
195 : /*----------------------------------------------------------------*
196 : * search 2 pulses
197 : * All combinaisons are tested:
198 : * 32 pos x 32 pos x 2 signs = 2048 tests
199 : *----------------------------------------------------------------*/
200 :
201 0 : p0 = rrixix[0];
202 0 : p1 = rrixix[1];
203 0 : p2 = rrixiy;
204 0 : psk = -1;
205 0 : move16();
206 0 : alpk = 1;
207 0 : move16();
208 0 : ix = 0;
209 0 : move16();
210 0 : iy = 1;
211 0 : move16();
212 :
213 0 : FOR( i0 = 0; i0 < L_SUBFR; i0 += STEP )
214 : {
215 0 : ps1 = dn_p[i0];
216 0 : move16();
217 0 : alp1 = *p0++;
218 0 : move16();
219 0 : pos = -1;
220 0 : move16();
221 0 : FOR( i1 = 1; i1 < L_SUBFR; i1 += STEP )
222 : {
223 0 : ps2 = add( ps1, dn_p[i1] );
224 0 : alp2 = add_o( alp1, add_o( *p1++, *p2++, &Overflow ), &Overflow );
225 0 : sq = mult( ps2, ps2 );
226 0 : s = L_msu_o( L_mult( alpk, sq ), psk, alp2, &Overflow );
227 0 : IF( s > 0 )
228 : {
229 0 : psk = sq;
230 0 : move16();
231 0 : alpk = alp2;
232 0 : move16();
233 0 : pos = i1;
234 0 : move16();
235 : }
236 : }
237 0 : p1 -= NB_POS_FCB_2T;
238 :
239 0 : IF( pos >= 0 )
240 : {
241 0 : ix = i0;
242 0 : move16();
243 0 : iy = pos;
244 0 : move16();
245 : }
246 : }
247 :
248 0 : i0 = shr( ix, 1 );
249 0 : i1 = shr( iy, 1 );
250 :
251 0 : sign0 = shl( pol[ix], 9 ); // Q9
252 0 : sign1 = shl( pol[iy], 9 ); // Q9
253 :
254 : /*-------------------------------------------------------------------*
255 : * Build the codeword, the filtered codeword and index of codevector.
256 : *-------------------------------------------------------------------*/
257 :
258 0 : set16_fx( code, 0, L_SUBFR );
259 :
260 0 : code[ix] = sign0;
261 0 : move16();
262 0 : code[iy] = sign1;
263 0 : move16();
264 :
265 0 : index = add( shl( i0, 6 ), i1 );
266 :
267 :
268 0 : if ( sign0 < 0 )
269 : {
270 0 : index = add( index, 0x800 );
271 : }
272 0 : if ( sign1 < 0 )
273 : {
274 0 : index = add( index, 0x20 ); /* move16();*/
275 : }
276 :
277 0 : set16_fx( y, 0, L_SUBFR );
278 : /* y_Q9 = sign_Q9<<3 * h_Q12 */
279 :
280 0 : sign0 = shl( sign0, 3 );
281 0 : sign1 = shl( sign1, 3 );
282 :
283 0 : FOR( i = ix; i < L_SUBFR; i++ )
284 : {
285 0 : y[i] = mult_r( sign0, h[i - ix] ); // Q9
286 0 : move16();
287 : }
288 0 : FOR( i = iy; i < L_SUBFR; i++ )
289 : {
290 0 : y[i] = round_fx( L_mac( L_deposit_h( y[i] ), sign1, h[i - iy] ) ); // Q9
291 0 : move16();
292 : }
293 : {
294 : /* write index to array of indices */
295 0 : push_indice( hBstr, IND_ALG_CDBK_2T32, index, 12 );
296 : }
297 0 : return;
298 : }
299 :
300 15103 : void acelp_2t32_ivas_fx(
301 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
302 : const Word16 dn[], /* i : corr. between target and h[]. Qx*/
303 : const Word16 h[], /* i : impulse response of weighted synthesis filter Q12*/
304 : Word16 code[], /* o : algebraic (fixed) codebook excitation Q9 */
305 : Word16 y[] /* o : filtered fixed codebook excitation Q9 */
306 : )
307 : {
308 : Word16 i, j, k, i0, i1, ix, iy, pos, pos2, sign0, sign1, index;
309 : Word16 ps1, ps2, alpk, alp1, alp2;
310 : Word16 sq, psk;
311 : Word16 pol[L_SUBFR], dn_p[L_SUBFR];
312 : Word16 ii, jj;
313 : Word16 *p0, *p1, *p2;
314 : const Word16 *ptr_h1, *ptr_h2, *ptr_hf;
315 :
316 : Word32 s, L_cor;
317 : Word32 L_tmp;
318 : Word16 rrixix[NB_TRACK_FCB_2T][NB_POS_FCB_2T];
319 : Word16 rrixiy[MSIZE];
320 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
321 15103 : Flag Overflow = 0;
322 15103 : move32();
323 : #endif
324 : /*----------------------------------------------------------------*
325 : * Compute rrixix[][] needed for the codebook search.
326 : *----------------------------------------------------------------*/
327 :
328 : /* Init pointers to last position of rrixix[] */
329 15103 : p0 = &rrixix[0][NB_POS_FCB_2T - 1];
330 15103 : p1 = &rrixix[1][NB_POS_FCB_2T - 1];
331 :
332 15103 : ptr_h1 = h;
333 15103 : move16();
334 15103 : L_cor = L_deposit_h( 1 );
335 498399 : FOR( i = 0; i < NB_POS_FCB_2T; i++ )
336 : {
337 483296 : L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow );
338 483296 : ptr_h1++;
339 483296 : *p1-- = extract_h( L_cor );
340 483296 : move16(); /*Q9 Q7*/
341 483296 : L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow );
342 483296 : ptr_h1++;
343 483296 : *p0-- = extract_h( L_cor );
344 483296 : move16(); /*Q9 Q7*/
345 : }
346 :
347 15103 : p0 = rrixix[0];
348 15103 : p1 = rrixix[1];
349 :
350 498399 : FOR( i = 0; i < NB_POS_FCB_2T; i++ )
351 : {
352 483296 : *p0 = shr( *p0, 1 );
353 483296 : move16();
354 483296 : p0++;
355 483296 : *p1 = shr( *p1, 1 );
356 483296 : move16();
357 483296 : p1++;
358 : }
359 :
360 : /*------------------------------------------------------------*
361 : * Compute rrixiy[][] needed for the codebook search.
362 : *------------------------------------------------------------*/
363 :
364 15103 : pos = MSIZE - 1;
365 15103 : move16();
366 15103 : pos2 = MSIZE - 2;
367 15103 : move16();
368 15103 : ptr_hf = h + 1;
369 :
370 498399 : FOR( k = 0; k < NB_POS_FCB_2T; k++ )
371 : {
372 : /* Init pointers to last position of diagonals */
373 483296 : p1 = &rrixiy[pos];
374 483296 : p0 = &rrixiy[pos2];
375 :
376 483296 : ptr_h1 = h;
377 483296 : ptr_h2 = ptr_hf;
378 :
379 483296 : L_cor = L_mult( *ptr_h1++, *ptr_h2++ ); // Q25
380 7974384 : FOR( i = k; i < NB_POS_FCB_2T - 1; i++ )
381 : {
382 7491088 : *p1 = round_fx_o( L_cor, &Overflow ); // Q9
383 7491088 : L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow );
384 7491088 : *p0 = round_fx_o( L_cor, &Overflow ); // Q9
385 7491088 : L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow );
386 7491088 : move16();
387 7491088 : move16();
388 7491088 : p1 -= ( NB_POS_FCB_2T + 1 );
389 7491088 : p0 -= ( NB_POS_FCB_2T + 1 );
390 : }
391 :
392 483296 : *p1 = round_fx_o( L_cor, &Overflow );
393 483296 : pos -= NB_POS_FCB_2T;
394 483296 : move16();
395 483296 : pos2 = sub( pos2, 1 );
396 483296 : ptr_hf += STEP;
397 483296 : move16();
398 : }
399 :
400 : /*----------------------------------------------------------------*
401 : * computing reference vector and pre-selection of polarities
402 : *----------------------------------------------------------------*/
403 :
404 15103 : L_tmp = L_deposit_h( dn[0] );
405 981695 : FOR( i = 0; i < L_SUBFR; i++ )
406 : {
407 : /* FIR high-pass filtering */
408 966592 : IF( i == 0 )
409 : {
410 15103 : L_tmp = L_msu( L_tmp, dn[1], 11469 /*.3f Q15*/ );
411 : }
412 951489 : ELSE IF( EQ_16( i, L_SUBFR - 1 ) )
413 : {
414 15103 : L_tmp = L_deposit_h( dn[i] );
415 15103 : L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ );
416 : }
417 : ELSE
418 : {
419 936386 : L_tmp = L_deposit_h( dn[i] );
420 936386 : L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ );
421 936386 : L_tmp = L_msu( L_tmp, dn[i + 1], 11469 /*.3f Q15*/ );
422 : }
423 :
424 : /* pre-selection of polarities */
425 966592 : IF( L_tmp >= 0 )
426 : {
427 458402 : pol[i] = 1;
428 458402 : move16();
429 458402 : dn_p[i] = dn[i];
430 458402 : move16();
431 : }
432 : ELSE
433 : {
434 508190 : pol[i] = -1;
435 508190 : move16();
436 508190 : dn_p[i] = negate( dn[i] );
437 508190 : move16();
438 : }
439 : }
440 :
441 : /*----------------------------------------------------------------*
442 : * compute denominator ( multiplied by polarity )
443 : *----------------------------------------------------------------*/
444 :
445 15103 : k = 0;
446 15103 : ii = 0;
447 15103 : move16();
448 15103 : move16();
449 498399 : FOR( i = 0; i < NB_POS_FCB_2T; i++ )
450 : {
451 483296 : jj = 1;
452 483296 : move16();
453 15948768 : FOR( j = 0; j < NB_POS_FCB_2T; j++ )
454 : {
455 15465472 : test();
456 15465472 : if ( EQ_16( s_and( pol[ii], pol[jj] ), 1 ) && EQ_16( s_or( pol[ii], pol[jj] ), -1 ) )
457 : {
458 6095096 : rrixiy[k + j] = negate( rrixiy[k + j] );
459 6095096 : move16();
460 : }
461 15465472 : jj = add( jj, 2 );
462 : }
463 483296 : ii = add( ii, 2 );
464 483296 : k = add( k, NB_POS_FCB_2T );
465 : }
466 :
467 : /*----------------------------------------------------------------*
468 : * search 2 pulses
469 : * All combinaisons are tested:
470 : * 32 pos x 32 pos x 2 signs = 2048 tests
471 : *----------------------------------------------------------------*/
472 :
473 15103 : p0 = rrixix[0];
474 15103 : p1 = rrixix[1];
475 15103 : p2 = rrixiy;
476 15103 : psk = -1;
477 15103 : move16();
478 15103 : alpk = 1;
479 15103 : move16();
480 15103 : ix = 0;
481 15103 : move16();
482 15103 : iy = 1;
483 15103 : move16();
484 :
485 498399 : FOR( i0 = 0; i0 < L_SUBFR; i0 += STEP )
486 : {
487 483296 : ps1 = dn_p[i0];
488 483296 : move16();
489 483296 : alp1 = *p0++;
490 483296 : move16();
491 483296 : pos = -1;
492 483296 : move16();
493 15948768 : FOR( i1 = 1; i1 < L_SUBFR; i1 += STEP )
494 : {
495 15465472 : ps2 = add( ps1, dn_p[i1] );
496 15465472 : alp2 = add_o( alp1, add_o( *p1++, *p2++, &Overflow ), &Overflow );
497 15465472 : sq = mult( ps2, ps2 );
498 15465472 : s = L_msu_o( L_mult( alpk, sq ), psk, alp2, &Overflow );
499 15465472 : IF( s > 0 )
500 : {
501 188811 : psk = sq;
502 188811 : move16();
503 188811 : alpk = alp2;
504 188811 : move16();
505 188811 : pos = i1;
506 188811 : move16();
507 : }
508 : }
509 483296 : p1 -= NB_POS_FCB_2T;
510 :
511 483296 : IF( pos >= 0 )
512 : {
513 76755 : ix = i0;
514 76755 : move16();
515 76755 : iy = pos;
516 76755 : move16();
517 : }
518 : }
519 :
520 15103 : i0 = shr( ix, 1 );
521 15103 : i1 = shr( iy, 1 );
522 :
523 15103 : sign0 = shl( pol[ix], 9 ); // Q9
524 15103 : sign1 = shl( pol[iy], 9 ); // Q9
525 :
526 : /*-------------------------------------------------------------------*
527 : * Build the codeword, the filtered codeword and index of codevector.
528 : *-------------------------------------------------------------------*/
529 :
530 15103 : set16_fx( code, 0, L_SUBFR );
531 :
532 15103 : code[ix] = sign0;
533 15103 : move16();
534 15103 : code[iy] = sign1;
535 15103 : move16();
536 :
537 15103 : index = add( shl( i0, 6 ), i1 );
538 :
539 :
540 15103 : if ( sign0 < 0 )
541 : {
542 7573 : index = add( index, 0x800 );
543 : }
544 15103 : if ( sign1 < 0 )
545 : {
546 7774 : index = add( index, 0x20 ); /* move16();*/
547 : }
548 :
549 15103 : set16_fx( y, 0, L_SUBFR );
550 : /* y_Q9 = sign_Q9<<3 * h_Q12 */
551 :
552 15103 : sign0 = shl( sign0, 3 );
553 15103 : sign1 = shl( sign1, 3 );
554 :
555 487823 : FOR( i = ix; i < L_SUBFR; i++ )
556 : {
557 472720 : y[i] = mult_r( sign0, h[i - ix] ); // Q9
558 472720 : move16();
559 : }
560 414646 : FOR( i = iy; i < L_SUBFR; i++ )
561 : {
562 399543 : y[i] = round_fx( L_mac( L_deposit_h( y[i] ), sign1, h[i - iy] ) ); // Q9
563 399543 : move16();
564 : }
565 : {
566 : /* write index to array of indices */
567 15103 : push_indice( hBstr, IND_ALG_CDBK_2T32, index, 12 );
568 : }
569 15103 : return;
570 : }
571 : /*----------------------------------------------------------------------------------
572 : * Function acelp_1t64()
573 : *
574 : * 7 bits algebraic codebook.
575 : * 1 track x 64 positions per track = 64 samples.
576 : *
577 : * The pulse can have 64 possible positions and two (2) possible amplitudes: +1 or -1.
578 : *----------------------------------------------------------------------------------*/
579 :
580 0 : void acelp_1t64_fx(
581 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
582 : const Word16 dn[], /* i : corr. between target and h[]. Qx*/
583 : const Word16 h[], /* i : impulse response of weighted synthesis filter Q12 */
584 : Word16 code[], /* o : algebraic (fixed) codebook excitation Q9 */
585 : Word16 y[], /* o : filtered fixed codebook excitation Q9 */
586 : const Word16 L_subfr /* i : subframe length */
587 : )
588 : {
589 : Word16 i, pos, sgn, index;
590 : Word32 L_tmp;
591 : /*-------------------------------------------------------------------*
592 : * Find position and sign of maximum impulse.
593 : *-------------------------------------------------------------------*/
594 0 : pos = emaximum_fx( 0, dn, L_subfr, &L_tmp );
595 :
596 0 : IF( dn[pos] < 0 )
597 : {
598 0 : sgn = -512; //-1 in Q9
599 0 : move16();
600 : }
601 : ELSE
602 : {
603 0 : sgn = 512; // 1 in Q9
604 0 : move16();
605 : }
606 :
607 : /*-------------------------------------------------------------------*
608 : * Build the codeword, the filtered codeword and index of codevector.
609 : *-------------------------------------------------------------------*/
610 :
611 0 : set16_fx( code, 0, L_subfr );
612 0 : code[pos] = sgn;
613 0 : move16();
614 :
615 0 : set16_fx( y, 0, L_subfr );
616 :
617 0 : FOR( i = pos; i < L_subfr; i++ )
618 : {
619 0 : IF( sgn > 0 )
620 : {
621 0 : y[i] = shr_r( h[i - pos], 3 ); // Q9
622 0 : move16();
623 : }
624 : ELSE
625 : {
626 0 : y[i] = negate( shr_r( h[i - pos], 3 ) ); // Q9
627 0 : move16();
628 : }
629 : }
630 :
631 0 : index = pos;
632 0 : move16();
633 0 : if ( sgn > 0 )
634 : {
635 0 : index = add( index, L_subfr );
636 : }
637 0 : IF( EQ_16( L_subfr, L_SUBFR ) )
638 : {
639 0 : push_indice( hBstr, IND_ALG_CDBK_1T64, index, 7 );
640 : }
641 : ELSE /* L_subfr == 2*L_SUBFR */
642 : {
643 0 : push_indice( hBstr, IND_ALG_CDBK_1T64, index, 8 );
644 : }
645 :
646 0 : return;
647 : }
648 :
649 367 : void acelp_1t64_ivas_fx(
650 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
651 : const Word16 dn[], /* i : corr. between target and h[]. Qx */
652 : const Word16 h[], /* i : impulse response of weighted synthesis filter Q12*/
653 : Word16 code[], /* o : algebraic (fixed) codebook excitation Q9*/
654 : Word16 y[], /* o : filtered fixed codebook excitation Q9*/
655 : const Word16 L_subfr /* i : subframe length */
656 : )
657 : {
658 : Word16 i, pos, sgn, index;
659 : Word32 L_tmp;
660 : /*-------------------------------------------------------------------*
661 : * Find position and sign of maximum impulse.
662 : *-------------------------------------------------------------------*/
663 367 : pos = emaximum_fx( 0, dn, L_subfr, &L_tmp );
664 :
665 367 : IF( dn[pos] < 0 )
666 : {
667 189 : sgn = -512; //-1 in Q9
668 189 : move16();
669 : }
670 : ELSE
671 : {
672 178 : sgn = 512; // 1 in Q9
673 178 : move16();
674 : }
675 :
676 : /*-------------------------------------------------------------------*
677 : * Build the codeword, the filtered codeword and index of codevector.
678 : *-------------------------------------------------------------------*/
679 :
680 367 : set16_fx( code, 0, L_subfr );
681 367 : code[pos] = sgn;
682 367 : move16();
683 :
684 367 : set16_fx( y, 0, L_subfr );
685 :
686 15896 : FOR( i = pos; i < L_subfr; i++ )
687 : {
688 15529 : IF( sgn > 0 )
689 : {
690 7621 : y[i] = shr_r( h[i - pos], 3 ); // Q9
691 7621 : move16();
692 : }
693 : ELSE
694 : {
695 7908 : y[i] = negate( shr_r( h[i - pos], 3 ) ); // Q9
696 7908 : move16();
697 : }
698 : }
699 :
700 367 : index = pos;
701 367 : move16();
702 367 : if ( sgn > 0 )
703 : {
704 178 : index = add( index, L_subfr );
705 : }
706 367 : IF( EQ_16( L_subfr, L_SUBFR ) )
707 : {
708 367 : push_indice( hBstr, IND_ALG_CDBK_1T64, index, 7 );
709 : }
710 : ELSE /* L_subfr == 2*L_SUBFR */
711 : {
712 0 : push_indice( hBstr, IND_ALG_CDBK_1T64, index, 8 );
713 : }
714 :
715 367 : return;
716 : }
|