LCOV - code coverage report
Current view: top level - lib_enc - multi_harm_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 321 333 96.4 %
Date: 2025-05-03 01:55:50 Functions: 2 2 100.0 %

          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             : }

Generated by: LCOV version 1.14