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