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 20890 : 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 20890 : L = L_FFT / 2;
53 20890 : move16();
54 20890 : 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 20890 : Copy( Bin_E, S, L );
62 :
63 : /*------------------------------------------------------------------*
64 : * searching of spectral maxima and minima
65 : *------------------------------------------------------------------*/
66 :
67 20890 : pt_mins = ind_mins;
68 :
69 : /* index of the first minimum */
70 20890 : if ( LT_16( Bin_E[0], Bin_E[1] ) )
71 : {
72 10230 : *pt_mins++ = 0;
73 10230 : move16();
74 : }
75 :
76 2653030 : FOR( i = 1; i < L - 1; i++ )
77 : {
78 : /* minimum found */
79 2632140 : test();
80 2632140 : if ( LT_16( Bin_E[i], Bin_E[i - 1] ) && LT_16( Bin_E[i], Bin_E[i + 1] ) )
81 : {
82 717213 : *pt_mins++ = i;
83 717213 : move16();
84 : }
85 : }
86 :
87 : /* index of the last minimum */
88 20890 : 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 20890 : N_mins = (Word16) ( pt_mins - ind_mins - 1 );
96 20890 : move16();
97 :
98 : /*------------------------------------------------------------------*
99 : * calculation of the spectral floor
100 : * subtraction of the spectral floor
101 : *------------------------------------------------------------------*/
102 :
103 20890 : set16_fx( S, 0, L );
104 :
105 20890 : IF( N_mins > 0 )
106 : {
107 20698 : L_acc = L_deposit_l( 0 );
108 727442 : FOR( i = 0; i < N_mins; ++i )
109 : {
110 706744 : L_acc = L_mac0( L_acc, Bin_E[ind_mins[i]], 1 );
111 : }
112 20698 : *sp_floor = extract_l( Mult_32_16( L_acc, div_s( 1, N_mins ) ) );
113 20698 : move16();
114 :
115 20698 : set16_fx( S, 0, ind_mins[0] );
116 20698 : set16_fx( &S[ind_mins[N_mins]], 0, sub( shr( L_FFT, 1 ), ind_mins[N_mins] ) );
117 :
118 20698 : pt_mins = ind_mins;
119 20698 : flor = 0;
120 20698 : move16();
121 20698 : step = 0;
122 20698 : move16();
123 :
124 2557174 : FOR( i = ind_mins[0]; i < ind_mins[N_mins]; i++ )
125 : {
126 : /* we are at the end of the next minimum */
127 2536476 : IF( EQ_16( i, *pt_mins ) )
128 : {
129 706744 : pt_mins++;
130 706744 : flor = Bin_E[i];
131 706744 : move16(); /*Q7*/
132 : /* calculate the new step */
133 : /*step = (Bin_E[*pt_mins] - Bin_E[i]) / (*pt_mins-i);*/
134 706744 : tmp16 = sub( *pt_mins, i );
135 706744 : tmpdB = sub( Bin_E[*pt_mins], Bin_E[i] );
136 706744 : sign_fx = shr( tmpdB, 15 ); /* 0 if positive else -1 */
137 706744 : ExpdB = sub( norm_s( tmpdB ), 1 );
138 706744 : tmpdB = abs_s( shl( tmpdB, ExpdB ) );
139 706744 : ExpInd = norm_s( tmp16 );
140 706744 : tmp16 = shl( tmp16, ExpInd );
141 706744 : tmp16 = div_s( tmpdB, tmp16 );
142 706744 : tmp16 = sub( s_xor( tmp16, sign_fx ), sign_fx );
143 706744 : step = shr( tmp16, add( sub( ExpdB, ExpInd ), 15 ) ); /* Q7 */
144 : }
145 :
146 : /* subtract the floor */
147 2536476 : S[i] = s_max( sub_sat( Bin_E[i], flor ), 0 );
148 2536476 : move16();
149 :
150 : /* update the floor */
151 2536476 : 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 20890 : L_acc = L_deposit_l( 0 );
159 856490 : FOR( i = L - 40; i < L; i++ )
160 : {
161 835600 : L_acc = L_mac( L_acc, S[i], 819 /* 1 / 40 in Q15 */ );
162 : }
163 20890 : mean_dyn = round_fx( L_acc ); /*Q7*/
164 :
165 : /*mean_dyn = 0.6f * *st_mean_avr_dyn + 0.4f * mean_dyn;*/
166 20890 : L_acc = L_mult( 13107 /*0.4f*/, mean_dyn ); /*Q23*/
167 20890 : L_acc = L_mac( L_acc, 19661 /*0.6f*/, *st_mean_avr_dyn ); /*Q23*/
168 20890 : mean_dyn = round_fx( L_acc ); /*Q7*/
169 :
170 20890 : test();
171 20890 : IF( LT_16( mean_dyn, 1229 ) /*9.6f.Q7*/ && *cor_strong_limit != 0 )
172 : {
173 1701 : *cor_strong_limit = 0;
174 1701 : move16();
175 1701 : *st_last_sw_dyn = mean_dyn;
176 1701 : move16();
177 : }
178 19189 : ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f.Q7*/ )
179 : {
180 168 : *cor_strong_limit = 1;
181 168 : move16();
182 : }
183 20890 : test();
184 20890 : if ( LT_32( total_brate, ACELP_9k60 ) || GT_32( total_brate, ACELP_16k40 ) )
185 : {
186 16800 : *cor_strong_limit = 1;
187 16800 : move16();
188 : }
189 :
190 20890 : *st_mean_avr_dyn = mean_dyn;
191 20890 : move16();
192 :
193 : /*------------------------------------------------------------------*
194 : * calculation of the correlation map
195 : *------------------------------------------------------------------*/
196 :
197 20890 : set16_fx( cor_map, 0, L );
198 20890 : IF( N_mins > 0 )
199 : {
200 20698 : Lcorx2 = L_deposit_l( 0 );
201 20698 : Lcorxy = L_deposit_l( 0 );
202 20698 : stemp = ind_mins[0];
203 20698 : move16();
204 20698 : Lcory2 = L_mult( old_S[stemp], old_S[stemp] );
205 20698 : k = 1;
206 20698 : move16();
207 :
208 2557174 : FOR( i = add( stemp, 1 ); i <= ind_mins[N_mins]; i++ )
209 : {
210 2536476 : IF( EQ_16( i, ind_mins[k] ) )
211 : {
212 : /* include the last peak point (new minimum) to the corr. sum */
213 706744 : Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
214 :
215 : /* calculation of the norm. peak correlation */
216 706744 : test();
217 706744 : IF( Lcorx2 != 0 && Lcory2 != 0 )
218 : {
219 : /* corxy * corxy*/
220 701725 : tmp16 = sub( norm_l( Lcorxy ), 1 );
221 701725 : corxy = extract_h( L_shl( Lcorxy, tmp16 ) );
222 701725 : corxy = mult_r( corxy, corxy );
223 : /* (corx2 * cory2) */
224 701725 : Expx2 = norm_l( Lcorx2 );
225 701725 : Expy2 = norm_l( Lcory2 );
226 701725 : corx2 = extract_h( L_shl( Lcorx2, Expx2 ) );
227 701725 : cory2 = extract_h( L_shl( Lcory2, Expy2 ) );
228 701725 : corx2 = mult_r( corx2, cory2 );
229 701725 : Expx2 = add( Expy2, Expx2 );
230 : /* Validate num < den */
231 701725 : cor = sub( corx2, corxy );
232 701725 : cor = shr( cor, 15 );
233 : /* Add 1 to tmp16 & shr by 2 if corxy > corx2 */
234 701725 : tmp16 = sub( tmp16, cor );
235 701725 : corxy = shl( corxy, cor );
236 701725 : corxy = shl( corxy, cor );
237 : /* cor = corxy * corxy / (corx2 * cory2) */
238 701725 : corxy = div_s( corxy, corx2 );
239 701725 : cor = shr_sat( corxy, sub( shl( tmp16, 1 ), Expx2 ) ); /* Q15 */
240 : }
241 : ELSE
242 : {
243 5019 : cor = 0;
244 5019 : move16();
245 : }
246 :
247 : /* save the norm. peak correlation in the correlation map */
248 3243220 : FOR( j = ind_mins[k - 1]; j < ind_mins[k]; j++ )
249 : {
250 2536476 : old_S[j] = S[j];
251 2536476 : move16();
252 2536476 : S[j] = shr( cor, 8 );
253 2536476 : move16();
254 2536476 : cor_map[j] = cor;
255 2536476 : move16();
256 : }
257 :
258 706744 : Lcorx2 = L_deposit_l( 0 );
259 706744 : Lcory2 = L_deposit_l( 0 );
260 706744 : Lcorxy = L_deposit_l( 0 );
261 :
262 706744 : k++;
263 : }
264 2536476 : Lcorx2 = L_mac_sat( Lcorx2, S[i], S[i] );
265 2536476 : Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
266 2536476 : Lcorxy = L_mac_sat( Lcorxy, S[i], old_S[i] );
267 : }
268 :
269 20698 : Copy( S, old_S, ind_mins[0] );
270 20698 : Copy( &S[ind_mins[N_mins]], &old_S[ind_mins[N_mins]], sub( L, ind_mins[N_mins] ) );
271 : }
272 : ELSE
273 : {
274 192 : *sp_floor = Bin_E[0];
275 192 : move16();
276 : }
277 20890 : *sp_floor = mult( *sp_floor, 14231 /* 1.0f / logf( 10.0f ) in Q15 */ );
278 20890 : 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 20890 : Lcor_map_LT_sum = L_deposit_l( 0 );
286 20890 : tmp2 = 0;
287 20890 : move16();
288 :
289 20890 : cor_strong = 0;
290 20890 : move16();
291 20890 : pt1 = cor_map_LT; // Q15
292 20890 : move16();
293 20890 : pt2 = cor_map;
294 20890 : move16();
295 2694810 : FOR( i = 0; i < L; i++ )
296 : {
297 : /* tmp2 += S[i]; */
298 2673920 : 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 2673920 : *pt1 = mac_r( L_mult( ONE_MINUS_M_ALPHA, *pt2 ), M_ALPHA_FX, *pt1 );
302 2673920 : move16();
303 :
304 : /* cor_map_LT_sum += *pt1 */
305 2673920 : Lcor_map_LT_sum = L_add( Lcor_map_LT_sum, *pt1 ); /* cor_map_LT_sum in Q15; max value is 128) */
306 :
307 2673920 : if ( GT_16( *pt1, 31130 ) /*0.95f.Q15*/ )
308 : {
309 3718 : cor_strong = 1;
310 3718 : move16();
311 : }
312 :
313 2673920 : pt1++;
314 2673920 : pt2++;
315 : }
316 :
317 20890 : 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 20890 : *cor_map_sum = tmp2;
325 20890 : move16();
326 :
327 : /* final decision about multi-harmonicity */
328 20890 : harm = 0;
329 20890 : move16();
330 20890 : test();
331 20890 : if ( ( L_msu0( Lcor_map_LT_sum, *multi_harm_limit, 64 ) > 0 ) || ( cor_strong != 0 ) )
332 : {
333 5439 : harm = 1;
334 5439 : move16();
335 : }
336 :
337 : /*------------------------------------------------------------------*
338 : * updating of the decision threshold
339 : *------------------------------------------------------------------*/
340 :
341 20890 : stemp = add( *multi_harm_limit, THR_CORR_STEP_FX );
342 20890 : if ( GT_32( Lcor_map_LT_sum, THR_CORR_FX ) ) /* Q15 */
343 : {
344 : /* *multi_harm_limit -= THR_CORR_STEP_FX */
345 6045 : stemp = sub( *multi_harm_limit, THR_CORR_STEP_FX );
346 : }
347 :
348 20890 : stemp = s_min( stemp, THR_CORR_MAX_FX );
349 20890 : *multi_harm_limit = s_max( stemp, THR_CORR_MIN_FX );
350 20890 : move16();
351 :
352 20890 : IF( N_mins <= 0 )
353 : {
354 192 : set16_fx( old_S, 0, L );
355 : }
356 20890 : IF( S_map != NULL )
357 : {
358 17790 : Copy( S, S_map, L );
359 : }
360 20890 : return harm;
361 : }
362 :
363 :
364 : /* o : frame multi-harmonicity (1-harmonic, 0-not) */
365 1136964 : 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 1136964 : L = L_FFT / 2;
394 1136964 : move16();
395 1136964 : 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 1136964 : Copy( Bin_E, S, L );
403 :
404 : /*------------------------------------------------------------------*
405 : * searching of spectral maxima and minima
406 : *------------------------------------------------------------------*/
407 :
408 1136964 : pt_mins = ind_mins;
409 :
410 : /* index of the first minimum */
411 1136964 : if ( LT_16( Bin_E[0], Bin_E[1] ) )
412 : {
413 550434 : *pt_mins++ = 0;
414 550434 : move16();
415 : }
416 :
417 144394428 : FOR( i = 1; i < L - 1; i++ )
418 : {
419 : /* minimum found */
420 143257464 : test();
421 143257464 : if ( LT_16( Bin_E[i], Bin_E[i - 1] ) && LT_16( Bin_E[i], Bin_E[i + 1] ) )
422 : {
423 36516951 : *pt_mins++ = i;
424 36516951 : move16();
425 : }
426 : }
427 :
428 : /* index of the last minimum */
429 1136964 : 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 1136964 : N_mins = (Word16) ( pt_mins - ind_mins - 1 );
437 1136964 : move16();
438 :
439 : /*------------------------------------------------------------------*
440 : * calculation of the spectral floor
441 : * subtraction of the spectral floor
442 : *------------------------------------------------------------------*/
443 :
444 1136964 : set16_fx( S, 0, L );
445 :
446 1136964 : IF( N_mins > 0 )
447 : {
448 1071282 : L_acc = L_deposit_l( 0 );
449 37067380 : FOR( i = 0; i < N_mins; ++i )
450 : {
451 35996098 : L_acc = L_mac0( L_acc, Bin_E[ind_mins[i]], 1 );
452 : }
453 1071282 : *sp_floor = extract_l( Mult_32_16( L_acc, div_s( 1, N_mins ) ) );
454 1071282 : move16();
455 :
456 1071282 : set16_fx( S, 0, ind_mins[0] );
457 1071282 : set16_fx( &S[ind_mins[N_mins]], 0, sub( shr( L_FFT, 1 ), ind_mins[N_mins] ) );
458 :
459 1071282 : pt_mins = ind_mins;
460 1071282 : flor = 0;
461 1071282 : move16();
462 1071282 : step = 0;
463 1071282 : move16();
464 :
465 132319064 : FOR( i = ind_mins[0]; i < ind_mins[N_mins]; i++ )
466 : {
467 : /* we are at the end of the next minimum */
468 131247782 : IF( EQ_16( i, *pt_mins ) )
469 : {
470 35996098 : pt_mins++;
471 35996098 : flor = Bin_E[i];
472 35996098 : move16(); /*Q7*/
473 :
474 : /* calculate the new step */
475 : /*step = (Bin_E[*pt_mins] - Bin_E[i]) / (*pt_mins-i);*/
476 :
477 35996098 : tmp16 = div_s( 1, sub( *pt_mins, i ) ); // Q15
478 35996098 : 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 131247782 : S[i] = s_max( sub_sat( Bin_E[i], flor ), 0 );
483 131247782 : move16();
484 :
485 : /* update the floor */
486 131247782 : 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 1136964 : L_acc = L_deposit_l( 0 );
494 46615524 : FOR( i = L - 40; i < L; i++ )
495 : {
496 45478560 : L_acc = L_mac( L_acc, S[i], 819 /* 1 / 40 in Q15 */ );
497 : }
498 1136964 : mean_dyn = round_fx( L_acc ); /*Q7*/
499 :
500 : /*mean_dyn = 0.6f * *st_mean_avr_dyn + 0.4f * mean_dyn;*/
501 1136964 : L_acc = L_mult( 13107 /*0.4f*/, mean_dyn ); /*Q23*/
502 1136964 : L_acc = L_mac( L_acc, 19661 /*0.6f*/, *st_mean_avr_dyn ); /*Q23*/
503 1136964 : mean_dyn = round_fx( L_acc ); /*Q7*/
504 :
505 1136964 : test();
506 1136964 : IF( LT_16( mean_dyn, 1229 ) /*9.6f*/ && *cor_strong_limit != 0 )
507 : {
508 244591 : *cor_strong_limit = 0;
509 244591 : move16();
510 244591 : *st_last_sw_dyn = mean_dyn;
511 244591 : move16();
512 : }
513 892373 : ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f*/ )
514 : {
515 37678 : *cor_strong_limit = 1;
516 37678 : move16();
517 : }
518 1136964 : test();
519 1136964 : if ( LT_32( total_brate, ACELP_9k60 ) || GT_32( total_brate, ACELP_16k40 ) )
520 : {
521 1020174 : *cor_strong_limit = 1;
522 1020174 : move16();
523 : }
524 :
525 1136964 : *st_mean_avr_dyn = mean_dyn;
526 1136964 : move16();
527 :
528 : /*------------------------------------------------------------------*
529 : * calculation of the correlation map
530 : *------------------------------------------------------------------*/
531 :
532 1136964 : set16_fx( cor_map, 0, L );
533 1136964 : IF( N_mins > 0 )
534 : {
535 1071282 : Lcorx2 = L_deposit_l( 0 );
536 1071282 : Lcorxy = L_deposit_l( 0 );
537 1071282 : stemp = ind_mins[0];
538 1071282 : move16();
539 1071282 : Lcory2 = L_mult( old_S[stemp], old_S[stemp] );
540 1071282 : k = 1;
541 1071282 : move16();
542 :
543 132319064 : FOR( i = add( stemp, 1 ); i <= ind_mins[N_mins]; i++ )
544 : {
545 131247782 : IF( EQ_16( i, ind_mins[k] ) )
546 : {
547 : /* include the last peak point (new minimum) to the corr. sum */
548 35996098 : Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
549 :
550 : /* calculation of the norm. peak correlation */
551 35996098 : test();
552 35996098 : IF( Lcorx2 != 0 && Lcory2 != 0 )
553 : {
554 : /* corxy * corxy*/
555 35786511 : tmp16 = sub( norm_l( Lcorxy ), 1 );
556 35786511 : corxy = extract_h( L_shl( Lcorxy, tmp16 ) );
557 35786511 : corxy = mult_r( corxy, corxy );
558 : /* (corx2 * cory2) */
559 35786511 : Expx2 = norm_l( Lcorx2 );
560 35786511 : Expy2 = norm_l( Lcory2 );
561 35786511 : corx2 = extract_h( L_shl( Lcorx2, Expx2 ) );
562 35786511 : cory2 = extract_h( L_shl( Lcory2, Expy2 ) );
563 35786511 : corx2 = mult_r( corx2, cory2 );
564 35786511 : Expx2 = add( Expy2, Expx2 );
565 : /* Validate num < den */
566 35786511 : cor = sub( corx2, corxy );
567 35786511 : cor = shr( cor, 15 );
568 : /* Add 1 to tmp16 & shr by 2 if corxy > corx2 */
569 35786511 : tmp16 = sub( tmp16, cor );
570 35786511 : corxy = shl( corxy, cor );
571 35786511 : corxy = shl( corxy, cor );
572 : /* cor = corxy * corxy / (corx2 * cory2) */
573 35786511 : corxy = div_s( corxy, corx2 );
574 35786511 : cor = shr_sat( corxy, sub( shl( tmp16, 1 ), Expx2 ) ); /* Q15 */
575 : }
576 : ELSE
577 : {
578 209587 : cor = 0;
579 209587 : move16();
580 : }
581 :
582 : /* save the norm. peak correlation in the correlation map */
583 167243880 : FOR( j = ind_mins[k - 1]; j < ind_mins[k]; j++ )
584 : {
585 131247782 : old_S[j] = S[j];
586 131247782 : move16();
587 131247782 : S[j] = shr( cor, 8 );
588 131247782 : move16();
589 131247782 : cor_map[j] = cor;
590 131247782 : move16();
591 : }
592 :
593 35996098 : Lcorx2 = L_deposit_l( 0 );
594 35996098 : Lcory2 = L_deposit_l( 0 );
595 35996098 : Lcorxy = L_deposit_l( 0 );
596 :
597 35996098 : k++;
598 : }
599 131247782 : Lcorx2 = L_mac_sat( Lcorx2, S[i], S[i] );
600 131247782 : Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
601 131247782 : Lcorxy = L_mac_sat( Lcorxy, S[i], old_S[i] );
602 : }
603 :
604 1071282 : Copy( S, old_S, ind_mins[0] );
605 1071282 : Copy( &S[ind_mins[N_mins]], &old_S[ind_mins[N_mins]], sub( L, ind_mins[N_mins] ) );
606 : }
607 : ELSE
608 : {
609 65682 : *sp_floor = Bin_E[0];
610 65682 : move16();
611 : }
612 1136964 : *sp_floor = mult( *sp_floor, 14231 /* 1.0f / logf( 10.0f ) in Q15 */ );
613 1136964 : 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 1136964 : Lcor_map_LT_sum = L_deposit_l( 0 );
621 1136964 : tmp2_32 = 0;
622 1136964 : move16();
623 :
624 1136964 : cor_strong = 0;
625 1136964 : move16();
626 1136964 : pt1 = cor_map_LT;
627 1136964 : move16();
628 1136964 : pt2 = cor_map;
629 1136964 : move16();
630 146668356 : FOR( i = 0; i < L; i++ )
631 : {
632 : /* tmp2 += S[i]; */
633 145531392 : 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 145531392 : *pt1 = mac_r( L_mult( ONE_MINUS_M_ALPHA, *pt2 ), M_ALPHA_FX, *pt1 );
637 145531392 : move16();
638 :
639 : /* cor_map_LT_sum += *pt1 */
640 145531392 : Lcor_map_LT_sum = L_add( Lcor_map_LT_sum, *pt1 ); /* cor_map_LT_sum in Q15; max value is 128) */
641 :
642 145531392 : if ( GT_16( *pt1, 31130 ) /*0.95f*/ )
643 : {
644 330851 : cor_strong = 1;
645 330851 : move16();
646 : }
647 :
648 145531392 : pt1++;
649 145531392 : pt2++;
650 : }
651 1136964 : tmp2 = extract_l( L_shr_sat( tmp2_32, 7 ) ); // q15-> q8
652 :
653 1136964 : 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 1136964 : *cor_map_sum = tmp2;
661 1136964 : move16();
662 :
663 : /* final decision about multi-harmonicity */
664 1136964 : harm = 0;
665 1136964 : move16();
666 1136964 : test();
667 1136964 : if ( ( L_msu0( Lcor_map_LT_sum, *multi_harm_limit, 64 ) > 0 ) || ( cor_strong != 0 ) )
668 : {
669 546119 : harm = 1;
670 546119 : move16();
671 : }
672 :
673 : /*------------------------------------------------------------------*
674 : * updating of the decision threshold
675 : *------------------------------------------------------------------*/
676 :
677 1136964 : stemp = add( *multi_harm_limit, THR_CORR_STEP_FX );
678 1136964 : if ( GT_32( Lcor_map_LT_sum, THR_CORR_FX ) ) /* Q15 */
679 : {
680 : /* *multi_harm_limit -= THR_CORR_STEP_FX */
681 538111 : stemp = sub( *multi_harm_limit, THR_CORR_STEP_FX );
682 : }
683 :
684 1136964 : stemp = s_min( stemp, THR_CORR_MAX_FX );
685 1136964 : *multi_harm_limit = s_max( stemp, THR_CORR_MIN_FX );
686 1136964 : move16();
687 :
688 1136964 : IF( N_mins <= 0 )
689 : {
690 65682 : set16_fx( old_S, 0, L );
691 : }
692 1136964 : IF( S_map != NULL )
693 : {
694 1136964 : Copy( S, S_map, L );
695 : }
696 1136964 : return harm;
697 : }
|