Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <assert.h>
6 : #include <stdint.h>
7 : #include "options.h"
8 : #include "cnst.h"
9 : //#include "prot_fx.h"
10 : #include "rom_com_fx.h"
11 : #include "rom_com.h"
12 : #include "rom_enc.h"
13 : #include "basop_util.h"
14 : #include "prot_fx.h" /* Function prototypes */
15 : #include "prot_fx_enc.h" /* Function prototypes */
16 :
17 : void E_GAIN_norm_corr_fx( Word16 exc[] /*Q_new*/, Word16 xn[] /*(Q_new+shift-1)*/, Word16 h[] /*(Q14+shift)*/, Word16 t_min, Word16 t_max, Word16 corr_norm[] /*(Q15+(Q_new+shift-1)+scale)*/, Word16 L_subfr );
18 :
19 : /*
20 : * E_GAIN_norm_corr
21 : *
22 : * Parameters:
23 : * exc I: excitation buffer (Q_new)
24 : * xn I: target signal (Q_new+shift-1)
25 : * h I: weighted synthesis filter impulse response (Q14+shift)
26 : * t0_min I: minimum value in the searched range
27 : * t0_max I: maximum value in the searched range
28 : * corr_norm O: normalized correlation (Q15+(Q_new+shift-1)+scale)
29 : *
30 : * Function:
31 : * Find the normalized correlation between the target vector and the
32 : * filtered past excitation (correlation between target and filtered
33 : * excitation divided by the square root of energy of filtered excitation)
34 : * Size of subframe = L_SUBFR.
35 : *
36 : * Returns:
37 : * void
38 : */
39 3020 : void E_GAIN_norm_corr_fx( Word16 exc[] /*Q_new*/, Word16 xn[] /*(Q_new+shift-1)*/, Word16 h[] /*(Q14+shift)*/, Word16 t_min, Word16 t_max, Word16 corr_norm[] /*(Q15+(Q_new+shift-1)+scale)*/, Word16 L_subfr )
40 : {
41 : Word16 excf[L_SUBFR]; /* filtered past excitation (Q_new+shift-1) */
42 : Word16 ps, norm, exp_alp, exp_ps, scale, L_subfr2;
43 : Word16 t, j, k;
44 : Word32 L_tmp, L_tmp2;
45 :
46 :
47 3020 : k = negate( t_min );
48 3020 : L_subfr2 = shr( L_subfr, 1 );
49 :
50 : /* compute the filtered excitation for the first delay t_min */
51 3020 : E_UTIL_f_convolve( &exc[k], h, excf, L_subfr );
52 :
53 : /* Compute rounded down 1/sqrt(energy of xn[]) */
54 3020 : Dot_product12_offs( xn, xn, L_subfr, &scale, 1 );
55 :
56 3020 : scale = add( scale, 2 + 1 ); /* energy of xn[] x 2 + rounded up */
57 3020 : move16();
58 3020 : scale = negate( shr( scale, 1 ) ); /* (1<<scale) < 1/sqrt(energy rounded) */
59 :
60 : /* loop for every possible period */
61 81824 : FOR( t = t_min; t < t_max; t++ )
62 : {
63 : /* Compute correlation between xn[] and excf[] */
64 :
65 : /*for (j = 0; j < L_subfr; j++)
66 : {
67 : ps += xn[j] * excf[j]; MAC(1);
68 : alp += excf[j] * excf[j]; MAC(1);
69 : }*/
70 78804 : L_tmp = Dot_product12_offs( xn, excf, L_subfr, &exp_ps, 1 ); /*Q31 + 2x(Q_new+shift-1) - exp_ps*/
71 78804 : ps = extract_h( L_tmp ); /* Scaling of ps = 15 + 2x(Q_new+shift-1) - exp_ps */
72 :
73 :
74 : /* Compute 1/sqrt(energy of excf[]) */
75 78804 : L_tmp = Dot_product12_offs( excf, excf, L_subfr2, NULL, 1 );
76 78804 : L_tmp2 = Dot_product12_offs( excf + L_subfr2, excf + L_subfr2, L_subfr2, NULL, 1 );
77 78804 : exp_alp = sub( s_min( norm_l( L_tmp ), norm_l( L_tmp2 ) ), 1 );
78 78804 : L_tmp = L_add( L_shl( L_tmp, exp_alp ), L_shl( L_tmp2, exp_alp ) );
79 78804 : exp_alp = sub( 31 + 1, exp_alp );
80 :
81 : /*norm = (Float32)(1.0F / sqrt(alp)); SQRT(1);*/
82 78804 : L_tmp = ISqrt32( L_tmp, &exp_alp ); /*Q31 - (Q_new+shift-1) - exp_alp*/
83 78804 : norm = extract_h( L_tmp ); /* Scaling of norm = 15 - (Q_new+shift-1) - exp_alp */
84 :
85 : /* Normalize correlation = correlation * (1/sqrt(energy)) */
86 : /*corr_norm[t-t_min] = ps * norm; MULT(1); STORE(1);*/
87 78804 : L_tmp = L_mult( ps, norm ); /*Q31 + (Q_new+shift-1) - (exp_ps + exp_alp)*/
88 78804 : L_tmp = L_shl( L_tmp, add( add( exp_ps, exp_alp ), scale ) );
89 :
90 78804 : corr_norm[t - t_min] = round_fx( L_tmp ); /* Scaling of corr_norm = 15 + (Q_new+shift-1) + scale */
91 :
92 : /* update the filtered excitation excf[] for the next iteration */
93 78804 : k = sub( k, 1 );
94 :
95 5043456 : FOR( j = L_subfr - 1; j > 0; j-- )
96 : {
97 : /*excf[j] = excf[j - 1] + exc[k] * h[j]; MAC(1); STORE(1);*/
98 : /* saturation can occur in add() */
99 4964652 : excf[j] = add( mult_r( exc[k], h[j] ), excf[j - 1] ); /*Q_new + (Q14+shift) - 15*/
100 4964652 : move16();
101 : }
102 78804 : excf[0] = mult_r( exc[k], h[0] ); /*Q_new + (Q14+shift) - 15*/
103 78804 : move16();
104 : }
105 : /* Last reduced iteration for t=t_max */
106 3020 : L_tmp = Dot_product12_offs( xn, excf, L_subfr, &exp_ps, 1 ); /*Q31 + 2x(Q_new+shift-1) - exp_ps*/
107 3020 : ps = extract_h( L_tmp ); /*Q15 + 2x(Q_new+shift-1) - exp_ps*/
108 :
109 :
110 : /* Compute 1/sqrt(energy of excf[]) */
111 3020 : L_tmp = Dot_product12_offs( excf, excf, L_subfr2, NULL, 1 );
112 3020 : L_tmp2 = Dot_product12_offs( excf + L_subfr2, excf + L_subfr2, L_subfr2, NULL, 1 );
113 3020 : exp_alp = sub( s_min( norm_l( L_tmp ), norm_l( L_tmp2 ) ), 1 );
114 3020 : L_tmp = L_add( L_shl( L_tmp, exp_alp ), L_shl( L_tmp2, exp_alp ) );
115 3020 : exp_alp = sub( 31 + 1, exp_alp );
116 :
117 :
118 : /*norm = (Float32)(1.0F / sqrt(alp)); SQRT(1);*/
119 3020 : L_tmp = ISqrt32( L_tmp, &exp_alp ); /*Q31 - (Q_new+shift-1) - exp_alp*/
120 3020 : norm = extract_h( L_tmp ); /*15 - (Q_new+shift-1) - exp_alp */
121 :
122 : /* Normalize correlation = correlation * (1/sqrt(energy)) */
123 : /*corr_norm[t-t_min] = ps * norm; MULT(1); STORE(1);*/
124 3020 : L_tmp = L_mult( ps, norm ); /*Q31 + (Q_new+shift-1) - (exp_ps + exp_alp)*/
125 3020 : L_tmp = L_shl( L_tmp, add( add( exp_ps, exp_alp ), scale ) );
126 3020 : corr_norm[t - t_min] = round_fx( L_tmp ); /* 15 + (Q_new+shift-1) + scale */
127 :
128 3020 : return;
129 : }
130 :
131 :
132 : /*
133 : * E_GAIN_norm_corr_interpolate
134 : *
135 : * Parameters:
136 : * x I: input vector
137 : * frac I: fraction (-4..+3)
138 : *
139 : * Function:
140 : * Interpolating the normalized correlation
141 : *
142 : * Returns:
143 : * interpolated value
144 : */
145 0 : static Word16 E_GAIN_norm_corr_interpolate_fx( Word16 *x /*Qx*/, Word16 frac /*Q0*/ )
146 : {
147 : Word16 *x1, *x2, i;
148 : const Word16 *c1, *c2;
149 : Word32 s;
150 :
151 0 : IF( frac < 0 )
152 : {
153 0 : frac = add( frac, 4 ); /*Q0*/
154 0 : x--;
155 : }
156 :
157 0 : x1 = &x[0]; /*Qx*/
158 0 : x2 = &x[1]; /*Qx*/
159 0 : c1 = &E_ROM_inter4_1_fx[frac]; /*Q14*/
160 0 : c2 = &E_ROM_inter4_1_fx[4 - frac]; /*Q14*/
161 :
162 : /*s = x1[0] * c1[0] + x2[0] * c2[0];
163 : s += x1[-1] * c1[4] + x2[1] * c2[4];
164 : s += x1[-2] * c1[8] + x2[2] * c2[8];
165 : s += x1[-3] * c1[12] + x2[3] * c2[12];*/
166 :
167 0 : s = L_deposit_l( 0 );
168 0 : FOR( i = 0; i < 4; i++ )
169 : {
170 0 : s = L_mac( s, *x1--, *c1 ); /* Qx + 15 */
171 0 : s = L_mac( s, *x2++, *c2 ); /* Qx + 15 */
172 0 : c1 += 4;
173 0 : c2 += 4;
174 : }
175 :
176 0 : return round_fx( L_shl( s, 1 ) ); /*Qx*/
177 : }
178 :
179 14390 : static Word16 E_GAIN_norm_corr_interpolate6_fx( Word16 *x /*Qx*/, Word16 frac /*Q0*/ )
180 : {
181 : Word16 *x1, *x2, i;
182 : const Word16 *c1, *c2;
183 : Word32 s;
184 :
185 14390 : IF( frac < 0 )
186 : {
187 5770 : frac = add( frac, 6 ); /*Q0*/
188 5770 : x--;
189 : }
190 :
191 14390 : x1 = &x[0]; /*Qx*/
192 14390 : x2 = &x[1]; /*Qx*/
193 14390 : c1 = &E_ROM_inter6_1_fx[frac]; /*Q14*/
194 14390 : c2 = &E_ROM_inter6_1_fx[6 - frac]; /*Q14*/
195 :
196 : /*s = x1[0] * c1[0] + x2[0] * c2[0];
197 : s += x1[-1] * c1[6] + x2[1] * c2[6];
198 : s += x1[-2] * c1[12] + x2[2] * c2[12];
199 : s += x1[-3] * c1[18] + x2[3] * c2[18];*/
200 14390 : s = L_deposit_l( 0 );
201 71950 : FOR( i = 0; i < 4; i++ )
202 : {
203 57560 : s = L_mac( s, *x1--, *c1 ); /* Qx + 15 */
204 57560 : s = L_mac( s, *x2++, *c2 ); /* Qx + 15 */
205 57560 : c1 += 6;
206 57560 : c2 += 6;
207 : }
208 :
209 14390 : return round_fx( L_shl( s, 1 ) ); /*Qx*/
210 : }
211 :
212 : /*
213 : * E_GAIN_closed_loop_search_fx
214 : *
215 : * Parameters:
216 : * exc I: excitation buffer
217 : * xn I: target signal
218 : * h I: weighted synthesis filter impulse response
219 : * dn I: residual domain target signal
220 : * t0_min I: minimum value in the searched range
221 : * t0_max I: maximum value in the searched range
222 : * pit_frac O: chosen fraction
223 : * i_subfr I: flag to first subframe
224 : * t0_fr2 I: minimum value for resolution 1/2
225 : * t0_fr1 I: minimum value for resolution 1
226 : *
227 : * Function:
228 : * Find the closed loop pitch period with 1/4 subsample resolution.
229 : *
230 : * Returns:
231 : * chosen integer pitch lag
232 : */
233 3020 : Word16 E_GAIN_closed_loop_search_fx( Word16 exc[], /*Q_new*/
234 : Word16 xn[], /*Q_xn*/
235 : Word16 h[], /* Q14+shift */
236 : Word16 t0_min, /*Q0*/
237 : Word16 t0_min_frac, /*Q0*/
238 : Word16 t0_max, /*Q0*/
239 : Word16 t0_max_frac, /*Q0*/
240 : Word16 t0_min_max_res, /*Q0*/
241 : Word16 *pit_frac, /*Q0*/
242 : Word16 *pit_res, /*Q0*/
243 : Word16 pit_res_max, /*Q0*/
244 : Word16 i_subfr, /*Q0*/
245 : Word16 pit_min, /*Q0*/
246 : Word16 pit_fr2, /*Q0*/
247 : Word16 pit_fr1, /*Q0*/
248 : Word16 L_subfr /*Q0*/ )
249 : {
250 : Word16 corr_v[32 + 2 * L_INTERPOL1 + 1];
251 : Word16 cor_max, max, temp;
252 : Word16 *corr;
253 : Word16 i, fraction, frac1, frac2, step;
254 : Word16 t0, t_min, t_max;
255 :
256 3020 : set16_fx( corr_v, 0, 32 + 2 * L_INTERPOL1 + 1 );
257 : /* Find interval to compute normalized correlation */
258 3020 : if ( t0_min_frac > 0 )
259 : {
260 2716 : t0_min = add( t0_min, 1 );
261 2716 : move16();
262 : }
263 3020 : t_min = sub( t0_min, L_INTERPOL1 );
264 3020 : t_max = add( t0_max, L_INTERPOL1 );
265 3020 : move16();
266 3020 : move16();
267 :
268 : /* allocate memory to normalized correlation vector */
269 3020 : corr = &corr_v[negate( t_min )]; /* corr[t_min..t_max] */
270 :
271 : /* Compute normalized correlation between target and filtered excitation */
272 3020 : E_GAIN_norm_corr_fx( exc, xn, h, t_min, t_max, corr_v, L_subfr );
273 :
274 : /* find integer pitch */
275 3020 : max = corr[t0_min]; /*(Q15+(Q_new+shift-1)+scale)*/
276 3020 : move16();
277 3020 : t0 = t0_min; /*Q0*/
278 3020 : move16();
279 :
280 57664 : FOR( i = t0_min + 1; i <= t0_max; i++ )
281 : {
282 : BASOP_SATURATE_WARNING_OFF_EVS;
283 54644 : if ( GE_16( corr[i], max ) )
284 : {
285 19923 : t0 = i;
286 19923 : move16();
287 : }
288 54644 : max = s_max( max, corr[i] );
289 : BASOP_SATURATE_WARNING_ON_EVS;
290 : }
291 :
292 :
293 : /* If first subframe and t0 >= pit_fr1, do not search fractionnal pitch */
294 3020 : test();
295 3020 : IF( ( i_subfr == 0 ) && GE_16( t0, pit_fr1 ) )
296 : {
297 117 : *pit_frac = 0;
298 117 : move16();
299 117 : *pit_res = 1;
300 117 : move16();
301 117 : return ( t0 );
302 : }
303 :
304 :
305 : /*
306 : * Search fractionnal pitch
307 : * Test the fractions around t0 and choose the one which maximizes
308 : * the interpolated normalized correlation.
309 : */
310 :
311 2903 : IF( EQ_16( t0_min_max_res, shr( pit_res_max, 1 ) ) )
312 : {
313 2903 : t0_min_frac = shl( t0_min_frac, 1 ); /*Q0*/
314 2903 : t0_max_frac = shl( t0_max_frac, 1 ); /*Q0*/
315 : }
316 :
317 2903 : step = 1;
318 2903 : move16();
319 2903 : frac1 = sub( 1, pit_res_max ); /*Q0*/
320 2903 : frac2 = sub( pit_res_max, 1 ); /*Q0*/
321 :
322 2903 : test();
323 2903 : test();
324 2903 : IF( ( ( i_subfr == 0 ) && GE_16( t0, pit_fr2 ) ) || LE_16( pit_fr2, pit_min ) )
325 : {
326 2903 : step = 2;
327 2903 : move16();
328 2903 : frac1 = sub( 2, pit_res_max ); /*Q0*/
329 2903 : frac2 = sub( pit_res_max, 2 ); /*Q0*/
330 : }
331 2903 : test();
332 2903 : IF( ( EQ_16( t0, t0_min ) ) && ( t0_min_frac == 0 ) )
333 : {
334 8 : frac1 = t0_min_frac; /*Q0*/
335 8 : move16();
336 : }
337 : ELSE
338 : {
339 2895 : test();
340 2895 : IF( ( EQ_16( t0, t0_min ) ) && ( LT_16( add( frac1, pit_res_max ), t0_min_frac ) ) )
341 : {
342 20 : frac1 = sub( t0_min_frac, pit_res_max ); /*Q0*/
343 : }
344 : }
345 :
346 2903 : if ( EQ_16( t0, t0_max ) )
347 : {
348 71 : frac2 = t0_max_frac; /*Q0*/
349 71 : move16();
350 : }
351 2903 : assert( frac1 <= 0 && frac2 >= 0 && frac2 > frac1 );
352 :
353 2903 : IF( EQ_16( pit_res_max, 6 ) )
354 : {
355 2903 : cor_max = E_GAIN_norm_corr_interpolate6_fx( &corr[t0], frac1 ); /*(Q15+(Q_new+shift-1)+scale)*/
356 2903 : fraction = frac1; /*Q0*/
357 2903 : move16();
358 :
359 14390 : FOR( i = ( frac1 + step ); i <= frac2; i += step )
360 : {
361 11487 : temp = E_GAIN_norm_corr_interpolate6_fx( &corr[t0], i ); /*(Q15+(Q_new+shift-1)+scale)*/
362 11487 : IF( GT_16( temp, cor_max ) )
363 : {
364 5787 : cor_max = temp; /*(Q15+(Q_new+shift-1)+scale)*/
365 5787 : move16();
366 5787 : fraction = i;
367 5787 : move16();
368 : }
369 : }
370 : }
371 : ELSE
372 : {
373 0 : cor_max = E_GAIN_norm_corr_interpolate_fx( &corr[t0], frac1 ); /*(Q15+(Q_new+shift-1)+scale)*/
374 0 : fraction = frac1; /*Q0*/
375 0 : move16();
376 :
377 0 : FOR( i = ( frac1 + step ); i <= frac2; i += step )
378 : {
379 0 : temp = E_GAIN_norm_corr_interpolate_fx( &corr[t0], i ); /*(Q15+(Q_new+shift-1)+scale)*/
380 0 : IF( GT_16( temp, cor_max ) )
381 : {
382 0 : cor_max = temp; /*(Q15+(Q_new+shift-1)+scale)*/
383 0 : move16();
384 0 : fraction = i;
385 0 : move16();
386 : }
387 : }
388 : }
389 :
390 : /* limit the fraction value */
391 2903 : IF( fraction < 0 )
392 : {
393 757 : fraction = add( fraction, pit_res_max ); /*Q0*/
394 757 : t0 = sub( t0, 1 );
395 : }
396 2903 : test();
397 2903 : test();
398 2903 : IF( ( ( i_subfr == 0 ) && GE_16( t0, pit_fr2 ) ) || LE_16( pit_fr2, pit_min ) )
399 : {
400 2903 : *pit_res = shr( pit_res_max, 1 ); /*Q0*/
401 2903 : move16();
402 2903 : *pit_frac = shr( fraction, 1 ); /*Q0*/
403 2903 : move16();
404 : }
405 : ELSE
406 : {
407 0 : *pit_res = pit_res_max; /*Q0*/
408 0 : move16();
409 0 : *pit_frac = fraction; /*Q0*/
410 0 : move16();
411 : }
412 2903 : return ( t0 );
413 : }
|