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