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 "prot_fx.h" /* Function prototypes */
8 : #include "prot_fx.h" /* Function prototypes */
9 : #include "prot_fx_enc.h" /* Function prototypes */
10 : #include "basop_util.h"
11 :
12 : #define THR_CORR_FX ( 56 << 15 ) /* 56 in Q15 starting threshold of multi-harm. correlation */
13 : #define THR_CORR_MAX_FX 30720 /* 60 in Q9 upper threshold of multi-harm. correlation */
14 : #define THR_CORR_MIN_FX 25088 /* 49 in Q9 lower threshold of multi-harm. correlation */
15 : #define THR_CORR_STEP_FX 102 /* 0.2 in Q9 step for the threshold of multi-harm. correlation */
16 :
17 : /*---------------------------------------------------------------------*
18 : * multi_harm()
19 : *
20 : * Perform multi-harmonic analysis, information used for UV and VAD decision
21 : *---------------------------------------------------------------------*/
22 :
23 20890 : Word16 multi_harm_fx( /* o : frame multi-harmonicity (1-harmonic, 0-not) */
24 : const Word16 Bin_E[], /* i : log-energy spectrum of the current frame Q7 */
25 : Word16 old_S[], /* i/o: prev. log-energy spectrum w. subtracted floor Q7 */
26 : Word16 cor_map_LT[], /* i/o: LT correlation map Q15 */
27 : Word16 *multi_harm_limit, /* i/o: multi harminic threshold Q9 */
28 : const Word32 total_brate, /* i : total bitrate Q0 */
29 : const Word16 bwidth, /* i : input signal bandwidth Q0 */
30 : Word16 *cor_strong_limit, /* i/o: HF correlation indicator Q0 */
31 : Word16 *st_mean_avr_dyn, /* i/o: long term average dynamic Q7 */
32 : Word16 *st_last_sw_dyn, /* i/o: last dynamic Q7 */
33 : Word16 *cor_map_sum, /* i : sum of correlation map Q8 */
34 : Word16 *sp_floor, /* o: noise floor estimate Q7 */
35 : Word16 S_map[] /* o : short-term correlation map Q7 */
36 : )
37 : {
38 : Word16 i, j, k, L, stemp, N_mins, ind_mins[L_FFT / 4], *pt_mins, harm;
39 : Word16 S[L_FFT / 2], flor, step, sign_fx, tmp16, tmp2, ExpInd, tmpdB, ExpdB, Expx2, Expy2;
40 : Word16 corx2, cory2, corxy, cor, cor_map[L_FFT / 2], *pt1, *pt2, cor_strong;
41 : Word32 L_acc;
42 : Word32 Lcorx2, Lcory2, Lcorxy, Lcor_map_LT_sum;
43 : Word16 mean_dyn;
44 : #ifndef ISSUE_1867_replace_overflow_libenc
45 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
46 : Flag Overflow = 0;
47 : move32();
48 : #endif
49 : #endif
50 :
51 : /*------------------------------------------------------------------*
52 : * initialization
53 : *------------------------------------------------------------------*/
54 :
55 : /* length of the useful part of the spectrum (up to 6.4kHz) */
56 20890 : L = L_FFT / 2;
57 20890 : move16();
58 20890 : if ( ( bwidth == NB ) )
59 : {
60 : /* length of the useful part of the spectrum (up to 3.6kHz) */
61 0 : L = 76;
62 0 : move16();
63 : }
64 :
65 20890 : Copy( Bin_E, S, L );
66 :
67 : /*------------------------------------------------------------------*
68 : * searching of spectral maxima and minima
69 : *------------------------------------------------------------------*/
70 :
71 20890 : pt_mins = ind_mins;
72 :
73 : /* index of the first minimum */
74 20890 : if ( LT_16( Bin_E[0], Bin_E[1] ) )
75 : {
76 10230 : *pt_mins++ = 0;
77 10230 : move16();
78 : }
79 :
80 2653030 : FOR( i = 1; i < L - 1; i++ )
81 : {
82 : /* minimum found */
83 2632140 : test();
84 2632140 : if ( LT_16( Bin_E[i], Bin_E[i - 1] ) && LT_16( Bin_E[i], Bin_E[i + 1] ) )
85 : {
86 717213 : *pt_mins++ = i;
87 717213 : move16();
88 : }
89 : }
90 :
91 : /* index of the last minimum */
92 20890 : IF( LT_16( Bin_E[L - 1], Bin_E[L - 2] ) )
93 : {
94 0 : *pt_mins++ = sub( L, 1 );
95 0 : move16();
96 : }
97 :
98 : /* total number of minimas found */
99 20890 : N_mins = (Word16) ( pt_mins - ind_mins - 1 );
100 20890 : move16();
101 :
102 : /*------------------------------------------------------------------*
103 : * calculation of the spectral floor
104 : * subtraction of the spectral floor
105 : *------------------------------------------------------------------*/
106 :
107 20890 : set16_fx( S, 0, L );
108 :
109 20890 : IF( N_mins > 0 )
110 : {
111 20698 : L_acc = L_deposit_l( 0 );
112 727442 : FOR( i = 0; i < N_mins; ++i )
113 : {
114 706744 : L_acc = L_mac0( L_acc, Bin_E[ind_mins[i]], 1 );
115 : }
116 20698 : *sp_floor = extract_l( Mult_32_16( L_acc, div_s( 1, N_mins ) ) );
117 20698 : move16();
118 :
119 20698 : set16_fx( S, 0, ind_mins[0] );
120 20698 : set16_fx( &S[ind_mins[N_mins]], 0, sub( shr( L_FFT, 1 ), ind_mins[N_mins] ) );
121 :
122 20698 : pt_mins = ind_mins;
123 20698 : flor = 0;
124 20698 : move16();
125 20698 : step = 0;
126 20698 : move16();
127 :
128 2557174 : FOR( i = ind_mins[0]; i < ind_mins[N_mins]; i++ )
129 : {
130 : /* we are at the end of the next minimum */
131 2536476 : IF( EQ_16( i, *pt_mins ) )
132 : {
133 706744 : pt_mins++;
134 706744 : flor = Bin_E[i];
135 706744 : move16(); /*Q7*/
136 : /* calculate the new step */
137 : /*step = (Bin_E[*pt_mins] - Bin_E[i]) / (*pt_mins-i);*/
138 706744 : tmp16 = sub( *pt_mins, i );
139 706744 : tmpdB = sub( Bin_E[*pt_mins], Bin_E[i] );
140 706744 : sign_fx = shr( tmpdB, 15 ); /* 0 if positive else -1 */
141 706744 : ExpdB = sub( norm_s( tmpdB ), 1 );
142 706744 : tmpdB = abs_s( shl( tmpdB, ExpdB ) );
143 706744 : ExpInd = norm_s( tmp16 );
144 706744 : tmp16 = shl( tmp16, ExpInd );
145 706744 : tmp16 = div_s( tmpdB, tmp16 );
146 706744 : tmp16 = sub( s_xor( tmp16, sign_fx ), sign_fx );
147 706744 : step = shr( tmp16, add( sub( ExpdB, ExpInd ), 15 ) ); /* Q7 */
148 : }
149 :
150 : /* subtract the floor */
151 2536476 : S[i] = s_max( sub_sat( Bin_E[i], flor ), 0 );
152 2536476 : move16();
153 :
154 : /* update the floor */
155 2536476 : flor = add( flor, step ); /*Q7*/
156 : }
157 : }
158 :
159 : /* Calculate the maximum dynamic per band */
160 : /* since we are processing 40 bins we will use 1/40 in Q15 to find the mean */
161 : /* mean_dyn = mean(&S[L-40], 40);*/
162 20890 : L_acc = L_deposit_l( 0 );
163 856490 : FOR( i = L - 40; i < L; i++ )
164 : {
165 835600 : L_acc = L_mac( L_acc, S[i], 819 /* 1 / 40 in Q15 */ );
166 : }
167 20890 : mean_dyn = round_fx( L_acc ); /*Q7*/
168 :
169 : /*mean_dyn = 0.6f * *st_mean_avr_dyn + 0.4f * mean_dyn;*/
170 20890 : L_acc = L_mult( 13107 /*0.4f*/, mean_dyn ); /*Q23*/
171 20890 : L_acc = L_mac( L_acc, 19661 /*0.6f*/, *st_mean_avr_dyn ); /*Q23*/
172 20890 : mean_dyn = round_fx( L_acc ); /*Q7*/
173 :
174 20890 : test();
175 20890 : IF( LT_16( mean_dyn, 1229 ) /*9.6f.Q7*/ && *cor_strong_limit != 0 )
176 : {
177 1701 : *cor_strong_limit = 0;
178 1701 : move16();
179 1701 : *st_last_sw_dyn = mean_dyn;
180 1701 : move16();
181 : }
182 19189 : ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f.Q7*/ )
183 : {
184 168 : *cor_strong_limit = 1;
185 168 : move16();
186 : }
187 20890 : test();
188 20890 : if ( LT_32( total_brate, ACELP_9k60 ) || GT_32( total_brate, ACELP_16k40 ) )
189 : {
190 16800 : *cor_strong_limit = 1;
191 16800 : move16();
192 : }
193 :
194 20890 : *st_mean_avr_dyn = mean_dyn;
195 20890 : move16();
196 :
197 : /*------------------------------------------------------------------*
198 : * calculation of the correlation map
199 : *------------------------------------------------------------------*/
200 :
201 20890 : set16_fx( cor_map, 0, L );
202 20890 : IF( N_mins > 0 )
203 : {
204 20698 : Lcorx2 = L_deposit_l( 0 );
205 20698 : Lcorxy = L_deposit_l( 0 );
206 20698 : stemp = ind_mins[0];
207 20698 : move16();
208 20698 : Lcory2 = L_mult( old_S[stemp], old_S[stemp] );
209 20698 : k = 1;
210 20698 : move16();
211 :
212 2557174 : FOR( i = add( stemp, 1 ); i <= ind_mins[N_mins]; i++ )
213 : {
214 2536476 : IF( EQ_16( i, ind_mins[k] ) )
215 : {
216 : /* include the last peak point (new minimum) to the corr. sum */
217 : #ifdef ISSUE_1867_replace_overflow_libenc
218 706744 : Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
219 : #else
220 : Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow );
221 : #endif
222 :
223 : /* calculation of the norm. peak correlation */
224 706744 : test();
225 706744 : IF( Lcorx2 != 0 && Lcory2 != 0 )
226 : {
227 : /* corxy * corxy*/
228 701725 : tmp16 = sub( norm_l( Lcorxy ), 1 );
229 701725 : corxy = extract_h( L_shl( Lcorxy, tmp16 ) );
230 701725 : corxy = mult_r( corxy, corxy );
231 : /* (corx2 * cory2) */
232 701725 : Expx2 = norm_l( Lcorx2 );
233 701725 : Expy2 = norm_l( Lcory2 );
234 701725 : corx2 = extract_h( L_shl( Lcorx2, Expx2 ) );
235 701725 : cory2 = extract_h( L_shl( Lcory2, Expy2 ) );
236 701725 : corx2 = mult_r( corx2, cory2 );
237 701725 : Expx2 = add( Expy2, Expx2 );
238 : /* Validate num < den */
239 701725 : cor = sub( corx2, corxy );
240 701725 : cor = shr( cor, 15 );
241 : /* Add 1 to tmp16 & shr by 2 if corxy > corx2 */
242 701725 : tmp16 = sub( tmp16, cor );
243 701725 : corxy = shl( corxy, cor );
244 701725 : corxy = shl( corxy, cor );
245 : /* cor = corxy * corxy / (corx2 * cory2) */
246 701725 : corxy = div_s( corxy, corx2 );
247 701725 : cor = shr_sat( corxy, sub( shl( tmp16, 1 ), Expx2 ) ); /* Q15 */
248 : }
249 : ELSE
250 : {
251 5019 : cor = 0;
252 5019 : move16();
253 : }
254 :
255 : /* save the norm. peak correlation in the correlation map */
256 3243220 : FOR( j = ind_mins[k - 1]; j < ind_mins[k]; j++ )
257 : {
258 2536476 : old_S[j] = S[j];
259 2536476 : move16();
260 2536476 : S[j] = shr( cor, 8 );
261 2536476 : move16();
262 2536476 : cor_map[j] = cor;
263 2536476 : move16();
264 : }
265 :
266 706744 : Lcorx2 = L_deposit_l( 0 );
267 706744 : Lcory2 = L_deposit_l( 0 );
268 706744 : Lcorxy = L_deposit_l( 0 );
269 :
270 706744 : k++;
271 : }
272 : #ifdef ISSUE_1867_replace_overflow_libenc
273 2536476 : Lcorx2 = L_mac_sat( Lcorx2, S[i], S[i] );
274 2536476 : Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
275 2536476 : Lcorxy = L_mac_sat( Lcorxy, S[i], old_S[i] );
276 : #else
277 : Lcorx2 = L_mac_o( Lcorx2, S[i], S[i], &Overflow );
278 : Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow );
279 : Lcorxy = L_mac_o( Lcorxy, S[i], old_S[i], &Overflow );
280 : #endif
281 : }
282 :
283 20698 : Copy( S, old_S, ind_mins[0] );
284 20698 : Copy( &S[ind_mins[N_mins]], &old_S[ind_mins[N_mins]], sub( L, ind_mins[N_mins] ) );
285 : }
286 : ELSE
287 : {
288 192 : *sp_floor = Bin_E[0];
289 192 : move16();
290 : }
291 20890 : *sp_floor = mult( *sp_floor, 14231 /* 1.0f / logf( 10.0f ) in Q15 */ );
292 20890 : move16(); /* Convert to log10() */
293 :
294 : /*------------------------------------------------------------------*
295 : * updating of the long-term correlation map
296 : * summation of the long-term correlation map
297 : *------------------------------------------------------------------*/
298 :
299 20890 : Lcor_map_LT_sum = L_deposit_l( 0 );
300 20890 : tmp2 = 0;
301 20890 : move16();
302 :
303 20890 : cor_strong = 0;
304 20890 : move16();
305 20890 : pt1 = cor_map_LT; // Q15
306 20890 : move16();
307 20890 : pt2 = cor_map;
308 20890 : move16();
309 2694810 : FOR( i = 0; i < L; i++ )
310 : {
311 : /* tmp2 += S[i]; */
312 2673920 : tmp2 = add( tmp2, shl( S[i], 1 ) ); /* tmp2 in Q8; max value is 128) */
313 :
314 : /* *pt1 = M_ALPHA_FX * *pt1 + (1-M_ALPHA_FX) * *pt2++ */
315 2673920 : *pt1 = mac_r( L_mult( ONE_MINUS_M_ALPHA, *pt2 ), M_ALPHA_FX, *pt1 );
316 2673920 : move16();
317 :
318 : /* cor_map_LT_sum += *pt1 */
319 2673920 : Lcor_map_LT_sum = L_add( Lcor_map_LT_sum, *pt1 ); /* cor_map_LT_sum in Q15; max value is 128) */
320 :
321 2673920 : if ( GT_16( *pt1, 31130 ) /*0.95f.Q15*/ )
322 : {
323 3718 : cor_strong = 1;
324 3718 : move16();
325 : }
326 :
327 2673920 : pt1++;
328 2673920 : pt2++;
329 : }
330 :
331 20890 : IF( ( bwidth == NB ) )
332 : {
333 : /* cor_map_LT_sum *= 1.53f; */
334 : /* tmp2 *= 1.53f; */
335 0 : Lcor_map_LT_sum = L_shl( Mult_32_16( Lcor_map_LT_sum, 25068 /* 1.53f in Q14 */ ), 1 );
336 0 : tmp2 = round_fx( L_mac( L_mult( tmp2, 32767 ), tmp2, 17367 /* 0.53 in Q15 */ ) );
337 : }
338 20890 : *cor_map_sum = tmp2;
339 20890 : move16();
340 :
341 : /* final decision about multi-harmonicity */
342 20890 : harm = 0;
343 20890 : move16();
344 20890 : test();
345 20890 : if ( ( L_msu0( Lcor_map_LT_sum, *multi_harm_limit, 64 ) > 0 ) || ( cor_strong != 0 ) )
346 : {
347 5439 : harm = 1;
348 5439 : move16();
349 : }
350 :
351 : /*------------------------------------------------------------------*
352 : * updating of the decision threshold
353 : *------------------------------------------------------------------*/
354 :
355 20890 : stemp = add( *multi_harm_limit, THR_CORR_STEP_FX );
356 20890 : if ( GT_32( Lcor_map_LT_sum, THR_CORR_FX ) ) /* Q15 */
357 : {
358 : /* *multi_harm_limit -= THR_CORR_STEP_FX */
359 6045 : stemp = sub( *multi_harm_limit, THR_CORR_STEP_FX );
360 : }
361 :
362 20890 : stemp = s_min( stemp, THR_CORR_MAX_FX );
363 20890 : *multi_harm_limit = s_max( stemp, THR_CORR_MIN_FX );
364 20890 : move16();
365 :
366 20890 : IF( N_mins <= 0 )
367 : {
368 192 : set16_fx( old_S, 0, L );
369 : }
370 20890 : IF( S_map != NULL )
371 : {
372 17790 : Copy( S, S_map, L );
373 : }
374 20890 : return harm;
375 : }
376 :
377 1132964 : Word16 multi_harm_ivas_fx( /* o : frame multi-harmonicity (1-harmonic, 0-not) */
378 : const Word16 Bin_E[], /* i : log-energy spectrum of the current frame Q7 */
379 : Word16 old_S[], /* i/o: prev. log-energy spectrum w. subtracted floor Q7 */
380 : Word16 cor_map_LT[], /* i/o: LT correlation map Q15 */
381 : Word16 *multi_harm_limit, /* i/o: multi harminic threshold Q9 */
382 : const Word32 total_brate, /* i : total bitrate Q0 */
383 : const Word16 bwidth, /* i : input signal bandwidth Q0 */
384 : Word16 *cor_strong_limit, /* i/o: HF correlation indicator Q0 */
385 : Word16 *st_mean_avr_dyn, /* i/o: long term average dynamic Q7 */
386 : Word16 *st_last_sw_dyn, /* i/o: last dynamic Q7 */
387 : Word16 *cor_map_sum, /* i : sum of correlation map Q8 */
388 : Word16 *sp_floor, /* o: noise floor estimate Q7 */
389 : Word16 S_map[] /* o : short-term correlation map Q7 */
390 : )
391 : {
392 : Word16 i, j, k, L, stemp, N_mins, ind_mins[L_FFT / 4], *pt_mins, harm;
393 : Word16 S[L_FFT / 2], flor, step, tmp16, tmp2, Expx2, Expy2;
394 : Word32 tmp2_32;
395 : Word16 corx2, cory2, corxy, cor, cor_map[L_FFT / 2], *pt1, *pt2, cor_strong;
396 : Word32 L_acc;
397 : Word32 Lcorx2, Lcory2, Lcorxy, Lcor_map_LT_sum;
398 : Word16 mean_dyn;
399 : #ifndef ISSUE_1867_replace_overflow_libenc
400 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
401 : Flag Overflow = 0;
402 : move32();
403 : #endif
404 : #endif
405 :
406 : /*------------------------------------------------------------------*
407 : * initialization
408 : *------------------------------------------------------------------*/
409 :
410 : /* length of the useful part of the spectrum (up to 6.4kHz) */
411 1132964 : L = L_FFT / 2;
412 1132964 : move16();
413 1132964 : if ( ( bwidth == NB ) )
414 : {
415 : /* length of the useful part of the spectrum (up to 3.6kHz) */
416 0 : L = 76;
417 0 : move16();
418 : }
419 :
420 1132964 : Copy( Bin_E, S, L );
421 :
422 : /*------------------------------------------------------------------*
423 : * searching of spectral maxima and minima
424 : *------------------------------------------------------------------*/
425 :
426 1132964 : pt_mins = ind_mins;
427 :
428 : /* index of the first minimum */
429 1132964 : if ( LT_16( Bin_E[0], Bin_E[1] ) )
430 : {
431 549035 : *pt_mins++ = 0;
432 549035 : move16();
433 : }
434 :
435 143886428 : FOR( i = 1; i < L - 1; i++ )
436 : {
437 : /* minimum found */
438 142753464 : test();
439 142753464 : if ( LT_16( Bin_E[i], Bin_E[i - 1] ) && LT_16( Bin_E[i], Bin_E[i + 1] ) )
440 : {
441 36416411 : *pt_mins++ = i;
442 36416411 : move16();
443 : }
444 : }
445 :
446 : /* index of the last minimum */
447 1132964 : IF( LT_16( Bin_E[L - 1], Bin_E[L - 2] ) )
448 : {
449 0 : *pt_mins++ = sub( L, 1 );
450 0 : move16();
451 : }
452 :
453 : /* total number of minimas found */
454 1132964 : N_mins = (Word16) ( pt_mins - ind_mins - 1 );
455 1132964 : move16();
456 :
457 : /*------------------------------------------------------------------*
458 : * calculation of the spectral floor
459 : * subtraction of the spectral floor
460 : *------------------------------------------------------------------*/
461 :
462 1132964 : set16_fx( S, 0, L );
463 :
464 1132964 : IF( N_mins > 0 )
465 : {
466 1068282 : L_acc = L_deposit_l( 0 );
467 36965441 : FOR( i = 0; i < N_mins; ++i )
468 : {
469 35897159 : L_acc = L_mac0( L_acc, Bin_E[ind_mins[i]], 1 );
470 : }
471 1068282 : *sp_floor = extract_l( Mult_32_16( L_acc, div_s( 1, N_mins ) ) );
472 1068282 : move16();
473 :
474 1068282 : set16_fx( S, 0, ind_mins[0] );
475 1068282 : set16_fx( &S[ind_mins[N_mins]], 0, sub( shr( L_FFT, 1 ), ind_mins[N_mins] ) );
476 :
477 1068282 : pt_mins = ind_mins;
478 1068282 : flor = 0;
479 1068282 : move16();
480 1068282 : step = 0;
481 1068282 : move16();
482 :
483 131948842 : FOR( i = ind_mins[0]; i < ind_mins[N_mins]; i++ )
484 : {
485 : /* we are at the end of the next minimum */
486 130880560 : IF( EQ_16( i, *pt_mins ) )
487 : {
488 35897159 : pt_mins++;
489 35897159 : flor = Bin_E[i];
490 35897159 : move16(); /*Q7*/
491 :
492 : /* calculate the new step */
493 : /*step = (Bin_E[*pt_mins] - Bin_E[i]) / (*pt_mins-i);*/
494 :
495 35897159 : tmp16 = div_s( 1, sub( *pt_mins, i ) ); // Q15
496 35897159 : step = msu_r( L_mult( Bin_E[*pt_mins], tmp16 ), Bin_E[i], tmp16 ); // Q7 (15+7+1-16)
497 : }
498 :
499 : /* subtract the floor */
500 130880560 : S[i] = s_max( sub_sat( Bin_E[i], flor ), 0 );
501 130880560 : move16();
502 :
503 : /* update the floor */
504 130880560 : flor = add( flor, step ); /*Q7*/
505 : }
506 : }
507 :
508 : /* Calculate the maximum dynamic per band */
509 : /* since we are processing 40 bins we will use 1/40 in Q15 to find the mean */
510 : /* mean_dyn = mean(&S[L-40], 40);*/
511 1132964 : L_acc = L_deposit_l( 0 );
512 46451524 : FOR( i = L - 40; i < L; i++ )
513 : {
514 45318560 : L_acc = L_mac( L_acc, S[i], 819 /* 1 / 40 in Q15 */ );
515 : }
516 1132964 : mean_dyn = round_fx( L_acc ); /*Q7*/
517 :
518 : /*mean_dyn = 0.6f * *st_mean_avr_dyn + 0.4f * mean_dyn;*/
519 1132964 : L_acc = L_mult( 13107 /*0.4f*/, mean_dyn ); /*Q23*/
520 1132964 : L_acc = L_mac( L_acc, 19661 /*0.6f*/, *st_mean_avr_dyn ); /*Q23*/
521 1132964 : mean_dyn = round_fx( L_acc ); /*Q7*/
522 :
523 1132964 : test();
524 1132964 : IF( LT_16( mean_dyn, 1229 ) /*9.6f*/ && *cor_strong_limit != 0 )
525 : {
526 244591 : *cor_strong_limit = 0;
527 244591 : move16();
528 244591 : *st_last_sw_dyn = mean_dyn;
529 244591 : move16();
530 : }
531 888373 : ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f*/ )
532 : {
533 37652 : *cor_strong_limit = 1;
534 37652 : move16();
535 : }
536 1132964 : test();
537 1132964 : if ( LT_32( total_brate, ACELP_9k60 ) || GT_32( total_brate, ACELP_16k40 ) )
538 : {
539 1016174 : *cor_strong_limit = 1;
540 1016174 : move16();
541 : }
542 :
543 1132964 : *st_mean_avr_dyn = mean_dyn;
544 1132964 : move16();
545 :
546 : /*------------------------------------------------------------------*
547 : * calculation of the correlation map
548 : *------------------------------------------------------------------*/
549 :
550 1132964 : set16_fx( cor_map, 0, L );
551 1132964 : IF( N_mins > 0 )
552 : {
553 1068282 : Lcorx2 = L_deposit_l( 0 );
554 1068282 : Lcorxy = L_deposit_l( 0 );
555 1068282 : stemp = ind_mins[0];
556 1068282 : move16();
557 1068282 : Lcory2 = L_mult( old_S[stemp], old_S[stemp] );
558 1068282 : k = 1;
559 1068282 : move16();
560 :
561 131948842 : FOR( i = add( stemp, 1 ); i <= ind_mins[N_mins]; i++ )
562 : {
563 130880560 : IF( EQ_16( i, ind_mins[k] ) )
564 : {
565 : /* include the last peak point (new minimum) to the corr. sum */
566 : #ifdef ISSUE_1867_replace_overflow_libenc
567 35897159 : Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
568 : #else
569 : Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow );
570 : #endif
571 :
572 : /* calculation of the norm. peak correlation */
573 35897159 : test();
574 35897159 : IF( Lcorx2 != 0 && Lcory2 != 0 )
575 : {
576 : /* corxy * corxy*/
577 35688220 : tmp16 = sub( norm_l( Lcorxy ), 1 );
578 35688220 : corxy = extract_h( L_shl( Lcorxy, tmp16 ) );
579 35688220 : corxy = mult_r( corxy, corxy );
580 : /* (corx2 * cory2) */
581 35688220 : Expx2 = norm_l( Lcorx2 );
582 35688220 : Expy2 = norm_l( Lcory2 );
583 35688220 : corx2 = extract_h( L_shl( Lcorx2, Expx2 ) );
584 35688220 : cory2 = extract_h( L_shl( Lcory2, Expy2 ) );
585 35688220 : corx2 = mult_r( corx2, cory2 );
586 35688220 : Expx2 = add( Expy2, Expx2 );
587 : /* Validate num < den */
588 35688220 : cor = sub( corx2, corxy );
589 35688220 : cor = shr( cor, 15 );
590 : /* Add 1 to tmp16 & shr by 2 if corxy > corx2 */
591 35688220 : tmp16 = sub( tmp16, cor );
592 35688220 : corxy = shl( corxy, cor );
593 35688220 : corxy = shl( corxy, cor );
594 : /* cor = corxy * corxy / (corx2 * cory2) */
595 35688220 : corxy = div_s( corxy, corx2 );
596 35688220 : cor = shr_sat( corxy, sub( shl( tmp16, 1 ), Expx2 ) ); /* Q15 */
597 : }
598 : ELSE
599 : {
600 208939 : cor = 0;
601 208939 : move16();
602 : }
603 :
604 : /* save the norm. peak correlation in the correlation map */
605 166777719 : FOR( j = ind_mins[k - 1]; j < ind_mins[k]; j++ )
606 : {
607 130880560 : old_S[j] = S[j];
608 130880560 : move16();
609 130880560 : S[j] = shr( cor, 8 );
610 130880560 : move16();
611 130880560 : cor_map[j] = cor;
612 130880560 : move16();
613 : }
614 :
615 35897159 : Lcorx2 = L_deposit_l( 0 );
616 35897159 : Lcory2 = L_deposit_l( 0 );
617 35897159 : Lcorxy = L_deposit_l( 0 );
618 :
619 35897159 : k++;
620 : }
621 : #ifdef ISSUE_1867_replace_overflow_libenc
622 130880560 : Lcorx2 = L_mac_sat( Lcorx2, S[i], S[i] );
623 130880560 : Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
624 130880560 : Lcorxy = L_mac_sat( Lcorxy, S[i], old_S[i] );
625 : #else
626 : Lcorx2 = L_mac_o( Lcorx2, S[i], S[i], &Overflow );
627 : Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow );
628 : Lcorxy = L_mac_o( Lcorxy, S[i], old_S[i], &Overflow );
629 : #endif
630 : }
631 :
632 1068282 : Copy( S, old_S, ind_mins[0] );
633 1068282 : Copy( &S[ind_mins[N_mins]], &old_S[ind_mins[N_mins]], sub( L, ind_mins[N_mins] ) );
634 : }
635 : ELSE
636 : {
637 64682 : *sp_floor = Bin_E[0];
638 64682 : move16();
639 : }
640 1132964 : *sp_floor = mult( *sp_floor, 14231 /* 1.0f / logf( 10.0f ) in Q15 */ );
641 1132964 : move16(); /* Convert to log10() */
642 :
643 : /*------------------------------------------------------------------*
644 : * updating of the long-term correlation map
645 : * summation of the long-term correlation map
646 : *------------------------------------------------------------------*/
647 :
648 1132964 : Lcor_map_LT_sum = L_deposit_l( 0 );
649 1132964 : tmp2_32 = 0;
650 1132964 : move16();
651 :
652 1132964 : cor_strong = 0;
653 1132964 : move16();
654 1132964 : pt1 = cor_map_LT;
655 1132964 : move16();
656 1132964 : pt2 = cor_map;
657 1132964 : move16();
658 146152356 : FOR( i = 0; i < L; i++ )
659 : {
660 : /* tmp2 += S[i]; */
661 145019392 : tmp2_32 = L_add( tmp2_32, cor_map[i] ); /* tmp2_32 in Q15; max value is 128) */
662 :
663 : /* *pt1 = M_ALPHA_FX * *pt1 + (1-M_ALPHA_FX) * *pt2++ */
664 145019392 : *pt1 = mac_r( L_mult( ONE_MINUS_M_ALPHA, *pt2 ), M_ALPHA_FX, *pt1 );
665 145019392 : move16();
666 :
667 : /* cor_map_LT_sum += *pt1 */
668 145019392 : Lcor_map_LT_sum = L_add( Lcor_map_LT_sum, *pt1 ); /* cor_map_LT_sum in Q15; max value is 128) */
669 :
670 145019392 : if ( GT_16( *pt1, 31130 ) /*0.95f*/ )
671 : {
672 330219 : cor_strong = 1;
673 330219 : move16();
674 : }
675 :
676 145019392 : pt1++;
677 145019392 : pt2++;
678 : }
679 1132964 : tmp2 = extract_l( L_shr_sat( tmp2_32, 7 ) ); // q15-> q8
680 :
681 1132964 : IF( ( bwidth == NB ) )
682 : {
683 : /* cor_map_LT_sum *= 1.53f; */
684 : /* tmp2 *= 1.53f; */
685 0 : Lcor_map_LT_sum = L_shl( Mult_32_16( Lcor_map_LT_sum, 25068 /* 1.53f in Q14 */ ), 1 );
686 0 : tmp2 = round_fx( L_mac( L_mult( tmp2, 32767 ), tmp2, 17367 /* 0.53 in Q15 */ ) );
687 : }
688 1132964 : *cor_map_sum = tmp2;
689 1132964 : move16();
690 :
691 : /* final decision about multi-harmonicity */
692 1132964 : harm = 0;
693 1132964 : move16();
694 1132964 : test();
695 1132964 : if ( ( L_msu0( Lcor_map_LT_sum, *multi_harm_limit, 64 ) > 0 ) || ( cor_strong != 0 ) )
696 : {
697 544016 : harm = 1;
698 544016 : move16();
699 : }
700 :
701 : /*------------------------------------------------------------------*
702 : * updating of the decision threshold
703 : *------------------------------------------------------------------*/
704 :
705 1132964 : stemp = add( *multi_harm_limit, THR_CORR_STEP_FX );
706 1132964 : if ( GT_32( Lcor_map_LT_sum, THR_CORR_FX ) ) /* Q15 */
707 : {
708 : /* *multi_harm_limit -= THR_CORR_STEP_FX */
709 536109 : stemp = sub( *multi_harm_limit, THR_CORR_STEP_FX );
710 : }
711 :
712 1132964 : stemp = s_min( stemp, THR_CORR_MAX_FX );
713 1132964 : *multi_harm_limit = s_max( stemp, THR_CORR_MIN_FX );
714 1132964 : move16();
715 :
716 1132964 : IF( N_mins <= 0 )
717 : {
718 64682 : set16_fx( old_S, 0, L );
719 : }
720 1132964 : IF( S_map != NULL )
721 : {
722 1132964 : Copy( S, S_map, L );
723 : }
724 1132964 : return harm;
725 : }
|