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