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

          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"
       7             : #include "cnst.h"
       8             : #include "basop_util.h"
       9             : // #include "prot_fx.h"
      10             : #include "prot_fx.h"     /* Function prototypes                    */
      11             : #include "prot_fx_enc.h" /* Function prototypes                    */
      12             : #include "rom_enc.h"
      13             : #include "rom_com.h"
      14             : #include <assert.h>
      15             : #include <math.h>
      16             : /*-------------------------------------------------------------------*
      17             :  * Local prototypes
      18             :  *-------------------------------------------------------------------*/
      19             : 
      20             : static void find_enr( Word16 data[], Word32 band[], Word32 *ptE, Word32 *LEtot, const Word16 min_band, const Word16 max_band, const Word16 Q_new2, const Word32 e_min, Word32 *Bin_E, Word16 BIN_FREQ_FX, Word32 *band_energies );
      21             : static void ivas_find_enr( Word16 *data, Word16 q_data, Word32 *band, Word16 *q_band, Word32 *ptE, Word16 *q_ptE, Word64 *LEtot, const Word16 min_band, const Word16 max_band, Word32 *Bin_E, Word16 BIN_FREQ_FX, Word32 *band_energies );
      22             : 
      23             : 
      24             : /*-------------------------------------------------------------------*
      25             :  * analy_sp_fx()
      26             :  *
      27             :  * Spectral analysis of 12.8kHz input
      28             :  *-------------------------------------------------------------------*/
      29             : 
      30        3100 : void analy_sp_fx(
      31             :     const Word16 element_mode, /* i  : element mode                                    */
      32             :     Word16 *speech,            /* i  : speech buffer                          Q_new - preemph_bits */
      33             :     const Word16 Q_new,        /* i  : current scaling exp                    Q0                 */
      34             :     Word32 *fr_bands,          /* o  : energy in critical frequency bands     Q_new + QSCALE    */
      35             :     Word32 *lf_E,              /* o  : per bin E for first...                 Q_new + QSCALE - 2*/
      36             :     Word16 *Etot,              /* o  : total input energy                     Q8                 */
      37             :     const Word16 min_band,     /* i  : minimum critical band                  Q0                 */
      38             :     const Word16 max_band,     /* i  : maximum critical band                  Q0                 */
      39             :     const Word32 e_min_scaled, /* i  : minimum energy scaled                  Q_new + QSCALE    */
      40             :     Word16 Scale_fac[2],       /* o  : FFT scales factors (2 values by frame) Q0                 */
      41             :     Word32 *Bin_E,             /* o  : per-bin energy spectrum                                  */
      42             :     Word32 *Bin_E_old,         /* o  : per-bin energy spectrum of the previous frame            */
      43             :     Word32 *PS,                /* o  : per-bin energy spectrum                                  */
      44             :     Word16 *EspecdB,           /* o  : per-bin log energy spectrum (with f=0) Q7                */
      45             :     Word32 *band_energies,     /* o  : energy in critical frequency bands without minimum noise floor MODE2_E_MIN */
      46             :     Word16 *fft_buff           /* o  : FFT coefficients                                         */
      47             : )
      48             : {
      49             :     Word16 *pt;
      50             :     Word16 i_subfr, i, exp_etot, frac_etot, exp, exp_frac, exp2;
      51             :     Word32 *pt_bands;
      52             :     Word32 Ltmp, LEtot, L_tmp2;
      53             :     Word16 *pt_fft;
      54             :     Word16 Min_val, Max_val;
      55             :     Word16 Scale_fac2;
      56             :     Word16 fft_temp[L_FFT];
      57             : 
      58             :     /*-----------------------------------------------------------------*
      59             :      * Compute spectrum
      60             :      * find energy per critical frequency band and total energy in dB
      61             :      *-----------------------------------------------------------------*/
      62             : 
      63        3100 :     pt_bands = fr_bands; /* Q_new + QSCALE */
      64        3100 :     pt_fft = fft_buff;
      65        3100 :     LEtot = L_deposit_l( 0 );
      66        3100 :     IF( NE_16( element_mode, IVAS_CPE_DFT ) )
      67             :     {
      68        9300 :         FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ )
      69             :         {
      70        6200 :             pt = speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2; /* Q_new - preemph_bits */
      71        6200 :             if ( i_subfr != 0 )
      72             :             {
      73        3100 :                 pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2; /* Q_new - preemph_bits */
      74             :             }
      75             : 
      76             :             /* Clear 1st value of 1st part, copy 1st value of 2nd part */
      77        6200 :             fft_temp[0] = 0;
      78        6200 :             move16();
      79        6200 :             fft_temp[L_FFT / 2] = pt[L_FFT / 2]; /* Q_new - preemph_bits */
      80        6200 :             move16();
      81        6200 :             Max_val = s_max( fft_temp[0], fft_temp[L_FFT / 2] ); /* Q_new - preemph_bits */
      82        6200 :             Min_val = s_min( fft_temp[0], fft_temp[L_FFT / 2] ); /* Q_new - preemph_bits */
      83             : 
      84      793600 :             FOR( i = 1; i < L_FFT / 2; i++ )
      85             :             {
      86             :                 /* 1st windowed part */
      87      787400 :                 fft_temp[i] = mult_r( pt[i], sqrt_han_window_fx[i] ); /* Q_new - preemph_bits */
      88      787400 :                 move16();
      89      787400 :                 IF( fft_temp[i] > 0 )
      90             :                 {
      91      396222 :                     Max_val = s_max( Max_val, fft_temp[i] ); /* Q_new - preemph_bits */
      92             :                 }
      93      787400 :                 IF( fft_temp[i] < 0 )
      94             :                 {
      95      387611 :                     Min_val = s_min( Min_val, fft_temp[i] ); /* Q_new - preemph_bits */
      96             :                 }
      97             : 
      98             :                 /* 2nd windowed part  */
      99      787400 :                 fft_temp[L_FFT - i] = mult_r( pt[L_FFT - i], sqrt_han_window_fx[i] ); /* Q_new - preemph_bits */
     100      787400 :                 move16();
     101      787400 :                 IF( fft_temp[L_FFT - i] > 0 )
     102             :                 {
     103      396243 :                     Max_val = s_max( Max_val, fft_temp[L_FFT - i] ); /* Q_new - preemph_bits */
     104             :                 }
     105      787400 :                 IF( fft_temp[L_FFT - i] < 0 )
     106             :                 {
     107      387515 :                     Min_val = s_min( Min_val, fft_temp[L_FFT - i] ); /* Q_new - preemph_bits */
     108             :                 }
     109             :             }
     110             : 
     111             :             /* Combine -Min_val and Max_val into one */
     112        6200 :             Max_val = s_max( negate( Min_val ), Max_val );
     113             : 
     114        6200 :             Scale_fac[i_subfr] = s_min( sub( norm_s( Max_val ), 1 ), 6 );
     115        6200 :             move16();
     116        6200 :             Scale_fac2 = shl( Scale_fac[i_subfr], 1 );
     117        6200 :             Scale_sig( fft_temp, L_FRAME_12k8, Scale_fac[i_subfr] ); /* Q_new - preemph_bits + Scale_fac */
     118             : 
     119        6200 :             r_fft_fx_lc( FFT_W128, SIZE_256, SIZE2_256, NUM_STAGE_256, fft_temp, pt_fft, 1 );
     120             : 
     121             :             /* find energy per critical band */
     122        6200 :             find_enr( pt_fft, pt_bands, lf_E + i_subfr * VOIC_BINS, &LEtot, min_band, max_band,
     123        6200 :                       add( Q_new, Scale_fac2 ), e_min_scaled, &Bin_E[i_subfr * L_FFT / 2], BIN, band_energies + i_subfr * NB_BANDS );
     124             : 
     125        6200 :             pt_bands += NB_BANDS;
     126        6200 :             pt_fft += L_FFT;
     127             :         }
     128             :     }
     129             : 
     130             :     /* Average total log energy over both half-frames */
     131        3100 :     frac_etot = 0;
     132        3100 :     move16();
     133        3100 :     exp_etot = norm_l( LEtot );
     134        3100 :     IF( LEtot != 0 ) /* Log2_norm_lc doesn't Support Input <= 0; deal with it here */
     135             :     {
     136        3100 :         frac_etot = Log2_norm_lc( L_shl( LEtot, exp_etot ) );
     137        3100 :         exp_etot = sub( 30, exp_etot );
     138             :     }
     139        3100 :     exp_etot = sub( exp_etot, add( Q_new, 1 + 3 ) ); /* remove scaling effect, 4 already removed */
     140        3100 :     Ltmp = Mpy_32( exp_etot, frac_etot, LG10, 0 );
     141             : 
     142             :     /*Q8 Averaged the total energy over both half-frames in log10  */
     143        3100 :     *Etot = extract_l( L_shr( Ltmp, 14 - 8 ) ); /* Q8 */
     144             : 
     145        3100 :     Bin_E[L_FFT / 2 - 1] = Bin_E[L_FFT / 2 - 2];
     146        3100 :     move32();
     147        3100 :     Bin_E[L_FFT - 1] = Bin_E[L_FFT - 2];
     148        3100 :     move32();
     149             : 
     150             :     /* Per-bin log-energy spectrum */
     151        3100 :     exp2 = sub( 31, add( Q_new, QSCALE - 2 ) );
     152        3100 :     L_tmp2 = L_mac( -56783L, exp2, 28391 );
     153      399900 :     FOR( i = 0; i < L_FFT / 2; i++ )
     154             :     {
     155      396800 :         Bin_E_old[i] = Bin_E[i];
     156      396800 :         move32();
     157             : 
     158             :         /* tmp = (input[i] + input[i+Len]+0.001f)/2.0f */
     159      396800 :         Ltmp = L_max( 1, L_add( L_shr( Bin_E[i], 1 ), L_shr( Bin_E[i + L_FFT / 2], 1 ) ) );
     160      396800 :         if ( PS != NULL )
     161             :         {
     162      396800 :             PS[i] = Ltmp;
     163      396800 :             move32();
     164             :         }
     165             : 
     166             :         /* 10.0*log((float)tmp)                                  */
     167             :         /* 10.0*Log(2)*Log2(L_tmp/2)                             */
     168             :         /* 6.93147*Log2(L_tmp/2)                                 */
     169             :         /* 0.86643*(Log2(L_tmp)-1)*8                             */
     170             :         /* 0.86643*Log2(L_tmp)*8 - 6.93147                       */
     171             :         /* We'll put it in Q8                                    */
     172      396800 :         exp = norm_l( Ltmp );
     173      396800 :         exp_frac = Log2_norm_lc( L_shl( Ltmp, exp ) );
     174             :         /* -56783L is to substract 0.86643 in Q16                */
     175             :         /* 28391 is 0.86643 in Q15                               */
     176             :         /* 1774 is (0.86643 in Q15) * 8 / 128 (/128 to go in Q7) */
     177      396800 :         EspecdB[i] = mac_r( L_shl( L_msu( L_tmp2, exp, 28391 ), 3 + 7 ), exp_frac, 887 ); /* Q7 */
     178      396800 :         move16();
     179             :     }
     180             : 
     181             : 
     182        3100 :     return;
     183             : }
     184             : 
     185             : /*------------------------------------------------------------------------*
     186             :  * find_enr_dft_fx()
     187             :  *
     188             :  * find input signal energy for each critical band using the DFT buffers
     189             :  *------------------------------------------------------------------------*/
     190             : 
     191             : 
     192       59643 : static void find_enr_dft_ivas_fx(
     193             :     CPE_ENC_HANDLE hCPE,      /* i/o: CPE encoder structure                            */
     194             :     const Word32 input_Fs,    /* i  : input sampling rate                              Q0*/
     195             :     Word32 DFT_past_DMX_fx[], /* i  :input DFT_Dmx      (Q_inp_dmx )                   */
     196             :     Word32 band_fx[],         /* o  : per band energy   (*q_band)                      */
     197             :     Word16 *q_band,           /* o  : Q of per band energy                             */
     198             :     Word32 *ptE_fx,           /* o  : per bin energy  for low frequencies  (*q_ptE)    */
     199             :     Word16 *q_ptE,            /* o  : Q of per bin energy  for low frequencies         */
     200             :     Word64 *Etot_fx,          /* i/o: total energy      (Q8)                           */
     201             :     const Word16 min_band,    /* i  : minimum critical band                            Q0*/
     202             :     const Word16 max_band,    /* i  : maximum critical band                            Q0*/
     203             :     Word32 *Bin_E_fx,         /* o  : Per bin energy      (Q7)                         */
     204             :     Word16 *q_Bin_E,          /* o  : Q of Per bin energy           (*q_band)          */
     205             :     Word32 *band_ener_fx,     /* o  : per band energy without E_MIN                    */
     206             :     Word16 Q_inp_dmx )
     207             : {
     208             :     Word16 i;
     209             :     Word64 tot_ener;
     210             :     Word32 freq;
     211             :     const Word32 *ptR_fx, *ptI_fx;
     212             :     Word16 norm_val_fx;
     213             :     Word16 bin_cnt;
     214             :     Word32 c_fx, s_fx;
     215             :     Word32 g_fx;
     216             :     Word32 scaleWin_fx;
     217             :     Word16 bin_freq;
     218             :     Word16 temp1, temp2, exp, exp1;
     219             :     Word16 q_norm_val;
     220             :     Word32 BinE_fx[STEREO_DFT_N_12k8_ENC / 2]; /* NB_BANDS = 20 (=  6350Hz) = highest band available for SR 12.8  -> bin_cnt = 158 */
     221             :     Word32 c_1_fx, s_1_fx, g_1_fx, g_2_fx;
     222             :     Word64 band_ener;
     223             :     Word32 BinE, tmp_fx;
     224             :     Word32 start_freq;
     225             :     Word32 min_ener;
     226       59643 :     Word16 shift = 0;
     227       59643 :     move16();
     228             : 
     229             :     /* One window - 40ms*12.8kHz = 512 samples */
     230       59643 :     c_1_fx = 1073660991; // 0.999924719 in Q30, cosf( PI2 / STEREO_DFT_N_12k8_ENC )
     231       59643 :     s_1_fx = 13176464;   // 0.0122715384 in Q30, sinf( PI2 / STEREO_DFT_N_12k8_ENC )
     232       59643 :     g_1_fx = 1570240043; // 1.4624 in Q30, ( 1.f + 0.68f * 0.68f )
     233       59643 :     g_2_fx = 1460288880; // 1.36 in Q30, 2 * 0.68f
     234       59643 :     move32();
     235       59643 :     move32();
     236       59643 :     move32();
     237       59643 :     move32();
     238             : 
     239       59643 :     bin_cnt = 0;
     240       59643 :     move16();
     241             : 
     242             :     /* input_Fs / (float) hCPE->hStereoDft->NFFT;*/ /* adaptive frequency bin width */
     243       59643 :     bin_freq = BASOP_Util_Divide3216_Scale( input_Fs, hCPE->hStereoDft->NFFT, &exp );
     244       59643 :     bin_freq = shl( bin_freq, add( 1, exp ) ); // Q0
     245             : 
     246             :     /* scaleWin = 1 / ( 2 * hCPE->hStereoDft->win_ana_energy );
     247             :        scaleWin *= (float) BIN / bin_freq; */
     248             : 
     249       59643 :     temp2 = BASOP_Util_Divide3216_Scale( BIN, bin_freq, &exp );
     250       59643 :     temp2 = shl( temp2, add( 1, exp ) ); // Q0
     251       59643 :     exp = norm_s( hCPE->hStereoDft->win_ana_energy_fx );
     252       59643 :     temp1 = div_s( ONE_IN_Q14, shl( hCPE->hStereoDft->win_ana_energy_fx, exp ) ); // 14-(15+exp-1)+15 = 15+exp
     253       59643 :     scaleWin_fx = L_mult0( temp1, temp2 );                                        // 15+exp
     254             : 
     255             :     /* scaleWin * 4.0f makes Q of scaleWin_fx from 15+exp to 13+exp
     256             :        norm_val = scaleWin * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT ); */
     257             : 
     258       59643 :     norm_val_fx = BASOP_Util_Divide3232_Scale( scaleWin_fx, L_mult0( hCPE->hStereoDft->NFFT, hCPE->hStereoDft->NFFT ), &exp1 ); // 13+exp+15-exp1 = 28+exp-exp1
     259       59643 :     q_norm_val = add( 28, sub( exp, exp1 ) );
     260             : 
     261       59643 :     ptR_fx = &DFT_past_DMX_fx[2]; /* first real  */
     262       59643 :     ptI_fx = &DFT_past_DMX_fx[3]; /* first imaginary */
     263             : 
     264       59643 :     c_fx = c_1_fx; // Q30
     265       59643 :     s_fx = s_1_fx; // Q30
     266       59643 :     move32();
     267       59643 :     move32();
     268             : 
     269             :     /* for low frequency bins, save per bin energy for the use in find_tilt() */
     270       59643 :     freq = bin_freq;
     271       59643 :     move32();
     272             : 
     273       59643 :     *q_band = add( shl( Q_inp_dmx, 1 ), sub( q_norm_val, 48 ) );
     274       59643 :     move16();
     275       59643 :     *q_Bin_E = *q_band;
     276       59643 :     move16();
     277             : 
     278       59643 :     IF( GT_16( *q_band, 39 ) )
     279             :     {
     280           0 :         shift = sub( *q_band, 39 );
     281           0 :         *q_band = 39;
     282           0 :         move16();
     283             :     }
     284             : 
     285       59643 :     min_ener = L_shl( E_MIN_FXQ31 /* 0.0035 in Q31 */, sub( *q_band, 31 ) );
     286     1192860 :     FOR( i = 0; i < NB_BANDS - 1; i++ ) /* up to maximum allowed voiced critical band */
     287             :     {
     288     1133217 :         band_ener = 0;
     289     1133217 :         move64();
     290     1133217 :         start_freq = freq;
     291     1133217 :         move32();
     292             : 
     293             :         /* bins up to crit_band 17 (<= 3700 Hz):
     294             :          * bin_cnt old (bin_width 50 Hz): 74 (74 * FRAMES_PER_SEC = 3700)
     295             :          * bin_cnt new (bin_width 40 Hz): 92 (92 * 40 = 3680)
     296             :          */
     297             : 
     298    13777533 :         WHILE( LE_32( freq, crit_bands_fx[i] ) )
     299             :         {
     300             :             // g_fx = L_sub( g_1_fx, L_shl( Mpy_32_32( g_2_fx, c_fx ), 1 ) );            // 30
     301    12644316 :             g_fx = L_sub( L_shr( g_1_fx, 1 ), Mpy_32_32( g_2_fx, c_fx ) );            // 29
     302    12644316 :             tmp_fx = Msub_32_32( Mpy_32_32( c_fx, c_1_fx ), s_fx, s_1_fx );           // 29
     303    12644316 :             s_fx = L_shl( Madd_32_32( Mpy_32_32( s_fx, c_1_fx ), c_fx, s_1_fx ), 1 ); // 30
     304    12644316 :             c_fx = L_shl( tmp_fx, 1 );                                                // 30
     305             : 
     306    12644316 :             BinE = Madd_32_32( Mpy_32_32( *ptR_fx, *ptR_fx ), *ptI_fx, *ptI_fx );   // 2*Q_inp_dmx-31
     307    12644316 :             BinE_fx[bin_cnt] = Mpy_32_32( BinE, Mpy_32_16_1( g_fx, norm_val_fx ) ); // (2*Q_inp_dmx-31)+(q_norm_val+29-15)-31 = 2*Q_inp_dmx+q_norm_val-48 = *q_Bin_E
     308    12644316 :             move32();
     309             : 
     310             :             /*
     311             :                 BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / bin_freq ) + 1
     312             :                 band[i] = BinE[bin_cnt];
     313             :                 band[i] *= inv_tbl[cnt]; // normalization per frequency bin
     314             :             */
     315    12644316 :             band_ener = W_mac_32_16( band_ener, BinE_fx[bin_cnt], inv_tbl_fx[( ( crit_bands_fx[i] - start_freq ) / bin_freq ) + 1] ); // *q_band+shift+16
     316             : 
     317    12644316 :             ptR_fx += 2;
     318    12644316 :             ptI_fx += 2;
     319    12644316 :             freq = L_mac0( freq, bin_freq, 1 );
     320    12644316 :             bin_cnt = add( bin_cnt, 1 );
     321             :         }
     322             : 
     323             :         /* normalization per frequency bin */
     324     1133217 :         band_fx[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band
     325     1133217 :         move32();
     326             : 
     327             :         /* per band energy without E_MIN   */
     328     1133217 :         band_ener_fx[i] = band_fx[i]; // *q_band
     329     1133217 :         move32();
     330             : 
     331     1133217 :         if ( LT_32( band_fx[i], min_ener ) )
     332             :         {
     333       67760 :             band_fx[i] = min_ener; // *q_band
     334       67760 :             move32();
     335             :         }
     336             :     }
     337             : 
     338             :     /* continue computing the energy per critical band for higher frequencies */
     339             : 
     340             :     /* old version, FFT 256 @ SR12.8 (-> bin_width = 50 Hz):
     341             :        NB_BANDS = 20 (=  6350Hz) = highest band available for SR 12.8 -> bin_cnt = 127 = L_FFT/2-1*/
     342             : 
     343             :     /* new version: DFT (1200/800/400) @ input SR (48/32/16) (-> bin_width = 40 Hz):
     344             :      *
     345             :      */
     346             :     /* NB_BANDS = 20 (=  6350Hz) = highest band available for SR 12.8  -> bin_cnt = 158 */
     347             :     /* NB_BANDS = 21 (=  7700Hz) = highest band available for SR 16    -> bin_cnt = 192 */
     348             :     /* NB_BANDS = 24 (= 15500Hz) = highest band available for SR 32    -> bin_cnt = 387 */
     349             :     /* NB_BANDS = 24 (= 15500Hz) = highest band available for SR 48    -> bin_cnt = 387 */
     350             : 
     351      119286 :     FOR( ; i < NB_BANDS; i++ )
     352             :     {
     353       59643 :         band_ener = 0;
     354       59643 :         move64();
     355       59643 :         start_freq = freq;
     356       59643 :         move32();
     357             : 
     358     2624292 :         WHILE( LT_32( freq, 6399 ) )
     359             :         {
     360             : 
     361             :             // g_fx = L_sub( g_1_fx, L_shl( Mpy_32_32( g_2_fx, c_fx ), 1 ) ); // 30
     362     2564649 :             g_fx = L_sub( L_shr( g_1_fx, 1 ), Mpy_32_32( g_2_fx, c_fx ) ); // 29
     363             : 
     364     2564649 :             BinE = Madd_32_32( Mpy_32_32( *ptR_fx, *ptR_fx ), *ptI_fx, *ptI_fx );   // 2*Q_inp_dmx-31
     365     2564649 :             BinE_fx[bin_cnt] = Mpy_32_32( BinE, Mpy_32_16_1( g_fx, norm_val_fx ) ); // (2*Q_inp_dmx-31)+(q_norm_val+29-15)-31 = 2*Q_inp_dmx+q_norm_val-48 = *q_Bin_E
     366     2564649 :             move32();
     367             : 
     368             :             /*
     369             :                 BIN_FREQ_FX = BIN, cnt = ( ( 6399 - start_freq ) / bin_freq ) + 1
     370             :                 band[i] = BinE[bin_cnt];
     371             :                 band[i] *= inv_tbl[cnt]; // normalization per frequency bin
     372             :             */
     373     2564649 :             band_ener = W_mac_32_16( band_ener, BinE_fx[bin_cnt], inv_tbl_fx[( ( 6399 - start_freq ) / bin_freq ) + 1] ); // *q_band+shift
     374             : 
     375     2564649 :             ptR_fx += 2;
     376     2564649 :             ptI_fx += 2;
     377     2564649 :             freq = L_mac0( freq, bin_freq, 1 );
     378     2564649 :             bin_cnt = add( bin_cnt, 1 );
     379             :         }
     380             : 
     381             :         /* normalization per frequency bin */
     382       59643 :         band_fx[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band
     383       59643 :         move32();
     384             : 
     385             :         /* per band energy without E_MIN   */
     386       59643 :         band_ener_fx[i] = band_fx[i]; // *q_band
     387       59643 :         move32();
     388             : 
     389       59643 :         if ( LT_32( band_fx[i], min_ener ) )
     390             :         {
     391        3050 :             band_fx[i] = min_ener; // *q_band
     392        3050 :             move32();
     393             :         }
     394             :     }
     395             : 
     396             :     /* put bin energies from BinE into Bin_E[L_FFT/2-1] (interpolate 40 Hz bin values to fit into 50 Hz bins) */
     397             :     /* Last value of Bin_E is handled outside this function*/
     398       59643 :     assert( bin_cnt == ( STEREO_DFT_N_12k8_ENC / 2 - 1 ) );
     399       59643 :     BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 1] = BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 2]; // // *q_Bin_E
     400       59643 :     move32();
     401             : 
     402       59643 :     Word16 norm = getScaleFactor32( BinE_fx, L_FFT );
     403       59643 :     scale_sig32( BinE_fx, L_FFT, norm );
     404       59643 :     *q_Bin_E = add( *q_Bin_E, norm );
     405       59643 :     move16();
     406       59643 :     L_lerp_fx( BinE_fx, Bin_E_fx, L_FFT / 2, STEREO_DFT_N_12k8_ENC / 2, q_Bin_E );
     407             : 
     408       59643 :     MVR2R_WORD32( Bin_E_fx, ptE_fx, VOIC_BINS ); // *q_Bin_E
     409       59643 :     *q_ptE = *q_Bin_E;
     410       59643 :     move16();
     411             : 
     412             :     /* find the total log energy */
     413       59643 :     tot_ener = *Etot_fx;
     414       59643 :     move64();
     415             : 
     416     1252503 :     FOR( i = min_band; i <= max_band; i++ )
     417             :     {
     418     1192860 :         tot_ener = W_mac_32_32( tot_ener, band_fx[i], 1 ); // *q_band+1
     419             :     }
     420             : 
     421       59643 :     *Etot_fx = tot_ener;
     422       59643 :     move64();
     423             : 
     424       59643 :     return;
     425             : }
     426             : /*-------------------------------------------------------------------*
     427             :  * ivas_analy_sp_fx()
     428             :  *
     429             :  * Spectral analysis of 12.8kHz input
     430             :  *-------------------------------------------------------------------*/
     431     1192936 : void ivas_analy_sp_fx(
     432             :     const Word16 element_mode, /* i  : element mode                                    Q0                 */
     433             :     CPE_ENC_HANDLE hCPE,       /* i/o: CPE encoder structure                                              */
     434             :     const Word32 input_Fs,     /* i  : input sampling rate                             Q0                 */
     435             :     Word16 *speech,            /* i  : speech buffer                                   Q_new              */
     436             :     const Word16 Q_new,        /* i  : current scaling exp                             Q0                 */
     437             :     Word32 *fr_bands,          /* o  : energy in critical frequency bands              q_fr_bands         */
     438             :     Word16 *q_fr_bands,        /* o  : energy in critical frequency bands              Q0                 */
     439             :     Word32 *lf_E,              /* o  : per bin E for first...                          q_lf_E             */
     440             :     Word16 *q_lf_E,            /* o  : per bin E for first...                          Q0                 */
     441             :     Word32 *Etot,              /* o  : total input energy                              Q24                 */
     442             :     const Word16 min_band,     /* i  : minimum critical band                           Q0                 */
     443             :     const Word16 max_band,     /* i  : maximum critical band                           Q0                 */
     444             :     Word32 *Bin_E,             /* o  : per-bin energy spectrum                         q_Bin_E            */
     445             :     Word16 *q_Bin_E,           /* o  : per-bin energy spectrum                         Q0                 */
     446             :     Word32 *Bin_E_old,         /* o  : per-bin energy spectrum of the previous frame   q_Bin_E_old        */
     447             :     Word16 *q_Bin_E_old,       /* o  : per-bin energy spectrum of the previous frame   Q0                 */
     448             :     Word32 *PS,                /* o  : per-bin energy spectrum                         q_PS               */
     449             :     Word16 *q_PS,              /* o  : per-bin energy spectrum                         Q0                 */
     450             :     Word16 *EspecdB,           /* o  : per-bin log energy spectrum (with f=0)          Q7                 */
     451             :     Word32 *band_energies,     /* o  : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (q_band_energies) */
     452             :     Word16 *q_band_energies,   /* o  : Q of energy in critical frequency bands without minimum noise floor MODE2_E_MIN              */
     453             :     Word16 *fft_buff,          /* o  : FFT coefficients                                (q_fft_buff)       */
     454             :     Word16 *q_fft_buff         /* o  : Q of FFT coefficients                           Q0                 */
     455             : )
     456             : {
     457             :     Word16 *pt;
     458             :     Word16 i_subfr, i;
     459             :     Word32 *pt_bands;
     460             :     Word32 Ltmp;
     461             :     Word16 *pt_fft;
     462             :     Word16 exp, tmp;
     463             :     Word16 resultant_q;
     464             :     Word16 exp2;
     465             :     Word64 LEtot;
     466     1192936 :     LEtot = 0;
     467     1192936 :     move64();
     468             :     /*-----------------------------------------------------------------*
     469             :      * Compute spectrum
     470             :      * find energy per critical frequency band and total energy in dB
     471             :      *-----------------------------------------------------------------*/
     472             : 
     473     1192936 :     pt_bands = fr_bands;
     474     1192936 :     pt_fft = fft_buff;
     475             : 
     476     1192936 :     IF( NE_16( element_mode, IVAS_CPE_DFT ) )
     477             :     {
     478     1133293 :         IF( is_zero_arr16( speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT + 4 * ( L_SUBFR / 2 ) ) )
     479             :         {
     480       73898 :             set16_fx( pt_fft, 0, 2 * L_FFT );
     481       73898 :             *q_fft_buff = Q15;
     482       73898 :             move16();
     483             : 
     484       73898 :             set32_fx( Bin_E, 0, L_FFT );
     485       73898 :             set32_fx( lf_E, 0, 2 * VOIC_BINS );
     486       73898 :             set32_fx( band_energies, 0, 2 * NB_BANDS );
     487       73898 :             set32_fx( fr_bands, E_MIN_FXQ31, 2 * NB_BANDS ); // Q31 (*q_fr_bands)
     488             : 
     489       73898 :             LEtot = W_shl( W_mult_32_16( E_MIN_FXQ31, add( sub( max_band, min_band ), 1 ) ), 1 ); // Q32 (*q_fr_bands+1)
     490       73898 :             *q_fr_bands = Q31;
     491       73898 :             *q_lf_E = *q_fr_bands;
     492       73898 :             move16();
     493       73898 :             move16();
     494             :         }
     495             :         ELSE
     496             :         {
     497     1059395 :             Word16 scale = 0, shift;
     498     1059395 :             move16();
     499     1059395 :             shift = s_min( norm_arr( speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT ), norm_arr( speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT ) );
     500     3178185 :             FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ )
     501             :             {
     502             :                 /* set pointer to the beginning of the signal for spectral analysis */
     503             :                 /* set the pointer for first analysis window */
     504     2118790 :                 pt = speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2;
     505     2118790 :                 if ( i_subfr != 0 )
     506             :                 {
     507             :                     /* set the pointer for second analysis window */
     508     1059395 :                     pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2;
     509             :                 }
     510             :                 /* Clear 1st value of 1st part, copy 1st value of 2nd part */
     511     2118790 :                 pt_fft[0] = 0;
     512     2118790 :                 move16();
     513     2118790 :                 pt_fft[L_FFT / 2] = shl( pt[L_FFT / 2], shift ); // (Q_new + shift) - preemph_bits
     514     2118790 :                 move16();
     515             : 
     516   271205120 :                 FOR( i = 1; i < L_FFT / 2; i++ )
     517             :                 {
     518             :                     /* 1st windowed part */
     519   269086330 :                     pt_fft[i] = mult_r( shl( pt[i], shift ), sqrt_han_window_fx[i] ); // (Q_new + shift) - preemph_bits
     520   269086330 :                     move16();
     521             : 
     522             :                     /* 2nd windowed part  */
     523   269086330 :                     pt_fft[L_FFT - i] = mult_r( shl( pt[L_FFT - i], shift ), sqrt_han_window_fx[i] ); // (Q_new + shift) - preemph_bits
     524   269086330 :                     move16();
     525             :                 }
     526             : 
     527             :                 /* compute the spectrum */
     528     2118790 :                 fft_rel_16_32fx( pt_fft, &scale, i_subfr, L_FFT, LOG2_L_FFT );
     529     2118790 :                 *q_fft_buff = add( add( Q_new, shift ), scale ); // resultant q for fft_buff
     530     2118790 :                 move16();
     531     2118790 :                 IF( EQ_16( i_subfr, 1 ) )
     532             :                 {
     533     1059395 :                     Word16 new_q_lf_E = add( shl( *q_fft_buff, 1 ), 14 );
     534     1059395 :                     Word16 new_q_bands = new_q_lf_E;
     535     1059395 :                     IF( GT_16( new_q_bands, 39 ) )
     536             :                     {
     537         758 :                         new_q_bands = 39;
     538         758 :                         move16();
     539             :                     }
     540     1059395 :                     scale_sig32( fr_bands, NB_BANDS, sub( new_q_bands, *q_fr_bands ) );
     541     1059395 :                     scale_sig32( lf_E, VOIC_BINS, sub( new_q_lf_E, *q_lf_E ) );
     542     1059395 :                     LEtot = W_shl( LEtot, sub( new_q_bands, *q_fr_bands ) );
     543     1059395 :                     scale_sig32( Bin_E, L_FFT / 2, sub( new_q_lf_E, *q_lf_E ) );
     544     1059395 :                     scale_sig32( band_energies, NB_BANDS, sub( new_q_bands, *q_fr_bands ) );
     545             :                 }
     546             :                 /* find energy per critical band */
     547     2118790 :                 ivas_find_enr( pt_fft, *q_fft_buff, pt_bands, q_fr_bands, lf_E + i_subfr * VOIC_BINS, q_lf_E, &LEtot, min_band, max_band,
     548     2118790 :                                &Bin_E[i_subfr * L_FFT / 2], BIN, band_energies + i_subfr * NB_BANDS );
     549             : 
     550     2118790 :                 pt_bands += NB_BANDS;
     551     2118790 :                 pt_fft += L_FFT;
     552             :             }
     553             :         }
     554             : 
     555     1133293 :         *q_Bin_E = *q_lf_E;
     556     1133293 :         move16();
     557             : 
     558             :         /* Average total log energy over both half-frames */
     559             :         /* *Etot = 10.0f * (float)log10(0.5f * *Etot); */
     560     1133293 :         *Etot = -838860800 /* 10.f * log10f(0.00001f) in Q24 : This is when LEtot is 0*/;
     561     1133293 :         move16();
     562     1133293 :         IF( LEtot != 0 )
     563             :         {
     564             :             /* Q of LEtot is  q_fr_bands+1, LEtot / 2 can be considered as LEtot in q_fr_bands+2 */
     565     1133293 :             exp = W_norm( LEtot );
     566     1133293 :             LEtot = W_shl( LEtot, exp );                                                                                        // q_fr_bands+2+exp
     567     1133293 :             Ltmp = BASOP_Util_Log10( W_extract_h( LEtot ), sub( 61, add( *q_fr_bands, exp ) ) /* 31-(q_fr_bands+2+exp-32) */ ); // Q25
     568     1133293 :             Ltmp = Mpy_32_32( Ltmp, 1342177280 /* 10.f in Q27 */ );                                                             // (Q25, Q27) -> Q21
     569     1133293 :             *Etot = L_shl( Ltmp, Q24 - Q21 );                                                                                   // Q24
     570     1133293 :             move16();
     571             :         }
     572             :     }
     573             :     ELSE
     574             :     {
     575       59643 :         IF( is_zero_arr( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC ) )
     576             :         {
     577           0 :             set32_fx( Bin_E, 0, L_FFT );
     578           0 :             set32_fx( lf_E, 0, 2 * VOIC_BINS );
     579           0 :             set32_fx( band_energies, 0, 2 * NB_BANDS );
     580           0 :             set32_fx( fr_bands, E_MIN_FXQ31, 2 * NB_BANDS ); // Q31 (*q_fr_bands)
     581             : 
     582           0 :             LEtot = W_shl( W_mult_32_16( E_MIN_FXQ31, add( sub( max_band, min_band ), 1 ) ), 1 ); // Q32 (*q_fr_bands+1)
     583           0 :             *q_fr_bands = Q31;
     584           0 :             *q_lf_E = *q_fr_bands;
     585           0 :             move16();
     586           0 :             move16();
     587             :         }
     588             :         ELSE
     589             :         {
     590       59643 :             exp = sub( getScaleFactor32( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC ), 1 );
     591       59643 :             scale_sig32( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC, exp ); /* exp(hCPE->hStereoDft->DFT_fx_e[0] - exp) */
     592       59643 :             hCPE->hStereoDft->DFT_fx_e[0] = sub( hCPE->hStereoDft->DFT_fx_e[0], exp );
     593       59643 :             move16();
     594       59643 :             find_enr_dft_ivas_fx( hCPE, input_Fs, hCPE->hStereoDft->DFT_fx[0], pt_bands, q_fr_bands, lf_E, q_lf_E, &LEtot, min_band, max_band, Bin_E, q_Bin_E, band_energies, sub( Q31, hCPE->hStereoDft->DFT_fx_e[0] ) );
     595       59643 :             MVR2R_WORD32( lf_E, lf_E + VOIC_BINS, VOIC_BINS );
     596       59643 :             MVR2R_WORD32( Bin_E, Bin_E + ( L_FFT / 2 ), L_FFT / 2 );
     597       59643 :             MVR2R_WORD32( band_energies, band_energies + NB_BANDS, NB_BANDS );
     598       59643 :             MVR2R_WORD32( pt_bands, pt_bands + NB_BANDS, NB_BANDS );
     599             :         }
     600             : 
     601             :         /* Average total log energy over both half-frames */
     602       59643 :         *Etot = -838860800 /* 10.f * log10f(0.00001f) in Q24 : This is when LEtot is 0*/;
     603       59643 :         move16();
     604       59643 :         IF( LEtot != 0 )
     605             :         {
     606       59643 :             exp = W_norm( LEtot );
     607       59643 :             LEtot = W_shl( LEtot, exp );                                                                                        // q_fr_bands+exp
     608       59643 :             Ltmp = BASOP_Util_Log10( W_extract_h( LEtot ), sub( 62, add( *q_fr_bands, exp ) ) /* 31-(q_fr_bands+1+exp-32) */ ); // Q25
     609       59643 :             Ltmp = Mpy_32_32( Ltmp, 1342177280 /* 10.f in Q27 */ );                                                             // (Q25, Q27) -> Q21
     610       59643 :             *Etot = L_shl( Ltmp, Q24 - Q21 );                                                                                   // Q24
     611       59643 :             move16();
     612             :         }
     613             :     }
     614             : 
     615     1192936 :     *q_band_energies = *q_fr_bands;
     616     1192936 :     move16();
     617             : 
     618     1192936 :     exp = sub( getScaleFactor32( fr_bands, 2 * NB_BANDS ), 1 );
     619     1192936 :     scale_sig32( fr_bands, 2 * NB_BANDS, exp ); /* q_fr_bands + exp */
     620     1192936 :     *q_fr_bands = add( *q_fr_bands, exp );
     621     1192936 :     move16();
     622             : 
     623     1192936 :     exp = sub( getScaleFactor32( band_energies, 2 * NB_BANDS ), 1 );
     624     1192936 :     scale_sig32( band_energies, 2 * NB_BANDS, exp ); /* q_band_energies + exp */
     625     1192936 :     *q_band_energies = add( *q_band_energies, exp );
     626     1192936 :     move16();
     627             : 
     628     1192936 :     *q_Bin_E_old = *q_Bin_E;
     629     1192936 :     move16();
     630             : 
     631             : 
     632             :     /* Per-bin log-energy spectrum */
     633     1192936 :     Bin_E[L_FFT / 2 - 1] = Bin_E[L_FFT / 2 - 2]; // *q_Bin_E
     634     1192936 :     move32();
     635     1192936 :     Bin_E[L_FFT - 1] = Bin_E[L_FFT - 2]; // *q_Bin_E
     636     1192936 :     move32();
     637     1192936 :     Word32 add_const = 21475; // 1e-5 in Q31
     638   153888744 :     FOR( i = 0; i < L_FFT / 2; i++ )
     639             :     {
     640   152695808 :         Bin_E_old[i] = Bin_E[i]; // *q_Bin_E
     641   152695808 :         move32();
     642             : 
     643             :         /* PS[i] = ( Bin_E[i] + 1e-5f + Bin_E[i + L_FFT / 2] + 1e-5f ) / 2.0f; */
     644   152695808 :         PS[i] = W_extract_h( W_add( W_mac_32_32( W_mult_32_32( Bin_E[i], ONE_IN_Q30 ), Bin_E[i + L_FFT / 2], ONE_IN_Q30 ), W_shr( W_shl( add_const, 32 ), sub( 31, *q_Bin_E ) ) ) ); // *q_Bin_E
     645   152695808 :         move32();
     646             : 
     647             :         /* Bin_E[i] = (float) ( 10.0f * log( PS[i] ) ); */
     648   152695808 :         IF( EspecdB != NULL )
     649             :         {
     650   144512000 :             EspecdB[i] = -14736; /* ln(1e-5) in Q7 */
     651   144512000 :             move16();
     652             :         }
     653             : 
     654   152695808 :         Bin_E[i] = -482887093; /* ln(1e-5) in Q22 */
     655   152695808 :         move32();
     656             : 
     657   152695808 :         IF( GT_32( PS[i], L_shl_sat( 21475, sub( *q_Bin_E, Q31 ) ) ) /*1e - 5 in *q_bin_E */ )
     658             :         {
     659   143218026 :             Ltmp = L_add( BASOP_Util_Log2( PS[i] ), L_shl( sub( Q31, *q_Bin_E ), Q25 ) );
     660   143218026 :             Bin_E[i] = Mpy_32_32( Ltmp, 1860652798 /*10.0*logf(2) in Q28 */ ); // Q22
     661   143218026 :             move32();
     662             : 
     663   143218026 :             tmp = extract_h( L_shl( Bin_E[i], Q23 - Q22 ) ); // Q7
     664   143218026 :             if ( EspecdB != NULL )
     665             :             {
     666   135034224 :                 EspecdB[i] = tmp; // Q7
     667   135034224 :                 move16();
     668             :             }
     669             :         }
     670             :     }
     671             : 
     672     1192936 :     if ( q_PS != NULL )
     673             :     {
     674     1129000 :         *q_PS = *q_Bin_E;
     675     1129000 :         move16();
     676             :     }
     677             : 
     678     1192936 :     exp = L_norm_arr( Bin_E, L_FFT / 2 );
     679     1192936 :     exp2 = L_norm_arr( Bin_E + L_FFT / 2, L_FFT / 2 );
     680     1192936 :     resultant_q = s_min( Q22, s_min( add( *q_Bin_E, exp2 ), add( exp, Q22 ) ) ); // calculating resultant q after scaling
     681     1192936 :     scale_sig32( Bin_E, L_FFT / 2, sub( resultant_q, Q22 ) );                    // Q22=>resultant_q
     682     1192936 :     scale_sig32( Bin_E + L_FFT / 2, L_FFT / 2, sub( resultant_q, *q_Bin_E ) );   // q_Bin_E=>resultant_q
     683     1192936 :     *q_Bin_E = resultant_q;
     684     1192936 :     move16();
     685             : 
     686     1192936 :     return;
     687             : }
     688             : 
     689             : /*------------------------------------------------------------------------*
     690             :  * find_enr()
     691             :  *
     692             :  * find input signal energy for each critical band and first 74 LF bins
     693             :  * The energy is normalized by the number of frequency bins in a channel
     694             :  *------------------------------------------------------------------------*/
     695             : 
     696             : /* Merge with ivas_find_enr function once analy_sp is unified */
     697     2118790 : static void ivas_find_enr(
     698             :     Word16 data[],         /* i  : fft result                                                  */
     699             :     Word16 q_data,         /* i  : Q of fft result                                             */
     700             :     Word32 band[],         /* o  : per band energy                           q_band            */
     701             :     Word16 *q_band,        /* o  : Q of per band energy                                                            */
     702             :     Word32 *ptE,           /* o  : per bin energy  for low frequencies       q_ptE             */
     703             :     Word16 *q_ptE,         /* o  : Q of per bin energy  for low frequencies  Q0                */
     704             :     Word64 *LEtot,         /* o  : total energy                              q_band+1          */
     705             :     const Word16 min_band, /* i  : minimum critical band                     Q0                */
     706             :     const Word16 max_band, /* i  : maximum critical band                     Q0                */
     707             :     Word32 *Bin_E,         /* o  : Per bin energy                            q_ptE             */
     708             :     Word16 BIN_FREQ_FX,    /* i  : Number of frequency bins                  Q0                */
     709             :     Word32 *band_energies  /* o  : per band energy without MODE2_E_MIN       q_band            */
     710             : )
     711             : {
     712             :     Word16 i;
     713             :     Word16 freq;
     714             :     Word16 *ptR, *ptI;
     715             :     Word16 voic_band;
     716             :     Word64 etot, band_ener;
     717             :     Word16 start_freq;
     718             :     Word32 min_ener;
     719     2118790 :     Word16 shift = 0;
     720     2118790 :     move16();
     721             : 
     722     2118790 :     ptR = &data[1];         /* first real */
     723     2118790 :     ptI = &data[L_FFT - 1]; /* first imaginary */
     724             : 
     725     2118790 :     voic_band = VOIC_BAND_8k;
     726     2118790 :     move16();
     727             :     assert( VOIC_BAND == VOIC_BAND_8k );
     728             : 
     729             :     /*-----------------------------------------------------------------*
     730             :      * For low frequency bins, save per bin energy for the use
     731             :      * in NS and find_tilt()
     732             :      *-----------------------------------------------------------------*/
     733             : 
     734     2118790 :     *q_ptE = add( shl( q_data, 1 ), 14 );
     735     2118790 :     move16();
     736     2118790 :     *q_band = add( shl( q_data, 1 ), 14 );
     737     2118790 :     move16();
     738             : 
     739     2118790 :     IF( GT_16( *q_band, 39 ) )
     740             :     {
     741        2134 :         shift = sub( *q_band, 39 );
     742        2134 :         *q_band = 39;
     743        2134 :         move16();
     744             :     }
     745             : 
     746     2118790 :     min_ener = L_shl( E_MIN_FXQ31, sub( *q_band, Q31 ) ); // *q_band
     747             : 
     748     2118790 :     freq = BIN_FREQ_FX;
     749     2118790 :     move16();
     750    38138220 :     FOR( i = 0; i < voic_band; i++ ) /* up to maximum allowed voiced critical band  */
     751             :     {
     752    36019430 :         band_ener = 0;
     753    36019430 :         move64();
     754    36019430 :         start_freq = freq;
     755    36019430 :         move16();
     756   192809890 :         WHILE( LE_32( freq, crit_bands_fx[i] ) )
     757             :         {
     758             :             /*
     759             :                *ptE = *ptR * *ptR + *ptI * *ptI;
     760             : 
     761             :                Overflow occurs in the above operation only when ptR and ptI values are equal to -32768.
     762             :                In that case, energy value will be 2^31 (only one greater than max 32 bit value).
     763             :                Hence, saturation is added.
     764             : 
     765             :                *ptE *= norm_val;
     766             :                norm_val = 4 / (256 * 256), As the value is in power's of 2, result can be obtained by increasing the Q factor
     767             : 
     768             :                Q of energy = 2 * q_data + 14 = *q_ptE
     769             :            */
     770             : 
     771   156790460 :             *ptE = L_mac0_sat( L_mult0( *ptR, *ptR ), *ptI, *ptI ); // *q_ptE
     772   156790460 :             move32();
     773             : 
     774   156790460 :             *Bin_E++ = *ptE; // *q_ptE
     775   156790460 :             move32();
     776             : 
     777             :             /*
     778             :                 BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1
     779             :                 band[i] += *ptE++;
     780             :                 band[i] *= inv_tbl[cnt]; // normalization per frequency bin
     781             :             */
     782   156790460 :             band_ener = W_mac_32_16( band_ener, *ptE, inv_tbl_fx[( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1] ); // *q_band+16+shift
     783   156790460 :             ptR++;
     784   156790460 :             ptI--;
     785   156790460 :             ptE++;
     786   156790460 :             freq = add( freq, BIN_FREQ_FX );
     787             :         }
     788             : 
     789    36019430 :         band[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band
     790    36019430 :         move32();
     791             : 
     792    36019430 :         band_energies[i] = band[i]; /* per band energy without E_MIN   */ // *q_band
     793    36019430 :         move32();
     794             : 
     795    36019430 :         if ( LT_32( band[i], min_ener ) ) // *q_band
     796             :         {
     797     1946459 :             band[i] = min_ener; // *q_band
     798     1946459 :             move32();
     799             :         }
     800             :     }
     801             : 
     802     2118790 :     IF( EQ_16( BIN_FREQ_FX, 50 ) )
     803             :     {
     804             :         /*-----------------------------------------------------------------*
     805             :          * Continue compute the E per critical band for high frequencies
     806             :          *-----------------------------------------------------------------*/
     807             : 
     808     8475160 :         FOR( i = voic_band; i < NB_BANDS; i++ )
     809             :         {
     810     6356370 :             band_ener = 0;
     811     6356370 :             move64();
     812     6356370 :             start_freq = freq;
     813     6356370 :             move16();
     814   118652240 :             WHILE( LE_32( freq, crit_bands_fx[i] ) )
     815             :             {
     816             :                 /*
     817             :                   *Bin_E = *ptR * *ptR + *ptI * *ptI;
     818             : 
     819             :                   Overflow occurs in the below operation only when ptR and ptI values are equal to - 32768.
     820             :                   In that case, energy value will be 2 ^ 31 (only one greater than max 32 bit value).
     821             :                   Hence, saturation is added.
     822             : 
     823             :                   *Bin_E *= norm_val;
     824             :                   norm_val = 4 / (256 * 256), As the value is in power's of 2, result can be obtained by increasing the Q factor
     825             : 
     826             :                   Q of energy = 2 * q_data + 14 = *q_ptE
     827             :                 */
     828             : 
     829   112295870 :                 *Bin_E = L_mac0_sat( L_mult0( *ptR, *ptR ), *ptI, *ptI ); // 2*q_data+14 = *q_ptE
     830   112295870 :                 move32();
     831             : 
     832             :                 /*
     833             :                    BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1
     834             :                    band[i] += *ptE++;
     835             :                    band[i] *= inv_tbl[cnt]; // normalization per frequency bin
     836             :                 */
     837   112295870 :                 band_ener = W_mac_32_16( band_ener, *Bin_E, inv_tbl_fx[( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1] ); // *q_band+16+shift
     838   112295870 :                 ptR++;
     839   112295870 :                 ptI--;
     840   112295870 :                 Bin_E++;
     841             : 
     842   112295870 :                 freq = add( freq, BIN_FREQ_FX );
     843             :             }
     844             : 
     845     6356370 :             band[i] = W_extract_h( W_shl_nosat( band_ener, sub( Q16, shift ) ) ); // *q_band
     846     6356370 :             move32();
     847             : 
     848     6356370 :             band_energies[i] = band[i]; /* per band energy without E_MIN   */ // *q_band
     849     6356370 :             move32();
     850             : 
     851     6356370 :             if ( LT_32( band[i], min_ener ) ) // *q_band
     852             :             {
     853      363001 :                 band[i] = min_ener; // *q_band
     854      363001 :                 move32();
     855             :             }
     856             :         }
     857             :     }
     858             : 
     859             :     /*-----------------------------------------------------------------*
     860             :      * Find the total energy over the input bandwidth
     861             :      *-----------------------------------------------------------------*/
     862             : 
     863     2118790 :     etot = *LEtot; // *q_band
     864     2118790 :     move64();
     865    44464654 :     FOR( i = min_band; i <= max_band; i++ )
     866             :     {
     867    42345864 :         etot = W_mac_32_32( etot, band[i], 1 ); // *q_band+1
     868             :     }
     869     2118790 :     *LEtot = etot; // *q_band+1
     870     2118790 :     move64();
     871             : 
     872     2118790 :     return;
     873             : }
     874             : 
     875        6200 : static void find_enr(
     876             :     Word16 data[],         /* i  : fft result                                                  */
     877             :     Word32 band[],         /* o  : per band energy                           Q_new + QSCALE   */
     878             :     Word32 *ptE,           /* o  : per bin energy  for low frequencies       Q_new + QSCALE-2 */
     879             :     Word32 *LEtot,         /* o  : total energy                              Q_new + QSCALE   */
     880             :     const Word16 min_band, /* i  : minimum critical band                     Q0                */
     881             :     const Word16 max_band, /* i  : maximum critical band                     Q0                */
     882             :     const Word16 Q_new2,   /* i  : scaling factor                            Q0                */
     883             :     const Word32 e_min,    /* i  : minimum energy scaled                     Q_new + QSCALE   */
     884             :     Word32 *Bin_E,         /* o  : Per bin energy                            Q_new + QSCALE-2 */
     885             :     Word16 BIN_FREQ_FX,    /* i  : Number of frequency bins                  Q0               */
     886             :     Word32 *band_energies  /* o  : per band energy without MODE2_E_MIN        */
     887             : )
     888             : {
     889             :     Word16 i, cnt, shift_to_norm;
     890             :     Word16 freq, wtmp;
     891             :     Word16 *ptR, *ptI, diff_scaleP1, diff_scaleM2;
     892             :     Word16 exp_band;
     893             :     Word32 Ltmp, Ltmp1;
     894             :     Word16 voic_band;
     895             :     Word32 etot;
     896             :     Word16 exp_etot;
     897             :     Word32 *tmpptr;
     898             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     899        6200 :     Flag Overflow = 0;
     900        6200 :     move32();
     901             : #endif
     902             : 
     903             : 
     904        6200 :     ptR = &data[1];         /* first real */
     905        6200 :     ptI = &data[L_FFT - 1]; /* first imaginary */
     906             : 
     907             :     /*-----------------------------------------------------------------------------------*
     908             :      * Scaling needed by band and ptE output
     909             :      * Wants all energies scaled by Q_new + QSCALE to maintain maximum
     910             :      * precision on bckr noise in clean speech
     911             :      * First shift left by Q_new + QSCALE than shift right by 2*Q_new-1
     912             :      * shift left (Q_new + QSCALE - (2*Q_new -1))
     913             :      * shift left (QSCALE - Q_new + 1) == shift left by (QSCALE+1) - Q_new
     914             :      *-----------------------------------------------------------------------------------*/
     915             : 
     916        6200 :     diff_scaleP1 = sub( QSCALE + 1 + 1, Q_new2 );
     917        6200 :     diff_scaleM2 = sub( QSCALE + 1 - 2, Q_new2 );
     918             : 
     919        6200 :     voic_band = VOIC_BAND_8k;
     920        6200 :     move16();
     921             :     assert( VOIC_BAND == VOIC_BAND_8k );
     922             : 
     923        6200 :     etot = L_deposit_l( 0 );
     924        6200 :     exp_etot = 0;
     925        6200 :     move16();
     926             : 
     927             :     /*-----------------------------------------------------------------*
     928             :      * For low frequency bins, save per bin energy for the use
     929             :      * in NS and find_tilt()
     930             :      *-----------------------------------------------------------------*/
     931             : 
     932        6200 :     freq = BIN_FREQ_FX;
     933        6200 :     move16();
     934      111600 :     FOR( i = 0; i < voic_band; i++ ) /* up to maximum allowed voiced critical band  */
     935             :     {
     936      105400 :         tmpptr = Bin_E; /* Q_new + QSCALE - 2 */
     937      105400 :         move16();
     938      105400 :         Ltmp1 = L_deposit_l( 0 );
     939             : 
     940      564200 :         FOR( ; LE_32( freq, crit_bands_fx[i] ); freq += BIN_FREQ_FX )
     941             :         {
     942             :             /*ptE = *ptR * *ptR + *ptI * *ptI */ /* energy */
     943      458800 :             Ltmp = L_mult( *ptI, *ptI );
     944      458800 :             Ltmp = L_mac( Ltmp, *ptR, *ptR );
     945             : 
     946             :             /* *ptE *= 4.0 / (L_FFT*L_FFT) */
     947             :             /* normalization - corresponds to FFT normalization by 2/L_FFT */
     948             :             BASOP_SATURATE_WARNING_OFF_EVS;                  /* saturation seems to have no effect (tested by simulation) */
     949      458800 :             *ptE = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); /* Q_new + QSCALE - 2 */
     950      458800 :             move32();                                        /* scaled by Q_new + QSCALE - 2 */
     951             :             BASOP_SATURATE_WARNING_ON_EVS;
     952             :             /*band[i] += *ptE++;*/
     953      458800 :             *Bin_E = *ptE;
     954      458800 :             move32();
     955      458800 :             Bin_E++;
     956      458800 :             Ltmp1 = L_add( Ltmp1, Ltmp );
     957             : 
     958      458800 :             ptE++;
     959      458800 :             ptR++;
     960      458800 :             ptI--;
     961             :         }
     962             : 
     963      105400 :         exp_band = sub( norm_l( Ltmp1 ), 1 ); /* divide by 2 to ensure band < cnt */
     964      105400 :         wtmp = round_fx( L_shl( Ltmp1, exp_band ) );
     965             : 
     966             :         /* band[i] /= cnt */ /* normalization per frequency bin */
     967      105400 :         cnt = (Word16) ( Bin_E - tmpptr );
     968      105400 :         shift_to_norm = norm_s( cnt );
     969      105400 :         wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) ); /* Q15 */
     970      105400 :         Ltmp1 = L_deposit_l( wtmp );                     /* Q15 */
     971             : 
     972      105400 :         exp_band = sub( exp_band, shift_to_norm );
     973      105400 :         exp_band = sub( diff_scaleP1, exp_band );
     974             :         BASOP_SATURATE_WARNING_OFF_EVS;                  /* saturation seems to have no effect (tested by simulation) */
     975      105400 :         band[i] = L_shl_o( Ltmp1, exp_band, &Overflow ); /* Q15 + exp_band */
     976      105400 :         move32();                                        /* band scaled by Q_new + QSCALE */
     977             :         BASOP_SATURATE_WARNING_ON_EVS;
     978             : 
     979      105400 :         test();
     980      105400 :         IF( GE_16( i, min_band ) && LE_16( i, max_band ) )
     981             :         {
     982      105400 :             IF( LT_32( band[i], e_min ) )
     983             :             {
     984        1360 :                 Ltmp1 = L_shl( e_min, 0 );
     985        1360 :                 exp_band = 0;
     986        1360 :                 move16();
     987             :             }
     988             : 
     989      105400 :             wtmp = sub( exp_band, exp_etot );
     990      105400 :             if ( wtmp > 0 )
     991             :             {
     992       15770 :                 etot = L_shr( etot, wtmp );
     993             :             }
     994      105400 :             exp_etot = s_max( exp_etot, exp_band );
     995      105400 :             etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) );
     996             :         }
     997             : 
     998      105400 :         band_energies[i] = band[i]; /* Q_new + QSCALE */
     999      105400 :         move32();
    1000             : 
    1001      105400 :         band[i] = L_max( band[i], e_min );
    1002      105400 :         move32();
    1003             :     }
    1004             : 
    1005        6200 :     IF( EQ_16( BIN_FREQ_FX, 50 ) )
    1006             :     {
    1007             :         /*-----------------------------------------------------------------*
    1008             :          * Continue compute the E per critical band for high frequencies
    1009             :          *-----------------------------------------------------------------*/
    1010             : 
    1011       24800 :         FOR( i = voic_band; i < NB_BANDS; i++ )
    1012             :         {
    1013       18600 :             tmpptr = Bin_E;
    1014       18600 :             move16();
    1015       18600 :             Ltmp1 = L_deposit_l( 0 );
    1016             : 
    1017      347200 :             FOR( ; LE_32( freq, crit_bands_fx[i] ); freq += BIN_FREQ_FX )
    1018             :             {
    1019             :                 /* *ptE = *ptR * *ptR + *ptI * *ptI */
    1020      328600 :                 Ltmp = L_mult( *ptI, *ptI );
    1021      328600 :                 Ltmp = L_mac( Ltmp, *ptR, *ptR );
    1022             : 
    1023             :                 /* *ptE *= 4.0 / (L_FFT*L_FFT) */
    1024             :                 /* normalization - corresponds to FFT normalization by 2/L_FFT  */
    1025             :                 BASOP_SATURATE_WARNING_OFF_EVS;                    /* saturation seems to have no effect (tested by simulation) */
    1026      328600 :                 *Bin_E = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); /* Q_new + QSCALE */
    1027      328600 :                 move32();                                          /* scaled by Q_new + QSCALE - 2 */
    1028             :                 BASOP_SATURATE_WARNING_ON_EVS;
    1029      328600 :                 Bin_E++;
    1030      328600 :                 Ltmp1 = L_add( Ltmp1, Ltmp );
    1031             : 
    1032      328600 :                 ptR++;
    1033      328600 :                 ptI--;
    1034             :             }
    1035             : 
    1036       18600 :             exp_band = sub( norm_l( Ltmp1 ), 1 ); /* divide by 2 to ensure band < cnt */
    1037       18600 :             wtmp = round_fx( L_shl( Ltmp1, exp_band ) );
    1038             : 
    1039             :             /* band[i] /= cnt */ /* normalization per frequency bin */
    1040       18600 :             cnt = (Word16) ( Bin_E - tmpptr );
    1041       18600 :             shift_to_norm = norm_s( cnt );
    1042       18600 :             wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) );
    1043       18600 :             Ltmp1 = L_deposit_l( wtmp );
    1044             : 
    1045       18600 :             exp_band = sub( exp_band, shift_to_norm );
    1046       18600 :             exp_band = sub( diff_scaleP1, exp_band );
    1047             :             BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */
    1048       18600 :             band[i] = L_shl_o( Ltmp1, exp_band, &Overflow );
    1049       18600 :             move32(); /* band scaled by Q_new + QSCALE */
    1050             :             BASOP_SATURATE_WARNING_ON_EVS;
    1051             : 
    1052       18600 :             test();
    1053       18600 :             IF( GE_16( i, min_band ) && LE_16( i, max_band ) )
    1054             :             {
    1055       18600 :                 IF( LT_32( band[i], e_min ) )
    1056             :                 {
    1057          39 :                     Ltmp1 = L_shl( e_min, 0 );
    1058          39 :                     exp_band = 0;
    1059          39 :                     move16();
    1060             :                 }
    1061             : 
    1062       18600 :                 wtmp = sub( exp_band, exp_etot );
    1063       18600 :                 if ( wtmp > 0 )
    1064             :                 {
    1065         468 :                     etot = L_shr( etot, wtmp );
    1066             :                 }
    1067       18600 :                 exp_etot = s_max( exp_etot, exp_band );
    1068             : 
    1069       18600 :                 etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) );
    1070             :             }
    1071             : 
    1072       18600 :             band_energies[i] = band[i];
    1073       18600 :             move32();
    1074             : 
    1075       18600 :             band[i] = L_max( band[i], e_min );
    1076       18600 :             move32();
    1077             :         }
    1078             :     }
    1079             : 
    1080             :     /*-----------------------------------------------------------------*
    1081             :      * Find the total energy over the input bandwidth
    1082             :      *-----------------------------------------------------------------*/
    1083             : 
    1084        6200 :     etot = L_add_sat( *LEtot, L_shl_sat( etot, sub( exp_etot, 4 ) ) );
    1085        6200 :     *LEtot = etot;
    1086        6200 :     move32();
    1087             : 
    1088             : 
    1089        6200 :     return;
    1090             : }

Generated by: LCOV version 1.14