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