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 15118 : 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 : #ifndef ISSUE_1867_replace_overflow_libenc
51 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
52 : Flag Overflow = 0;
53 : move32();
54 : #endif
55 : #endif
56 : /*----------------------------------------------------------------*
57 : * Compute rrixix[][] needed for the codebook search.
58 : *----------------------------------------------------------------*/
59 :
60 : /* Init pointers to last position of rrixix[] */
61 15118 : p0 = &rrixix[0][NB_POS_FCB_2T - 1];
62 15118 : p1 = &rrixix[1][NB_POS_FCB_2T - 1];
63 :
64 15118 : ptr_h1 = h;
65 15118 : L_cor = L_deposit_h( 1 );
66 498894 : FOR( i = 0; i < NB_POS_FCB_2T; i++ )
67 : {
68 : #ifdef ISSUE_1867_replace_overflow_libenc
69 483776 : L_cor = L_mac_sat( L_cor, *ptr_h1, *ptr_h1 );
70 : #else
71 : L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow );
72 : #endif
73 483776 : ptr_h1++;
74 483776 : *p1-- = extract_h( L_cor );
75 483776 : move16(); /*Q9 Q7*/
76 : #ifdef ISSUE_1867_replace_overflow_libenc
77 483776 : L_cor = L_mac_sat( L_cor, *ptr_h1, *ptr_h1 );
78 : #else
79 : L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow );
80 : #endif
81 483776 : ptr_h1++;
82 483776 : *p0-- = extract_h( L_cor );
83 483776 : move16(); /*Q9 Q7*/
84 : }
85 :
86 15118 : p0 = rrixix[0];
87 15118 : p1 = rrixix[1];
88 :
89 498894 : FOR( i = 0; i < NB_POS_FCB_2T; i++ )
90 : {
91 483776 : *p0 = shr( *p0, 1 );
92 483776 : move16();
93 483776 : p0++;
94 483776 : *p1 = shr( *p1, 1 );
95 483776 : move16();
96 483776 : p1++;
97 : }
98 :
99 : /*------------------------------------------------------------*
100 : * Compute rrixiy[][] needed for the codebook search.
101 : *------------------------------------------------------------*/
102 :
103 15118 : pos = MSIZE - 1;
104 15118 : move16();
105 15118 : pos2 = MSIZE - 2;
106 15118 : move16();
107 15118 : ptr_hf = h + 1;
108 :
109 498894 : FOR( k = 0; k < NB_POS_FCB_2T; k++ )
110 : {
111 : /* Init pointers to last position of diagonals */
112 483776 : p1 = &rrixiy[pos];
113 483776 : p0 = &rrixiy[pos2];
114 :
115 483776 : ptr_h1 = h;
116 483776 : ptr_h2 = ptr_hf;
117 :
118 483776 : L_cor = L_mult( *ptr_h1++, *ptr_h2++ ); // Q(12+12+1)
119 7982304 : FOR( i = k; i < NB_POS_FCB_2T - 1; i++ )
120 : {
121 : #ifdef ISSUE_1867_replace_overflow_libenc
122 7498528 : *p1 = round_fx_sat( L_cor ); // Q(25-16)
123 7498528 : L_cor = L_mac_sat( L_cor, *ptr_h1++, *ptr_h2++ );
124 7498528 : *p0 = round_fx_sat( L_cor ); // Q(9)
125 7498528 : L_cor = L_mac_sat( L_cor, *ptr_h1++, *ptr_h2++ );
126 : #else
127 : *p1 = round_fx_o( L_cor, &Overflow ); // Q(25-16)
128 : L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow );
129 : *p0 = round_fx_o( L_cor, &Overflow ); // Q(9)
130 : L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow );
131 : #endif
132 7498528 : move16();
133 7498528 : move16();
134 7498528 : p1 -= ( NB_POS_FCB_2T + 1 );
135 7498528 : p0 -= ( NB_POS_FCB_2T + 1 );
136 : }
137 :
138 : #ifdef ISSUE_1867_replace_overflow_libenc
139 483776 : *p1 = round_fx_sat( L_cor ); // Q9
140 : #else
141 : *p1 = round_fx_o( L_cor, &Overflow ); // Q9
142 : #endif
143 483776 : pos -= NB_POS_FCB_2T;
144 483776 : move16();
145 483776 : pos2--;
146 483776 : ptr_hf += STEP;
147 : }
148 :
149 : /*----------------------------------------------------------------*
150 : * computing reference vector and pre-selection of polarities
151 : *----------------------------------------------------------------*/
152 :
153 15118 : L_tmp = L_deposit_h( dn[0] );
154 982670 : FOR( i = 0; i < L_SUBFR; i++ )
155 : {
156 : /* FIR high-pass filtering */
157 967552 : IF( i == 0 )
158 : {
159 15118 : L_tmp = L_msu( L_tmp, dn[1], 11469 /*.3f Q15*/ );
160 : }
161 952434 : ELSE IF( EQ_16( i, L_SUBFR - 1 ) )
162 : {
163 15118 : L_tmp = L_deposit_h( dn[i] );
164 15118 : L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ );
165 : }
166 : ELSE
167 : {
168 937316 : L_tmp = L_deposit_h( dn[i] );
169 937316 : L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ );
170 937316 : L_tmp = L_msu( L_tmp, dn[i + 1], 11469 /*.3f Q15*/ );
171 : }
172 :
173 : /* pre-selection of polarities */
174 967552 : IF( L_tmp >= 0 )
175 : {
176 462385 : pol[i] = 1;
177 462385 : move16();
178 462385 : dn_p[i] = dn[i];
179 462385 : move16();
180 : }
181 : ELSE
182 : {
183 505167 : pol[i] = -1;
184 505167 : move16();
185 505167 : dn_p[i] = negate( dn[i] );
186 505167 : move16();
187 : }
188 : }
189 :
190 : /*----------------------------------------------------------------*
191 : * compute denominator ( multiplied by polarity )
192 : *----------------------------------------------------------------*/
193 :
194 15118 : k = 0;
195 15118 : ii = 0;
196 15118 : move16();
197 15118 : move16();
198 498894 : FOR( i = 0; i < NB_POS_FCB_2T; i++ )
199 : {
200 483776 : jj = 1;
201 483776 : move16();
202 15964608 : FOR( j = 0; j < NB_POS_FCB_2T; j++ )
203 : {
204 15480832 : test();
205 15480832 : if ( EQ_16( s_and( pol[ii], pol[jj] ), 1 ) && EQ_16( s_or( pol[ii], pol[jj] ), -1 ) )
206 : {
207 6149964 : rrixiy[k + j] = negate( rrixiy[k + j] );
208 6149964 : move16();
209 : }
210 15480832 : jj = add( jj, 2 );
211 : }
212 483776 : ii = add( ii, 2 );
213 483776 : k = add( k, NB_POS_FCB_2T );
214 : }
215 :
216 : /*----------------------------------------------------------------*
217 : * search 2 pulses
218 : * All combinaisons are tested:
219 : * 32 pos x 32 pos x 2 signs = 2048 tests
220 : *----------------------------------------------------------------*/
221 :
222 15118 : p0 = rrixix[0];
223 15118 : p1 = rrixix[1];
224 15118 : p2 = rrixiy;
225 15118 : psk = -1;
226 15118 : move16();
227 15118 : alpk = 1;
228 15118 : move16();
229 15118 : ix = 0;
230 15118 : move16();
231 15118 : iy = 1;
232 15118 : move16();
233 :
234 498894 : FOR( i0 = 0; i0 < L_SUBFR; i0 += STEP )
235 : {
236 483776 : ps1 = dn_p[i0];
237 483776 : move16();
238 483776 : alp1 = *p0++;
239 483776 : move16();
240 483776 : pos = -1;
241 483776 : move16();
242 15964608 : FOR( i1 = 1; i1 < L_SUBFR; i1 += STEP )
243 : {
244 15480832 : ps2 = add( ps1, dn_p[i1] );
245 : #ifdef ISSUE_1867_replace_overflow_libenc
246 15480832 : alp2 = add_sat( alp1, add_sat( *p1++, *p2++ ) );
247 15480832 : sq = mult( ps2, ps2 );
248 15480832 : s = L_msu_sat( L_mult( alpk, sq ), psk, alp2 );
249 : #else
250 : alp2 = add_o( alp1, add_o( *p1++, *p2++, &Overflow ), &Overflow );
251 : sq = mult( ps2, ps2 );
252 : s = L_msu_o( L_mult( alpk, sq ), psk, alp2, &Overflow );
253 : #endif
254 15480832 : IF( s > 0 )
255 : {
256 186802 : psk = sq;
257 186802 : move16();
258 186802 : alpk = alp2;
259 186802 : move16();
260 186802 : pos = i1;
261 186802 : move16();
262 : }
263 : }
264 483776 : p1 -= NB_POS_FCB_2T;
265 :
266 483776 : IF( pos >= 0 )
267 : {
268 76471 : ix = i0;
269 76471 : move16();
270 76471 : iy = pos;
271 76471 : move16();
272 : }
273 : }
274 :
275 15118 : i0 = shr( ix, 1 );
276 15118 : i1 = shr( iy, 1 );
277 :
278 15118 : sign0 = shl( pol[ix], 9 ); // Q9
279 15118 : sign1 = shl( pol[iy], 9 ); // Q9
280 :
281 : /*-------------------------------------------------------------------*
282 : * Build the codeword, the filtered codeword and index of codevector.
283 : *-------------------------------------------------------------------*/
284 :
285 15118 : set16_fx( code, 0, L_SUBFR );
286 :
287 15118 : code[ix] = sign0;
288 15118 : move16();
289 15118 : code[iy] = sign1;
290 15118 : move16();
291 :
292 15118 : index = add( shl( i0, 6 ), i1 );
293 :
294 :
295 15118 : if ( sign0 < 0 )
296 : {
297 7592 : index = add( index, 0x800 );
298 : }
299 15118 : if ( sign1 < 0 )
300 : {
301 7629 : index = add( index, 0x20 ); /* move16();*/
302 : }
303 :
304 15118 : set16_fx( y, 0, L_SUBFR );
305 : /* y_Q9 = sign_Q9<<3 * h_Q12 */
306 :
307 15118 : sign0 = shl( sign0, 3 );
308 15118 : sign1 = shl( sign1, 3 );
309 :
310 491018 : FOR( i = ix; i < L_SUBFR; i++ )
311 : {
312 475900 : y[i] = mult_r( sign0, h[i - ix] ); // Q9
313 475900 : move16();
314 : }
315 428814 : FOR( i = iy; i < L_SUBFR; i++ )
316 : {
317 413696 : y[i] = round_fx( L_mac( L_deposit_h( y[i] ), sign1, h[i - iy] ) ); // Q9
318 413696 : move16();
319 : }
320 : {
321 : /* write index to array of indices */
322 15118 : push_indice( hBstr, IND_ALG_CDBK_2T32, index, 12 );
323 : }
324 15118 : return;
325 : }
326 : /*----------------------------------------------------------------------------------
327 : * Function acelp_1t64()
328 : *
329 : * 7 bits algebraic codebook.
330 : * 1 track x 64 positions per track = 64 samples.
331 : *
332 : * The pulse can have 64 possible positions and two (2) possible amplitudes: +1 or -1.
333 : *----------------------------------------------------------------------------------*/
334 :
335 367 : void acelp_1t64_fx(
336 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
337 : const Word16 dn[], /* i : corr. between target and h[]. Qx*/
338 : const Word16 h[], /* i : impulse response of weighted synthesis filter Q12 */
339 : Word16 code[], /* o : algebraic (fixed) codebook excitation Q9 */
340 : Word16 y[], /* o : filtered fixed codebook excitation Q9 */
341 : const Word16 L_subfr /* i : subframe length */
342 : )
343 : {
344 : Word16 i, pos, sgn, index;
345 : Word32 L_tmp;
346 : /*-------------------------------------------------------------------*
347 : * Find position and sign of maximum impulse.
348 : *-------------------------------------------------------------------*/
349 367 : pos = emaximum_fx( 0, dn, L_subfr, &L_tmp );
350 :
351 367 : IF( dn[pos] < 0 )
352 : {
353 191 : sgn = -512; //-1 in Q9
354 191 : move16();
355 : }
356 : ELSE
357 : {
358 176 : sgn = 512; // 1 in Q9
359 176 : move16();
360 : }
361 :
362 : /*-------------------------------------------------------------------*
363 : * Build the codeword, the filtered codeword and index of codevector.
364 : *-------------------------------------------------------------------*/
365 :
366 367 : set16_fx( code, 0, L_subfr );
367 367 : code[pos] = sgn;
368 367 : move16();
369 :
370 367 : set16_fx( y, 0, L_subfr );
371 :
372 16071 : FOR( i = pos; i < L_subfr; i++ )
373 : {
374 15704 : IF( sgn > 0 )
375 : {
376 7940 : y[i] = shr_r( h[i - pos], 3 ); // Q9
377 7940 : move16();
378 : }
379 : ELSE
380 : {
381 7764 : y[i] = negate( shr_r( h[i - pos], 3 ) ); // Q9
382 7764 : move16();
383 : }
384 : }
385 :
386 367 : index = pos;
387 367 : move16();
388 367 : if ( sgn > 0 )
389 : {
390 176 : index = add( index, L_subfr );
391 : }
392 367 : IF( EQ_16( L_subfr, L_SUBFR ) )
393 : {
394 367 : push_indice( hBstr, IND_ALG_CDBK_1T64, index, 7 );
395 : }
396 : ELSE /* L_subfr == 2*L_SUBFR */
397 : {
398 0 : push_indice( hBstr, IND_ALG_CDBK_1T64, index, 8 );
399 : }
400 :
401 367 : return;
402 : }
|